Трансляция адреса в защищенном режиме в проц-х x86

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

Рейтинг:   / 0

Переход на обработчик происходит через дескрипторы, содержащиеся в таблице дескрипторов прерываний Interrupt Descriptor Table (IDT). Каждый дескриптор связывает источник прерывания или исключения с подпрограммой (шлюз подпрограммы-обработчика) или с задачей (шлюз задачи) которая будет вызвана в ответ на событие, связанное с прерыванием (см. рисунок ниже).

Схема вызова обработчика прерывания

Начало и предел IDT содержатся в регистре IDT (RIDT). Таким образом, таблица шлюзов прерываний может находиться в любом месте физической памяти (в отличие от реального режима, где таблица векторов находится в младших адресах). Более того, ничто не мешает иметь системе несколько IDT. Для переключения на новую IDT требуется всего лишь изменить значение RIDT, для чего имеются привилегированные команды LIDT и SIDT.

Далее приведен формат дескрипторов шлюзов, которые могут содержаться в IDT (см. рисунок ниже).

Формат дескрипторов шлюзов

Подобно тому, как команда CALL может вызвать подпрограмму или задачу, прерывание (или исключение) может вызвать обработчкик, оформленный в виде подпрограммы обработки прерывания или в виде задачи (см. рисунок ниже).

Схема вызова программы через шлюз прерывания

Прерывания в защищенном режиме

Рейтинг:   / 0

Источниками запросов, "запускающих" процесс входа в прерывание могут быть события трех типов: аппаратные прерывания, исключения и программные прерывания (см. таблица ниже). В свою очередь, исключения подразделяются на: отказы (fault), ловушки (trap) и выходы из процесса (abort). Они различаются по способу реакции процессора.

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

Ловушка регистрируется также на границе между командами, но после окончания команды, вызвавшей прерывание, в стеке сохраняется адрес следующей команды. Примеры ловушек - программные прерывания INTO или INT3.

Выход из процесса - это исключение, после которого не только невозможно продолжить выполнение программы, вызвавшей прерывание, но и зачастую невозможно установить адрес команды, вызвавшей исключение.

 

 

Векторы прерываний в защищенном режиме

Байт доступа и типы сегментов. Типы сегментов кода и данных

Рейтинг:   / 0

Поле TYPE байта доступа в дескрипторах кода или данных содержит четыре однобитовых поля:

•Бит11 служит признаком вида сегмента: 0 - сегмент данных, 1 - сегмент кода.

•Бит8 - A-бит обращения (Access). При создании дескрипторов операционная система должна установить значение этого бита для всех сегментов нулевым. При загрузке сегмента в память процессор автоматически устанавливает этот бит в 1, сигнализируя тем самым, что к данному сегменту уже было обращение.

•Биты 9 и 10 имеют разное значение для сегментов данных и кода.

•Для сегмента данных:

Бит9 - W-бит разрешения записи (Write) : 0 - только чтение,
1- чтение/запись. При попытке записи в сегмент "только для чтения" произойдет прерывание по исключительной ситуации.

Бит10 - D-бит (Direction) - направление расширения сегмента. Если этот бит установлен, то сегмент предназначен для стека, который растет в направлении младших адресов. Этот бит влияет на способ контроля процессором превышения размера сегмента.

Для сегмента кода:

Бит9 - R-бит (Read) - разрешение чтения. Если этот бит установлен, то сегмент кода можно читать.

Бит10 - C (Conforming) - бит "подчинения" (будет рассмотрен далее).

Имеется 13 типов системных дескрипторов (см. таблицу ниже).

Для системного дескриптора поле TYPE содержит код типа объекта, описываемого дескриптором, сегментами являются только некоторые из этих объектов. Значения кодов также приведены ниже (см. таблицу ниже).

Привилегированные команды:

1. Нулевого приоритета;

2. Чувствительные команды:

•команды ввода.вывода,
•работы с прерываниями;

3. Команды работы с флагами IOPL IF.

Типы системных дескрипторов

Ряд команд может выполняться только программами, имеющими 0-й уровень приоритета (т.е. операционной системой). Вот эти команды:

