Скачиваний:
94
Добавлен:
16.04.2013
Размер:
396 Кб
Скачать
☆

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

Для многозадачных операционных систем, важна способность процессора к быстрому переключению между выполняемыми задачами. При этом должна обеспечиваться взаимная защита программ и данных, относящихся к различным задачам, а также возможность перехода от выполнения одной задачи к другой (переключение задач). Архитектура IA-32 имеет эффективные средства поддержки многозадачного режима, реализующие защиту и быстрое переключение задач. В качестве таких средств используется специальная структура данных, организованная в виде сегмента, который называется сегментом состояния задачи TSS. Аппаратными средствами для поддержки многозадачности служит 16-разрядный регистр задачи TR, в который заносится селектор дескриптора TSS, и связанный с TR программно недоступный 64-разрядный регистр, в который из GDT загружается 8-байтовый дескриптор TSS.

Сегмент состояния задачи TSS, структура которого показана на рис. $10, состоит из двух частей. Обязательная часть TSS объемом 104 байта (68h) содержит всю информацию, необходимую процессору для решения данной задачи. Это не только образы всех рабочих регистров, но и регистр LDT, несущий информацию о сегментном наборе задачи, т.е. о линейном адресном пространстве задачи, а также регистр CR3, указывающий на виртуальное адресное пространство задачи.

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

Первые два байта в сегменте TSS используются для хранения селектора TSS предыдущей задачи, при выполнении которой произошел вызов данной задачи. В эти байты заносится содержимое регистра TR для предыдущей задачи, чтобы обеспечить возврат к ее выполнению. Поэтому данный селектор называется селектором возврата. Отдельные поля TSS хранят содержимое сегментных регистров ES, CS, SS, DS, FS, GS, регистров общего назначения ЕАХ, ЕСХ, EDX, ЕВХ, ESP, ЕВР, ESI, EDI, регистра флагов EFLAGS и указателя инструкций EIP. При переключении задач содержимое указанных полей из вызванного TSS загружается в соответствующие регистры процессора. При следующем переключении текущее содержимое регистров заносится в TSS данной задачи, после чего производится загрузка регистров из TSS новой задачи. Таким образом, содержимое TSS обновляется при каждом переключении задачи, фиксируя текущее состояние.

31

16

15

0

Резервировано (0…0)

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

Ax

ESP0

Ax+4

Резервировано (0…0)

SS0

Ax+8

ESP1

Ax+C

Резервировано (0…0)

SS1

Ax+10

ESP2

Ax+14

Резервировано (0…0)

SS2

Ax+18

CR3

Ax+1С

EIP

Ax+20

EFLAGS

Ax+24

EAX

Ax+28

ECX

Ax+2С

EDX

Ax+30

EBX

Ax+34

ESP

Ax+38

EBP

Ax+3С

ESI

Ax+40

EDI

Ax+44

Резервировано (0…0)

ES

Ax+48

Резервировано (0…0)

CS

Ax+4С

Резервировано (0…0)

SS

Ax+50

Резервировано (0…0)

DS

Ax+54

Резервировано (0…0)

FS

Ax+58

Резервировано (0…0)

GS

Ax+5С

Резервировано (0…0)

LTD

Ax+60

Относительный адрес БКВВ

Резервировано (0…0)

T

Ax+64

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

Битовая карта перенаправления прерываний

(Interrupt Redirection Bit Map)

Битовая карта разрешения ввода-вывода (БКВВ)

(I/O Permission Bit Map)

11111111

Рис. $10. Структура сегмента TSS

Содержимое ряда полей в обязательной части TSS не изменяется при решении задачи. Так не изменяется содержимое поля, определяющего значение селектора LDT для данной задачи, и содержимое регистра управления CR3, которое используется при страничной организации памяти. Не изменяется также содержимое полей SS0, ESP0, SS1, ESP1, SS2, ESP2, которые определяют начальный адрес стека при переключении к задачам с более высоким уровнем привилегий PL=0,1,2. Такое выделение отдельных стеков для задач с различными уровнями привилегий обеспечивает их более надежную защиту. Содержимое указанных полей TSS загружается в соответствующие регистры в процессе выполнения конкретной задачи.

Бит ловушки Т в сегменте TSS вызывает при Т=1 исключение типа #DB (“исключение отладки”) при переключении на данную задачу. Это исключение используется при отладке программного обеспечения.

Два последних байта в обязательной части TSS определяют относительный адрес начала битовой карты ввода-вывода (БКВВ) в TSS. Каждый бит БКВВ соответствует однобайтовому порту ввода-вывода. Так как процессор обеспечивает обслуживание до 65536 портов, то полная БКВВ, определяющая возможность их обслуживания, будет представлять строку длиной 8KB (2000h). При записи в бите БКВВ нуля разрешается обращение к порту ввода-вывода, адрес (номер) которого соответствует порядковому номеру данного бита в карте ввода-вывода. Если значение некоторого бита БКВВ равно 1, то при поступлении инструкций обращения к соответствующему порту процессор реализует исключение типа #GP (нарушение защиты).

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

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

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

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

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

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

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

Байт 7

Байт 6

Байт 5

Байт 4

31

24

23

22

21

20

19

16

15

14

13

12

11

8

7

0

BA[31:24]

G

0

0

Avail

Граница L[19:16]

P

DPL

0

TYPE

BA[23:16]

Базовый адрес BA[15:0]

Граница сегмента L[15:0]

31

16

15

0

Байты 3,2

Байты 1,0

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

Формат дескриптора TSS приведен на рис.$11. Назначение битов присутствия P и дробности G такое же, как в дескрипторах сегментов (см. рис.$4). Поле TYPE (см. рис. $5,в) в байте доступа определяет тип задачи (см. табл. $1): код 11В1 – что задача предназначена для 32-разрядных процессоров 386+, а код 01B1 указывает, что данная задача запрограммирована для решения на 16-разрядном процессоре 80286. Бит занятости B (Busy) устанавливается в состояние B=1 при переклю­чении на данную задачу. Указанная в дескрипторе граница сегмента TSS должна иметь значение не менее чем 67h, что соответствуют минимальному объему его обязательной части 104 байт. В противном случае при обращении к TSS реализуется исключение типа #TS. Неиспользуемый бит (Available) в байте 6 дескриптора может быть использован операционной системой и установлен ею в любое состояние.

При выполнении задач, запрограммированных для решения процессором 80286, структура сегмента TSS упрощается, но здесь не описана.

Переключение задач. Для переключения задач процессор использует инструкции межсегментного перехода JUMP, вызова CALL и возврата IRET. Если селектор инструкции JUMP или CALL выбирает из таблицы GDT дескриптор, который содержит в поле TYPE байта доступа код 0001 (обращение к TSS для процессора 80286) или 1001 (обращение к TSS для процессоров 386+), то выполняется переключение задач. Причем, этот селектор заносится в регистр TR, а в связанный с ним программно-недоступный регистр загружается дескриптор TSS. В соответствии с содержимым обязательной части TSS производится загрузка регистров процессора, после чего он начинает выполнение поступившей задачи. Следует отметить, что межсег­ментные инструкции JUMP и CALL содержат байты, определяющие новое содержимое регистра EIP. Однако если селектор выбирает дескриптор TSS, то эти байты игнорируются, а в регистр EIP загружается содержимое соответствующего поля TSS. При переключении задачи устанавливается значение TS=1 в регистре управления CR0. Сброс этого бита в состояние TS=0 может производиться инструкцией CLTS или путем загрузки нового содержимого в CR0 инструкциями LMSW или MOV.

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

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

При использовании инструкции CALL возможно обращение к задачам с более высокой степенью защиты, чем уровень привилегий текущей программы, с помощью шлюза задачи. Использование шлюзов задачи аналогично описанным ранее шлюзам вызова. Дескриптор шлюза задачи, формат которого показан на рис. $12, может размещаться в любой из таблиц дескрипторов: GDT, LDT или IDT. Содержащийся в этом дескрипторе селектор сегмента TSS обращается к дескриптору TSS, располагаемому в таблице GDT.

Обращение к шлюзу разрешается, если для текущей программы, указанное в дескрипторе шлюза задачи значение gDPL max(CPL,RPL),. Селектор TSS из дескриптора шлюза должен иметь значение бита TI=1. Селектор загружается в регистр TR и выбирает из GDT дескриптор TSS, при этом значение уровня DPL, указанное в выбранном дескрипторе, не учитывается. При нарушении указанных правил обращения возникает исключение типа #TS (“ошибка обращения к TSS”).

Байты 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

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

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

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

Возврат из текущей задачи к выполнению предыдущей осуществляется с помощью инструкции IRET, которая анализирует значение NT. При NT=1 осуществляется обратное переключение на задачу, задаваемую селектором возврата в сегменте TSS текущей задачи. В этом случае из TSS возвращаемой задачи загружается сохранившееся содержимое основных регистров. При NT=0 инструкция IRET осуществляет обычную процедуру возврата из подпрограммы с восстановлением из стека содержимого регистров CS, EIP, EFLAGS.

Инструкция JUMP при переключении задач не сохраняет в TSS селектор возврата и устанавливает значение NT=0. Кроме того, инструкции JUMP и CALL по-разному влияют на значение бита занятости. Инструкция JUMP при переключении устанавливает в дескрипторе старой задачи значение бита занятости B=0, а в дескрипторе новой задачи – В=1. Инструкция CALL также устанавливает B=1 для новой задачи, но сохраняет B=1 и для предыдущей задачи. Таким образом, каждая задача в цепи вызовов с помощью инструкции CALL оказывается занятой. Отметим, что запрещает применение рекурсивных процедур и реентерабельных программ. На рис. $13 показана цепочка вложенных задач, вызванных инструкциями CALL.

Таблица GDT

Регистр

Сегмент TSS

Корневая

EFLAG

Селектор

Дескриптор TSS

задача

NT=0

возврата

TYPE

B=1

Регистр

Сегмент TSS

Вложенная

EFLAG

Селектор

Дескриптор TSS

задача

NT=1

возврата

TYPE

B=1

Регистр

Сегмент TSS

Текущая

EFLAG

Селектор

Дескриптор TSS

выполняемая

NT=1

возврата

TYPE

задача

B=1

Регистр TR

Рис. $13. Цепочка вложенных задач, образованная инструкциями CALL.

$.4. Реализация режима виртуального 8086 (V86)

Прикладные программы для 8086 могут исполняться в IA-32, как в реальном режиме, так и в режиме виртуального 8086 (V86), который является особым состоянием задачи защищенного режима. Назначение этого режима – формирование виртуальной машины, эмулирующей процессор 8086. Виртуальная машина формируется программными средствами операционной системы – монитором V86, который поддерживается специальными аппаратными средствами процессора. Режим V86 позволяет пользоваться аппаратными средствами поддержки многозадачности. В этом режиме работают защита и механизм страничной переадресации, позволяющий адресоваться к любой области пространства физической памяти размером 4 Гбайт. Выполнение приложений 8086 в среде V86 возможно параллельно с приложениями защищенного режима. Страничная переадресация позволяет параллельно выполняться нескольким задачам V86 с возможностью совместного использования общих областей кода операционной системы и разделения реальных аппаратных ресурсов компьютера. В процессорах 486+ появилось расширение виртуального режима – EV86 (Enhanced Virtual 8086). Это расширение позволяет ускорить обработку прерываний, перенести ряд функций формирования виртуальной машины с программного обеспечения на аппаратные средства процессора, и тем самым существенно повысить производительность.

Для входа в режим V86 необходима установка бита VM в регистре EFLAGS, это делается одним из двух способов:

  • выполнение инструкции IRET в 32-битном режиме, когда образ EFLAGS сохранен в стеке с установленным битом VM (при CPL=0, иначе бит VM не установится);

  • переключение на задачу с TSS-386+, у которой в TSS образ EFLAGS имеет установленный бит VM.

Для использования режима EV86 необходимо также установить бит VME в регистре CR4.

Выход из режима V86 (EV86) возможен только при обработке прерывания. Если вызываемая процедура имеет CPL=0, то бит VM будет сброшен, и она будет выполняться в защищенном режиме. Если ее CPL>0, произойдет исключение #GP – нарушение защиты. Если прерывание вызывает переключение задач, состояние регистров с установленным флагом VM сохранится в TSS старой задачи, к которой можно будет вернуться. Новый режим (защищенный или V86) установится в соответствии с TSS новой задачи.

Схема взаимодействия защищенного режима и режима V86 (EV86) показана на рис. $14, обозначения: «ПЗ» - Переключение задач; IRET – инструкция возврата из прерывания.

Значение бита VM не может быть изменено никакими другими способами; кроме того, его значение не может быть прочитано – при любом программном сохранении регистра флагов значение VM всегда показывается нулевым. Так что приложение, выполняемое в среде V86, никак не может ни переключить режим процессора, ни распознать, в каком режиме – реальном или виртуальном – оно исполняется. Это, конечно же, справедливо при корректно построенном мониторе виртуальной машины V86, являющемся частью ОС защищенного режима. Процессор для этого предоставляет все необходимые аппаратные средства, позволяющие выполнить полную эмуляцию 8086.

Начальный вход

Монитор

V 86

ПЗ

Другие задачи

Защищенный

режим

IRET

ПЗ или

Режим

исключение

V86 (EV86)

Программа

ПЗ

ПЗ или IRET

М П8086

IRET

Исключение

Режим

для EV86

EV86

Обработка исключений внутри виртуальной машины

Рис. $14. Схема взаимодействия защищенного режима и режима V86 (EV86).

Монитор V86 представляет собой модуль 32-битного программного кода, исполняющийся с CPL=0. Он содержит обработчики прерываний и исключений, средства инициализации задач V86 и эмуляции операций ввода/вывода. Монитор тесно связан с обработчиком исключения #GP, через который в основном и происходит общение с приложениями 8086.

В режиме V86 программе доступны все регистры 8086, а с помощью префикса изменения разрядности операндов – и их 32-битные расширения. В качестве сегментных регистров через префиксы замены сегментов возможно также использование регистров GS и FS, которых в реальном 8086 нет. По умолчанию адресация 16-битная, но с помощью префикса изменения разрядности адреса возможна 32-битная адресация. Набор инструкций включает не только все инструкции 8086 и последующие расширения. Однако, попытка выполнения системных инструкций, допустимых только для защищенного режима – LTR, STR, LLDT, SLDT, LAR, LSL, ARPL, VERR и VERW, - вызовет исключение #UD.

Модель памяти в режиме V86 имеет некоторые особенности. По умолчанию в режиме V86 используются 16-разрядные регистры и исполнительные адреса. С помощью префиксов размера можно производить обработку 32-разрядных операндов и формировать 32-разрядные адреса. Однако значение полученного физического адреса в режиме V86 не должно превышать 64К, в противном случае возникает исключение типа #GP.

При работе в режиме V86 процессор формирует 20-разрядный линейный адрес таким же способом, как в реальном режиме. При использовании страничной адресации, адресуемая в режиме V86 память объемом 1М-байт делится на 256 страниц по 4KB. Младшие 12 разрядов линейного адреса выбирают адресуемый байт внутри страницы, а старшие 8 разрядов определяют с помощью таблицы страниц базовый адрес страницы. Каталог разделов в режиме V86 не используется, и базовый адрес таблицы страниц задается содержимым регистра CR3. Отдельные страницы могут быть размещены в любом месте адресного пространства, имеющего объем 4 Гбайта. Каждая задача в режиме V86 может использовать свои варианты размещения страниц, так как при переключении задач загружается заново содержимое регистра управления CR3, определяющее базовый адрес таблицы страниц. Таким образом, для некоторой задачи V86 можно добиться «сворачивания в кольцо» памяти размером 1М-байт, свойственного 8086 (отобразив адреса выше FFFFFh на ту же физическую память, что и начинающиеся с нуля).

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

Особую проблему в режиме V86 составляет обработка прерываний. Именно о прерываниях мы и поговорим далее.

Контрольные вопросы.

  1. Режим называется защищённым потому что он защищает …

  1. … операционную систему от вирусов

  2. … операционную систему от задач пользователя

  3. … одну задачу от другой

  4. … более привилегированные задачи от менее привилегирован­ных

  1. Размер селектора сегмента

    1. 2 байта

    2. 4 байта

    3. 8 байтов

    4. другой

  2. Размер дескриптора сегмента

    1. 2 байта

    2. 4 байта

    3. 8 байтов

    4. другой

  3. Укажите верные утверждения

    1. В IDT есть указатели на LDT и GDT

    2. В GDT есть указатели на LDT и IDT

    3. В LDT есть указатели на IDT и GDT

  4. Дескрипторы шлюза могут быть в таблице

    1. LDT

    2. GDT

    3. IDT

  5. На сегмент TSS может указывать дескриптор из таблицы

    1. LDT

    2. GDT

    3. IDT

33

Соседние файлы в папке M4