Материалы

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

Рейтинг:   / 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.

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