•LGDT - Load GDT register;

•LLDT - Load LDT register;

•LTR - Load task register;

LIDT - Load IDT register;

•MOV (control registers) - Load and store control registers;

•LMSW - Load machine status word;

•CLTS - Clear task-switched flag in register CR0;

•MOV (debug registers) - Load and store debug registers;

INVD - Invalidate cache, without writeback;

•WBINVD - Invalidate cache, with writeback;

•INVLPG - Invalidate TLB entry;

•HLT - Halt processor;

•RDMSR - Read Model-Specific Registers;

WRMSR - Write Model-Specific Registers;

•RDPMC - Read Performance-Monitoring Counter;

•RDTSC - Read Time-Stamp Counter.

При загрузке сегмента данных (это происходит, когда программа перезагуржает один из сегментных регистров) анализируются три значения уровня привилегий (см. рисунок ниже):

1) CPL - уровень привилегий текущего сегмента кода

2) DPL - уровень привилегий сегмента, к которму происходит обращение

3) RPL - запрашиваемый уровень привилегий; это поле в селекторе операнда программист может установить сам, но не выше CPL, т.е. RPL CPL. Это позволяет понизить уровень привилегий.
Условие доступа: max (CPL, RPL =< DPL).

 

 

Загрузка сегмента данных

При обращении за операндами:

1) Если происходит обращение за данными не в сегменты данных или стека, а к сегменту кода, для которого запрещено чтение (контроль типа), возбуждается исключение.

2) Сравнивается offset и предел сегмента, если превышение - возбуждается исключение.

3) Если команда пытается записать в Read-Only сегмент данных (бит R=1) или в страницу, для которой запрещена запись, - также генерируется исключение.

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

При передаче управления посредством дальнего перехода, дальнего вызова или при программном прерывании адрес перехода задан (в команде или в векторе прерывания) в формате:

селектор_сегмента : смещение.

При этом происходит перезагрузка сегментного регистра CS новым значением селектора. Обычно это возможно только при выполнении условия CPL >=DPL (т.е. переход на более привилегированный сегмент кода невозможен и вызовет исключение). Однако это лишило бы возможности использования прикладной программой с низким уровнем привилегий сервисов ОС, работающих на более высоком уровне привилегий. Для разрешения этого противоречия реализованы два разных механизма.

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

 

Первый механизм разрешения противоречий

Однако этот способ не всегда годится. Иногда сервису ОС требуется обладать высоким уровнем привилегий, чтобы выполнить требуемую функцию (например, динамически выделить память - это часто означает - создать новый сегмент с заполнением дескрипторной таблицы).

Второй способ (см. рисунок ниже). Такой вызов можно безопасно допустить, если обеспечить возможность входа в вызываемый модуль только в предопределенной точке и при этом контролировать процесс передачи параметров. Это делается путем указания в дальнем адресе вызова не селектора сегмента кода, а селектора так называемого шлюза вызова (Call Gate). При таком переходе указываемое в адресе перехода смещение игнорируется (никак не используется) потому что "настоящие" селектор сегмента, куда будет выполнен вызов, содержатся в дескрипторе шлюза вызова, на который указывает селектор сегмента, заданный в команде call far.

Схема трансляции через шлюз

Функции шлюза (см. рисунок ниже):

1. Определение точки входа в процедуру;

2. Задание уровня привилегированности, требуемого для входа в процедуру;

3. Переключение стеков.

При проверке привилегий анализируются:

1) RPL>=CPL;

2) Текущий уровень привилегий должен позволить обратиться к "шлюзу вызова":

CPL>=CallGate-DPL.

 

Функции шлюза

Есть четыре разновидности шлюзов:

•Шлюз вызова подпрограммыCall gates;
•Шлюз программного прерывания или исключенияTrap gates;
•Шлюз аппаратного прерыванияInterrupt gates;
•Шлюз задачиTask gates.

Механизмы защиты при срабатывании вызывают исключения защищенного режима:

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

•Проверка при загрузке сегментных регистров:

- Превышение лимита таблицы дескрипторов (13);
- Несуществующий дескриптор сегмента (11 или 12);                                                                                                                                                                                                                - Нарушение привилегий (13).

- Загрузка неверного дескриптора или типа сегмента (13);

--загрузка в SS сегмента данных только чтения или сегмента кода,
-- загрузка управляющих дескрипторов в DS, ES или SS,
-- загрузка только исполняемых сегментов в DS, ES или SS,
-- загрузка сегмента данных в CS.

•Проверка ссылок операндов:

- Запись в сегмент кода или сегмент данных только для чтения (13);
- Чтение только из исполняемого сегмента кодов (13);
- Превышение лимита сегмента (12 или 13).

Проверка привилегий инструкций:

- CPL 0 при выполнении инструкций LIDT, LLDT, LGDT, LTR, LMSW, CTS, HLT, операций с регистрами DRn, TRn, CRn (13);
- CPL > IOPL при выполнении инструкций STI, CLI, а для 80286 еще и инструкции LOCK (13);
- CPL > IOPL при выполнении инструкций IN, INS, OUT, OUTS с портами, не разрешенными битовой картой ввода-вывода (13).

При выполнении команд IRET и POPF с недостаточным уровнем привилегий не изменяются биты IF и IOPL в регистре флагов, что не порождает исключений:

-IF не меняется, при CPL>IOPL;
-IOPL не меняется, если CPLO.

•Команды тестирования условий защиты:

Для того чтобы задачи не "нарывались" на срабатывание защиты, в систему команд введены специальные инструкции тестирования указателей. Они позволяют быстро удостовериться в возможности использования селектора или сегмента без риска порождения исключения:

ARPL - выравнивание RPL: он приравнивается максимальному значению из текущего RPL-селектора и поля RPL в указанном регистре. При изменении RPL устанавливается ZF=1;

•VERR - верификация чтения: если сегмент, на который указывает селектор, допускает чтение, устанавливается ZF=1;

•VERW - верификация записи: если сегмент, на который указывает селектор, допускает запись, устанавливается ZF=1;

•LSL - чтение лимита сегмента в регистр, если позволяют привилегии. При успехе устанавливается ZF=1;

LAR - чтение байта доступа дескриптора в регистр, если позволяют привилегии. При успехе устанавливается ZF=1.

Поддержка многозадачности в защищенном режиме процесоров 386+

Рейтинг:   / 0

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

Далее перечислены эти структуры, а также регистры процессора, поддерживающие многозадачность:

1) Сегменты состояния задачи (Task State Segment TSS);
2) Дескрипторы сегмента состояния задачи;
3) Дескрипторы шлюзов вызова задачи;
4) Регистр задач.

Рассмотрим эти элементы подробнее.

Сегмент состояния задачи TSS

Его структура изображена на рисунке (см. рисунок ниже). Каждая задача имеет собственный TSS.

Поля TSS можно разделить на две категории:

•Динамические. Процессор обновляет их значения при каждом переключении данной задачи. В эту категорию входят следующие поля:

- регистры общего назначения EAX, ECX, EDX, EBX, ESP, EBP, ESI и EDI;
- сегментные регистры ES, CS, SS, DS, FS и GS;
- регистр флагов EFLAGS;
- счетчик команд IP;
- селектор сегмента TSS предыдущей задачи.

Формат сегмента TSS

•Статические. При переключении задачи процессор только читает, но не обновляет эти поля. Их значения устанавливаются операционной системой при создании задачи. К этим полям относятся следующие:

- Селектор локальной дескрипторной таблицы задачи (каждая задача может иметь одну собственную LDT, но может и не иметь);

- Управляющий регистр CR3 (это BDPR - регистр базового адреса таблицы каталогов страниц;

- Логические адреса стеков для уровней привилегий 0, 1 и 2;

- Значение T-бита (включения режима пошаговой отладки);

-Базовый адрес карты разрешения портов ввода/вывода и карты переназначения прерываний (необязательные элементы). Если эти элементы присутствуют, то они сохраняются в верхних адресах TSS.

Дескриптор TSS

Сегмент состояния задачи, подобно другим сегментам, описывается дескриптором, имеющим следующий формат (см. рисунок ниже):

Формат дескриптора TSS

Рассмотрим особенности полей дескриптора. Поля базы, предела и DPL имеют то же назначение, что и для сегментов данных. Предел сегмента TSS должен быть равен или больше величины 67h (на 1 меньше минимального размера TSS - 68h). Размер TSS может быть и больше, при этом добавочное пространство может быть использовано операционной системой по своему усмотрению).

