Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
90
Добавлен:
23.02.2015
Размер:
6.18 Mб
Скачать

3.13. Структура сегмента tss

При записи в бите БКВВ нуля разрешается обращение к порту ввода-вывода, адрес (номер) которого соответствует порядковому номеру данного бита в карте ввода-вывода. Если значение некоторого бита БКВВ равно 1, то при поступлении команд обращения к соответствующему порту процессор реализует ис­ключение типа #GР (нарушение защиты).

Таким образом, использование БКВВ вводит для команд ввода-вывода дополнительный вид защиты (помимо выполнения условия СРL<IOPL), который устанавливается для каждого порта индивидуально. Эту защиту можно обеспечить как для всех, так и для части портов. Если конец БКВВ выходит за границу сегмента, определенную его размером, который задается дескриптором ТSS, то доступность соответствующих портов с высокими номерами не зависит от БКВВ. При этом БКВВ кон­тролирует доступ только к портам с меньшими номерами, для которых би­ты БКВВ вошли в заданную дескриптором границу сегмента. Если значе­ние размера сегмента, заданное дескриптором ТSS, меньше указанного в ТSS относительного адреса БКВВ, то эта карта не влияет на доступность портов, и ее можно полностью исключить.

Перед БКВВ располагаются 32 байта (256 бит) таблицы, опреде­ляющей способ обслуживания программных прерываний, реализуемых при поступлении команды INTn в режиме виртуального процессора 8086. Каждому из 256 значений n в команде INTn соответствует бит с таким же номером в данной таблице. Если этот бит имеет значение "1", то при поступлении соответствующей команды INTn вызывается под­программа обслуживания в защищенном режиме, обращение к которой производится с помощью таблицы прерываний IDT. Если бит в этой таблице имеет значение "0", то выполняется обращение к под­программе обслуживания, которая должна содержаться в составе выпол­няемой программы, написанной для процессора 8086 (вектор соответст­вующей подпрограммы обслуживания должен размещаться в таблице, расположенной в начале адресуемой памяти, адреса 0000h — 03FFh).

За последним байтом БКВВ в ТSS должен следовать заключитель­ный байт, содержащий 1 во всех разрядах (FFh). Адрес этого байта должен соответствовать границе сегмента, определенной дескриптором ТSS.

Объем дополнительной части ТSS зависит от размеров применяемой БКВВ и количества служебной информации, используемой операционной системой. Этот объем определяется характером решаемой задачи. Во многих случаях дополнительная часть ТSS вообще отсутствует.

Обращение к ТSS осуществляется путем загрузки в регистр TR се­лектора, который адресует размещенный в GDT дескриптор ТSS соответ­ствующей задачи (рис. 3.14). Содержимое регистра ТR можно загружать или заносить в память командами LTR, STR. Однако обычно команда LTR используется только при инициализации системы для уста­новки начального содержимого ТR. В процессе дальнейшей работы этот регистр загружается процессором при выполнении команд JMP, CALL, IRET, переключающих задачу.

Дескриптор ТSS должен храниться только в таблице GDT. Поэтому обращение к дескриптору ТSS с помощью селектора, имеющего бит TI=1 (индикатор таблицы LDT), вызовет исключение типа #ТS (ошибка обраще­ния к ТSS). При загрузке селектора дескриптора ТSS в какой-либо из регистров сегментов (СS, DS, SS, ЕS, FS, GS) возникает исключение того же типа.

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

Байт 7 Байт 6 Байт 5 Байт 4

31 24 23 22 21 20 19 16 15 14 13 12 11 10 9 8 7 0

Базовый адрес

ВА23-24

G

00

A

V

L

Граница

L19-16

P

DPL

0

1

0

B

1

Базовый адрес

ВА23-16

Базовый адрес

ВА15-0

15 Байты 3,2 Байты 1,0 0

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

