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

редактировать

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

Содержание
  • 1 Глобальная таблица дескрипторов
  • 2 Пример GDT
  • 3 GDT в 64-битном
  • 4 Локальная таблица дескрипторов
  • 5 История
    • 5.1 Современное использование
  • 6 Ссылки
  • 7 Внешние ссылки
Глобальная таблица дескрипторов

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

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

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

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

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

Формат дескриптора сегмента
Пример GDT

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

base = 0x00000000, ограничение сегмента = 0xffffffff
; смещение 0x0. нулевой дескриптор: dq 0; смещение 0x8.code:; cs должен указывать на этот дескриптор dw 0xffff; ограничение сегмента первые 0-15 бит dw 0; базовые первые 0-15 бит db 0; базовые 16-23 бита db 0x9a; байт доступа db 11001111b; старшие 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 11001111b; старшие 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; попытка сделать это приведет к тому, что машина проверит ошибку..

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

A Таблица локальных дескрипторов (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), которые указывают на идентичные области памяти, называются псевдонимами. Псевдонимы также обычно создаются для того, чтобы получить доступ на запись к сегментам кода: исполняемый селектор не может использоваться для записи. (Программы в защищенном режиме, построенные в так называемой модели памяти tiny , где все находится в одном сегменте памяти, должны использовать отдельные селекторы для кода и данных / стека, что делает оба селектора технически «псевдонимами»..) В случае GDT псевдонимы также создаются, чтобы получить доступ к системным сегментам, таким как TSS.

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

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

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

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

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

Ссылки
Внешние ссылки
Последняя правка сделана 2021-05-21 10:47:45
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте