Глобальная таблица дескрипторов - Global Descriptor Table

В Глобальная таблица дескрипторов (GDT) - это структура данных, используемая Intel x86 -семейные процессоры, начиная с 80286 для определения характеристик различных областей памяти, используемых во время выполнения программы, включая базовый адрес, размер и права доступа, такие как исполняемость и возможность записи. Эти области памяти называются сегменты в терминологии Intel.

Глобальная таблица дескрипторов

GDT может содержать другие вещи, кроме дескрипторы сегментов также. Каждая 8-байтовая запись в GDT является дескриптором, но эти дескрипторы могут быть ссылками не только на сегменты памяти, но и на Сегмент состояния задачи (TSS), локальная таблица дескрипторов (LDT) или Call Gate структуры в памяти. Последние, шлюзы вызова, особенно важны для передачи управления между уровнями привилегий x86, хотя этот механизм не используется в большинстве современных операционных систем.

Также есть Таблица локальных дескрипторов (LDT). В GDT можно определить несколько LDT, но только один является текущим в любой момент времени: обычно он связан с текущей Задачей. В то время как LDT содержит сегменты памяти, которые являются частными для конкретной программы, GDT содержит глобальные сегменты. Процессоры x86 имеют средства для автоматического переключения текущего LDT на определенные машинные события, но не имеют средств для автоматического переключения GDT.

Каждый доступ к памяти, который может выполнить программа, всегда осуществляется через сегмент. На 80386 процессор и позже, из-за 32-битный смещения и ограничения сегментов, можно сделать так, чтобы сегменты покрывали всю адресуемую память, что делает адресацию относительно сегментов прозрачной для пользователя.

Чтобы ссылаться на сегмент, программа должна использовать его индекс внутри GDT или LDT. Такой индекс называется селектор сегментов (или селектор). Селектор обычно должен быть загружен в сегментный регистр использоваться. Помимо машинных инструкций, которые позволяют установить / получить положение GDT, и Таблица дескрипторов прерываний (IDT), в памяти каждая машинная инструкция, обращающаяся к памяти, имеет неявный регистр сегмента, иногда два. В большинстве случаев этот регистр сегмента можно переопределить, добавив префикс сегмента перед инструкцией.

Загрузка селектора в регистр сегмента автоматически считывает GDT или LDT и сохраняет свойства сегмента внутри самого процессора. Последующие модификации GDT или LDT не будут эффективными, если регистр сегмента не будет перезагружен.

Пример GDT

Ниже показана сборочная реализация GDT, которая открывает все 4 ГБ доступной памяти:

база = 0x00000000, предел сегмента = 0xffffffff
; смещение 0x0.ноль дескриптор:	dq 0; смещение 0x8.код:				; cs должен указывать на этот дескриптор	dw 0xffff		; ограничение сегмента первые 0-15 бит	dw 0			; базовые первые 0-15 бит	db 0			; база 16-23 бит	db 0x9a			; байт доступа	db 11001111б	; старшие 4 бита (флаги) младшие 4 бита (ограничение 4 последних бита) (ограничение 20 бит)	db 0			; база 24-31 бит; смещение 0x10.данные:				; ds, ss, es, fs и gs должны указывать на этот дескриптор	dw 0xffff		; ограничение сегмента первые 0-15 бит	dw 0			; базовые первые 0-15 бит	db 0			; база 16-23 бит	db 0x92			; байт доступа	db 11001111б	; старшие 4 бита (флаги) младшие 4 бита (ограничение 4 последних бита) (ограничение 20 бит)	db 0			; база 24-31 бит

GDT в 64-битной версии

GDT все еще присутствует в 64-битном режиме; GDT должен быть определен, но обычно никогда не изменяется и не используется для сегментации. Размер регистра был расширен с 48 до 80 бит, а 64-битные селекторы всегда «плоские» (таким образом, от 0x0000000000000000 до 0xFFFFFFFFFFFFFFFF). Однако база FS и GS не ограничивается 0, и они продолжают использоваться в качестве указателей на смещение таких элементов, как блок среды процесса и блок информации о потоке.

Если системный бит (4-й бит поля доступа) сброшен, размер дескриптора составляет 16 байтов вместо 8. Это связано с тем, что, хотя сегменты кода / данных игнорируются, TSS нет, но указатель TSS может быть Длина 64 бита, поэтому дескриптору требуется больше места для вставки более высокого двойного слова указателя TSS.

64-битные версии Windows запрещают зацепление GDT; попытка сделать это приведет к тому, что машина проверка ошибок.[1]

Таблица локальных дескрипторов

А Таблица локальных дескрипторов (LDT) - это таблица памяти, используемая в архитектура x86 в защищенный режим и содержащий память дескрипторы сегментов точно так же, как GDT: начало адреса в линейной памяти, размер, исполняемость, возможность записи, права доступа, фактическое присутствие в памяти и т. д.

LDT являются родственниками глобальной таблицы дескрипторов (GDT), и каждый определяет до 8192 сегментов памяти, доступных для программ - обратите внимание, что в отличие от GDT, нулевая запись является допустимой записью и может использоваться как любая другая запись LDT. Также обратите внимание, что в отличие от GDT, LDT не может использоваться для хранения определенных системных записей: TSS или LDT. Однако ворота вызова и ворота задач вполне подойдут.

История

На процессорах x86, не имеющих функций подкачки, таких как Intel 80286, LDT необходим для реализации отдельных адресные пространства для нескольких процессов. Обычно будет один LDT для каждого пользовательского процесса, описывающий частную память, в то время как Общая память и ядро память будет описана GDT. В Операционная система переключит текущий LDT при планировании нового процесса, с использованием машинной инструкции LLDT или при использовании TSS. Напротив, GDT обычно не переключается (хотя это может произойти, если мониторы виртуальных машин подобно VMware работают на компьютере).

Отсутствие симметрии между обеими таблицами подчеркивается тем фактом, что текущий LDT может автоматически включаться при определенных событиях, особенно если TSS используется многозадачность на основе, в то время как для GDT это невозможно. LDT также не может хранить определенные привилегированные типы сегментов памяти (например, TSS). Наконец, LDT фактически определяется дескриптором внутри GDT, тогда как GDT напрямую определяется линейным адресом.

Создание разделяемой памяти через GDT имеет некоторые недостатки. Примечательно, что такая память видна каждому процессу и на равных правах. Чтобы ограничить видимость и дифференцировать защиту разделяемой памяти, например, чтобы разрешить доступ только для чтения для некоторых процессов, можно использовать отдельные записи LDT, указывающие на те же области физической памяти и создаваемые только в LDT процессов, которые запросили доступ к данной области разделяемой памяти.

Записи LDT (и GDT), которые указывают на идентичные области памяти, называются псевдонимы. Псевдонимы также обычно создаются для того, чтобы получить доступ на запись к сегментам кода: исполняемый селектор не может использоваться для записи. (Программы защищенного режима, построенные в так называемом крошечный модель памяти, где все находится в одном сегменте памяти, должны использовать отдельные селекторы для кода и данных / стека, что также делает оба селектора технически «псевдонимами».) В случае GDT псевдонимы также создаются для получения доступа к системные сегменты, такие как TSSes.

Сегменты имеют в своих дескрипторах флаг «Присутствует», позволяющий при необходимости удалять их из памяти. Например, сегменты кода или немодифицированные сегменты данных могут быть выброшены, а измененные сегменты данных могут быть выгружены на диск. Однако, поскольку целые сегменты должны работать как единое целое, необходимо ограничить их размер, чтобы обеспечить своевременную замену. Однако использование сегментов меньшего размера, которые легче заменять, означает, что регистры сегментов необходимо перезагружать чаще, что само по себе является трудоемкой операцией.

Современное использование

В Intel 80386 микропроцессор представлен пейджинг - выделение отдельных страниц физической памяти (сами по себе очень маленькие блоки памяти) по одним и тем же виртуальным адресам, с тем преимуществом, что подкачка диска намного быстрее и эффективнее, чем подкачка сегментов. Таким образом, современные 32-разрядные операционные системы x86 очень мало используют LDT, в основном для запуска устаревших версий. 16 бит код.

Если 16-битный код должен работать в 32-битной среде при совместном использовании памяти (это происходит, например, при запуске OS / 2 1.x в OS / 2 2.0 и новее), LDT должен быть написан таким образом, чтобы каждый плоский (Страничный) адрес также имеет селектор в LDT (обычно это приводит к тому, что LDT заполняется записями 64 КиБ). Этот прием иногда называют ЛДТ черепица. Ограниченный размер LDT означает, что виртуальное плоское адресное пространство должно быть ограничено до 512 мегабайт (8191 умноженное на 64 КиБ) - это то, что происходит в OS / 2, хотя это ограничение было исправлено в версии 4.5. Также необходимо убедиться, что объекты, размещенные в 32-битной среде, не пересекают границы 64 КиБ; это порождает некоторую потерю адресного пространства.

Если 32-битный код не должен передавать произвольные объекты памяти в 16-битный код, например предположительно в эмуляции OS / 2 1.x, присутствующей в Windows NT или в Windows 3.1 слой эмуляции, нет необходимости искусственно ограничивать размер 32-битного адресного пространства.

Рекомендации

  1. ^ «Политика исправлений для систем на базе x64». Если операционная система обнаруживает одну из этих модификаций или любое другое неавторизованное исправление, она генерирует проверку на наличие ошибок и завершает работу системы.

внешняя ссылка