Форматы дескриптора ТSS приведен на рис.3.14. Назначение битов присутствия Р и дробности G такое же, как в дескрипторах сегментов. Поле ТYPE (см. рис. 3.5,в) в байте доступа определяет тип за­дачи (см. табл. 3.2): код 01В1 указывает, что данная задача за­программирована для решения на 16-разрядном процессоре 80286, код 11B1 - что задача предназначена для 32-разрядных процессоров 386, 486, Pentium, Р6. Бит занятости В в этом байте устанавливается в состоя­ние В=1 при переключении на данную задачу. Указанная в дескрипторе граница сегмента ТSS должна иметь значение не менее, чем 67h, что со­ответствуют минимальному объему его обязательной части 104 байт. В противном случае при обращении к ТSS реализуется исключение типа #ТS. Неиспользуемый бит АVL в байте 6 дескриптора может быть исполь­зован операционной системой и установлен ею в любое состояние.

При выполнении задач, запрограммированных для решения 16-разрядным процессором 80286, структура сегмента ТSS изменяется (рис. 3.15). Объем обязательной части сегмента в этом случае составляет 44 байта, и его граница должна иметь значение не менее, чем 2Сh.

Переключение задач.

Для переключения задач процессор исполь­зует команды межсегментного перехода JUMP, вызова CALL и возврата IRET. Если селектор (sel16) команды JUMP или CALL выбирает из таблицы GDT дескриптор, который содержит в поле ТУРЕ байта доступа код 0001 (обращение к ТSS для процессора 80286) или 1001 (обращение к ТSS для процессоров 386, 486, Pentium, Р6), то выполняется переключение задач. При этом селектор sel16 заносится в регистр ТR, а в связанный с ним программно-недоступный регистр за­гружается дескриптор ТSS.

Селектор возврата

Ax

SP0

Ax+2

SS0

Ax+4

SP1

Ax+6

SS1

Ax+8

SP2

Ax+A

SS2

Ax+C

IP

Ax+E

FLAGS

Ax+10

AX

Ax+12

GX

Ax+14

DX

Ax+16

BX

Ax+18

SP

Ax+A

BP

Ax+1C

SI

Ax+IE

DI

Ax+20

ES

Ax+22

GS

Ax+24

SS

Ax+26

DS

Ax+28

Селектор LDT

Ax+2A

Дополнительная информация для ОС


Рис. 3.15. Структура сегмента TSS для процессора 80286

В соответствии с содержимым обязательной части ТSS производится загрузка регистров процессора, после чего он начинает выполнение поступившей задачи. Следует отметить, что межсегментные команды JUMP и CALL содержат байты eip32, определяющие новое содержимое регистра ЕIР. Однако, если селектор выбирает дес­криптор ТSS, то эти байты игнорируются, а регистр ЕIР загружается со­держимым соответствующего поля ТSS. При переключении задачи уста­навливается значение ТS=1 в регистре управления CR0, хранящем слово состояния машины MSW. Сброс этого бита в состояние Т5=0 может производиться командой CLTS или путем загрузки нового со­держимого в CR0 командами LMSW или MOV.

Переключение задач производится, если бит занятости В в байте доступа дескриптора ТSS вызываемой задачи имеет значение "0" (задача свободна). При В=1 выполняется исключение типа #GP (нарушение защи­ты). Установка значения В=1 (задача занята) в дескрипторе ТSS производится командами JUMP или CALL, переключающими процессор на выполнение данной задачи. Обращение к задаче, находящейся в процессе решения, которая имеет значение бита В=1, запрещено (вызовет исключе­ние #GР). Если решение данной задачи было прервано переключением на другую задачу, то возврат к ее выполнению может быть реализован только командой IRET.

При переключении задач с помощью команд JUMP или CALL долж­ны выполняться правила доступа, установленные для обращения к сег­ментам данных: DPL>=CPL, RPL, где значение DPL задается соответствующим полем в дескрипторе сегмента ТSS (рис.3.14). Таким образом, допускается переключение на решение задач, чья степень защи­ты меньше или равна уровню привилегий текущей программы и запроса.

