Из Википедии, бесплатной энциклопедии
  (Перенаправлено из таблицы локальных дескрипторов )
Перейти к навигации Перейти к поиску

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

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

GDT может содержать и другие вещи, кроме дескрипторов сегментов . Каждая 8-байтовая запись в GDT является дескриптором, но эти дескрипторы могут быть ссылками не только на сегменты памяти, но и на сегмент состояния задачи (TSS), локальную таблицу дескрипторов (LDT) или структуры шлюза вызовов в памяти. Последние, Call Gates, особенно важны для передачи управления между уровнями привилегий 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 .code: ; cs должен указывать на этот дескриптор dw  0xffff ; ограничение сегмента первые 0-15 бит dw  0 ; базовые первые 0-15 битов db  0 ; базовые 16-23 бита db  0x9a ; байт доступа db  11001111 b ; старшие 4 бита (флаги) младшие 4 бита (ограничение 4 последних бита) (ограничение шириной 20 бит) db  0 ; база 24-31 бит; Смещение 0x10 .data: ; ds, ss, es, fs и gs должны указывать на этот дескриптор dw  0xffff ; ограничение сегмента первые 0-15 бит dw  0 ; базовые первые 0-15 битов db  0 ; базовые 16-23 бита db  0x92 ; байт доступа db  11001111 b ; старшие 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: начальный адрес в линейной памяти, размере, executability, writability, привилегии доступа, фактическом присутствии в памяти, и т.п.

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 псевдонимы также создаются для доступа к системным сегментам, таким как 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-битного адресного пространства.

Ссылки [ править ]

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

Внешние ссылки [ править ]

  • Руководство разработчика программного обеспечения для архитектуры Intel
  • Таблица GDT на OSDev.org
  • Учебное пособие по GDT на OSDev.org
  • Учебное пособие по GDT для разработчиков ядра Брана
  • Защищенный режим BrokenThorn