Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТСИС.doc
Скачиваний:
170
Добавлен:
11.05.2015
Размер:
1.18 Mб
Скачать

35. Управление сегментами в защищенном режиме. Дескрипторные таблицы. Дескрипторы сегментов.

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

При всем этом у системного программиста имеется больше возможностей по управлению сегментацией памяти. Так, уже в микропроцессоре i80386 сняты ограничения на размер сегмента. Он может иметь значение от 1 байта до 4 Гбайт. В нем также сняты ограничения на местоположение границы сегмента. Граница сегмента больше не привязана к границе параграфа, да и само понятие "параграф" к защищенному режиму работы микропроцессора не применяется. Программист в описании сегмента сам определяет уровни привилегий и тип используемого сегмента.

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

1. Возможен переход от сегмента к сегменту, имеющих один и тот же уровень привилегий.

2. Возможно обращение к сегменту данных, имеющему тот же или более низкий уровень привилегий, чем сегмент кода.

3. Если необходимо перейти к сегменту кода, имеющий более высокий уровень привилегий, необходимо использовать вентиль.

Дескрипторные таблицы — служебные структуры данных, содержащие дескрипторы сегментов. В архитектуре x86 есть три вида дескрипторных таблиц:

  • Глобальная дескрипторная таблица (англ. Global Descriptor Table, GDT);

  • Локальная дескрипторная таблица (англ. Local Descriptor Table, LDT);

  • Таблица векторов прерываний (англ. Interrupt Descriptor Table, IDT);

Глобальная дескрипторная таблица одна. Она общая для всех задач. Её размер и расположение в физической памяти определяются регистром GDTR. Размер таблицы не может превышать 8192 дескрипторов, поскольку один дескриптор занимает 8 байт, а лимит в регистре GDTR - двухбайтный и хранит размер таблицы минус один (максимальное значение лимита - 65535), а 8192 x 8 = 65536.

Дескрипторы LDT и сегментов задач (TSS) могут находиться только здесь.

Особенностью GDT является то, что у неё запрещён доступ к первому (с нулевым смещением относительно начала таблицы) дескриптору. Обращение к нему вызывает исключение #GP, что предотвращает обращение к памяти с использованием незагруженного сегментного регистра.

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

Размер и расположение LDT в линейной памяти определяются дескриптором LDT из GDT (но это не означает, что размер LDT может быть больше 65536 байт).

Первый дескриптор LDT (№0) использовать можно.

Таблица прерываний глобальна. Размещение в физической памяти определяется регистром IDTR.

При возникновении прерывания (внешнего, аппаратного, или вызванного инструкцией Int):

  • из IDT выбирается дескриптор шлюза, соответственно номеру прерывания;

  • проверяются условия защиты (права доступа);

  • при соблюдении условий защиты выполняется переход на подпрограмму-обработчик этого прерывания

Дескриптор сегмента — служебная структура в памяти, которая определяет сегмент. Длина дескриптора равна восьми байтам.

Структура сегментного дескриптора

База (жёлтые поля, 32 бита) — начало сегмента в линейной памяти

Лимит (красные поля, 20 бит) — (размер сегмента в байтах)-1 (База+Лимит = линейный адрес последнего байта)

Права доступа (синие поля, 12 бит) — флаги, определяющие наличие сегмента в памяти, уровень защиты, тип, разрядность + один пользовательский флаг[1]

Байт прав доступа (AR, англ. Access Rights, биты 8-15 на рисунке):

Бит P определяет доступность сегмента (0 — сегмента нет, 1 — есть). При обращении к сегменту со сброшенным битом P происходит исключение #NP, обработчик которого может загрузить/создать сегмент.

Номер привилегий DPL содержит 2-битный номер (0-3), определяющий, к какому уровню (кольцу) защиты относится этот сегмент.

Тип сегмента (биты 8-12 на рисунке). Старший бит (S) определяет сегмент как системный (S=0) или пользовательский (S=1). Значение прочих бит для системных и пользовательских сегментов описано в таблице:

Типы системных сегментов

№ Биты AR(3210) Описание

0 0000 Зарезервировано

1 0001 Свободный 16-битный TSS

2 0010 LDT

3 0011 Занятый 16-битный TSS

4 0100 16-битный шлюз вызова

5 0101 Шлюз задачи

6 0110 16-битный шлюз прерывания

7 0111 16-битный шлюз ловушки

8 1000 Зарезервировано

9 1001 Свободный 32-битный TSS

A 1010 Зарезервировано

B 1011 Занятый 32-битный TSS

C 1100 32-битный шлюз вызова

D 1101 Зарезервировано

E 1110 32-битный шлюз прерывания

F 1111 32-битный шлюз ловушки

Типы пользовательских сегментов

№ Биты AR(321) Описание

0 000 Сегмент данных только для чтения

2 001 Сегмент данных для чтения/записи

4 010 Сегмент данных только для чтения, растёт вниз

6 011 Сегмент данных для чтения/записи, растёт вниз

8 100 Сегмент кода только для выполнения

A 101 Сегмент кода для выполнения/чтения

C 110 Подчинённый сегмент кода только для выполнения

E 111 Подчинённый сегмент кода для выполнения/чтения

Младший бит байта AR пользовательских сегментов (A, англ. Accessed, бит 8 на рисунке) можно использовать для сбора статистики о сегменте. При первом же обращении к сегменту (чтение, запись, выполнение) он устанавливается процессором в 1.

Флаг гранулярности G определяет лимит сегмента: при G=0 лимит равен значению соответствующего поля в дескрипторе, а при G=1 лимит равен полю дескриптора, умноженному на (212 = 4096). Таким образом при G=0 максимальный размер сегмента 1 МБайт, а при G=14 ГБайт.

Флаг разрядности DB (бит 22 на рисунке) актуален для пользовательских сегментов кода и стека. Определяет разрядность в 16 бит при нулевом и 32 бит при единичном значении.

Зарезервированный флаг (серое поле) должен всегда равняться нулю.

Пользовательский флаг AVL (A, бит 20 на рисунке) отдан операционной системе. Его состояние никак не влияет на работу с сегментом.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]