Задача не реентерабельна (т.е. не допускает рекурсивных вызовов). Для выявления попыток рекурсивного вызова служит бит занятости B (Busy Bit). Если задача была вызвана (и затем, возможно, прервана, например, вызовом друтой задачи), бит занятости устанавливается и остается установленным, что и будет признаком рекурсивного вызова при попытке вызвать эту задачу.

Переключение задачи происходит вследствие передачи управления через дескриптор TSS командами JMP или CALL, а также при прерываниях или исключениях через этот дескриптор.

Регистр задачи

Его содержимое показывает местонахождение в памяти текущего TSS. Этот регистр имеет видимую (т.е. программно доступную) часть, содержащую селектор TSS выполняемой в данный момент задачи и "теневую", которая автоматически заполняется процессором при переключении задачи и которая содержит базу и предел сегмента TSS. Селектор TSS является индексом дескриптора TSS, который может находиться только в GDT.

Привилегированные команды LTR и STR позволяют читать и писать этот регистр.

Дескриптор шлюза задачи

Дескриптор TSS обычно имеет высокий уровень привилегий, что исключает его использование "обычной" программой. Для обеспечения защищенного доступа к задаче используется шлюз задачи - дескриптор, имеющий низкий уровень привилегий, но обеспечивающий "косвенный" вызов на дескриптор TSS с высоким уровнем привилегий (см. рисунок ниже).

Формат шлюза TSS

Обратите внимание, что при использовании шлюза задачи защита анализирует DPL дескриптора шлюза, а не DPL дескриптора TSS.

Схема переключения задачи

Рисунок ниже иллюстрирует схему переключения задачи.

Процессор передает управление другой задаче в одном из четырех случаев:

1) Текущая задача выполняет JMP или CALL на дескриптор TSS.
2) Текущая задача выполняет JMP или CALL на шлюз задачи.
3) Прерывание или исключение происходит через шлюз задачи, находящийся в IDT.
4) Текущая задача выполняет команду IRET при установленном флаге NT (в CR0).

Схема переключения задачи

Вложенные задачи

При переключении задачи в ее TSS происходит заполнение ссылки на TSS предыдущей задачи. Эта информация используется для возврата на прерванную задачу после окончания задачи, ее прервавшей. Операционная система может модифицировать эти связи, изменяя записи в TSS. Каждая задача может иметь собственную LDT и систему трансляции страниц. Регистр PDBR (Page Directory Base Register) (CR3) загружается новым значением из TSS при переключении задачи.



Sitelinkx by eXtro-media.de

Защита

Рейтинг:   / 0

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

Проверки, выполняемые процессором при выполнении команд, можно подразделить на следующие категории:

•Limit checks - проверки превышения границы сегмента;

•Type checks - проверки допустимости типа дескриптора при обращении, возможности чтения или записи в сегмент;

•Privilege level checks - проверки уровня привилегий;

•Restriction of addressable domain - ограничение доступа к отдельным диапазонам адресов;

•Restriction of procedure entry-points - проверки доступности точек входа в процедуры (механизм шлюзования);

•Restriction of instruction set - проверки привилегированных команд.

Рассмотрим более подробно ситуации, в которых возможно срабатывание механизма защиты.

Прежде всего отметим, что в защищенном режиме каждой программе может быть присвоен один из четырех уровней привилегий (0 - наиболее привилегированный, 3 -наименее) - см. рисунок ниже.

Кольца защиты

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

При загрузке сегмента кода, его DPL помещается в младшие биты регистра CS это значение называется CPL (Current Privilege Level - текущий уровень привилегий), т.е. уровень привилегий выполняемого в данный момент кода.

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

 

Яндекс.Метрика