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

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 (EnhancedVirtual8086). Это расширение позволяет ускорить обработку прерываний, перенести ряд функций формирования виртуальной машины с программного обеспечения на аппаратные средства процессора, и тем самым существенно повысить производительность.

Для входа в режим 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.

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

Монитор

V86

ПЗ

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

Защищенный

режим

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