При использовании команды САLL возможно обращение к задачам с более высокой степенью защиты, чем уровень привилегий текущей программы, с помощью шлюза задачи. Использование шлюзов задачи аналогично описанным шлюзам вызова. Дескриптор шлюза за­дачи, формат которого показан на рис. 3.16., может размещаться в любой из дескрипторных таблиц: GDT, LDT или IDT. Содержащийся в этом деск­рипторе селектор сегмента ТSS обращается к дескриптору ТSS, распола­гаемому в таблице GDT.

Обращение к шлюзу разрешается, если для текущей программы значение CPL, RPL <= gDPL, указанному в дескрипторе шлюза задачи. Селектор ТSS из дескриптора шлюза должен иметь значение бита ТI=1. Селектор загружается в регистр ТR и выбирает из GDT дескриптор ТSS, при этом значение уровня DPL указанное в выбранном дескрипторе, не учитывается. При нарушении указанных правил обращения возникает ис­ключение типа #ТS ("ошибка обращения к ТSS").

При использовании шлюзов задачи с меньшим уровнем привилегий могут вызывать более привилегированные (защищенные) задачи, поэтому возникает проблема обеспечения сохранности содержимого стеков. Это решается путем использования трех отдельных начальных адресов стеков, которые задаются тремя парами полей ТSS: SS0 и ЕSР0, SS1 и ЕSР1, SS2 и ЕSР2. Если дескриптор вызываемого ТSS имеет поле DPL=0, то при вы­зове задачи через шлюз в регистры SS и ЕSР процессора загружаются значения SS0 и ЕSР0. При DPL=1 загружается SS1 и ЕSР1, при DРL=2 загружается SS2 и ЕSР2. Если DPL=CPL=3, то создание отдельного стека не требуется, и вызванная задача продолжает заполнение и использова­ние стека, созданного в процессе выполнения старой (вызывающей) зада­чи. Таким образом, для задач каждого уровня привилегий создается от­дельный стек, что исключает возможность нарушения его содержимого задачами с более низким уровнем привилегий.

При переключении задач с помощью команды CALL содержимое TR заносится в два младших байта сегмента ТSS в качестве селектора, обес­печивающего возврат к выполнявшейся задаче. В этом случае в регистре EFLAGS устанавливается значение бита вложенной задачи NT=1. Таким образом, при последовательном использовании команды CALL можно реализовать многократное вложение задач.

Байты 7,6 Байт 5 Байт 4

31 16 15 14 13 12 11 8 7 0

Резервировано

P

DPL

0

0101

Резервировано

Селектор сегмента TSS

Резервировано

31 16 15 0

Байты 3,2 Байты 1,0

Рис. 3.16. Формат дескриптора шлюза задачи

Возврат из текущей задачи к выполнению предыдущей осуществля­ется с помощью команды IRET, которая анализирует значение NT. При NT =1 осуществляется обратное переключение на задачу, задаваемую селек­тором возврата в сегменте ТSS текущей задачи. В этом случае из ТSS возвращаемой задачи загружается сохранившееся содержимое основных регистров. При NT=0 команда IRET осуществляет обычную процедуру воз­врата из подпрограммы с восстановлением из стека содержимого регистров СS, ЕIР, EFLAGS.

Команда JUMP при переключении задач не сохраняет в ТSS селек­тор возврата и устанавливает значение NT=0. Кроме того, команды JUMP и CALL. по-разному влияют на значение бита занятости. Команда JUMP при переключении устанавливает в дескрипторе старой задачи значение бита занятости В=0, а в дескрипторе новой задачи — В=1. Команда САLL также устанавливает В=1 для новой задачи, но сохраняет В=1 и для предыдущей задачи. Таким образом, каждая задача в цепи вызовов с по­мощью команды САLL оказывается занятой, что запрещает применение рекурсивных процедур и реентерабельных программ.

Соседние файлы в папке УчПосбЧ-3