Виртуальный режим 8086 - простой механизм, который
позволяет программе защищенного режима супервизора на
привилегированном уровне 0 диспетчеризовать программы 8086,
такие как программы персональных компьютеров IBM, на
пользовательском уровне. Виртуальный режим 8086, таким
образом, позволяет новым 80386 системам, работающим с
32-битным программным обеспечением, иметь доступ к большой
базе установленного программного обеспечения PC. С
виртуальным режимом 8086 программное обеспечение 8086
выполняется способом, подчиняющимся программе супервизора
защищенного режима на привелегированном нулевом уровне.
Просто из-за его пользы, виртуальное свойство 8086 -
хорошее дополнение к многим 32-битным 80386 системам.
Приложение G дает реальную, тестируемую супервизором
программу, которая запускает PC-DOS в виртуальном режиме 8086
на любом персональном компьютере.
Предыдущая глава закончилась обзором, как уровень
супервизора 80386 может диспетчеризовать программу
пользовательского уровня 32-битного защищенного режима. В
зависимом режиме работы виртуальный режим 80386 - простой
механизм, который позволет уровню супервизора
диспетчеризовать программу 8086 на пользовательском уровне.
Программы 8086, диспетчеризованные с использованием 8086
виртуального режима могут быть с любым об`ектным кодом. Это
может быть просто прикладная программа 8086 или даже
операционная система 8086. Различие не имеет значения, т.к.
все коды, выполненные в виртуальном 8086 режиме, присваиваются
8086 кодам. Виртуальный 8086 режим полностью совместим с 8086
в том же смысле, в котором реальный режим 80386 совместим с
8086.
После того, как отмечено сходство реального режима и
виртуального режима 8086, следует исследовать отличие. В
реальном режиме программа 8086, фактически, контролирует весь
80386, включая разрешение/запрещение прерываний и
использование команд ввода/вывода. В виртуальном 8086 режиме
программа 8086 существенно обманывается в "своих мыслях" о
том, что она контролирует все прерывания и ввод-вывод.
Все виртуальные программы 8086 выполняются на
привилегированном уровне 3. Это отличается от реального
режима, который неявно выполняяет (программы) как будто на
привилегированном уровне 0 (весь ввод/вывод допускается,
прерывания могут быть разрешены/запрещены). Менее
привилегированные программы виртуального режима позволяют
супервизору защищенного режима удерживать высокий уровень
контроля системы.
Когда виртуальная программа 8086 выполняется на
привилегированном уровне 3, большинство команд продолжает
работать верно, как и в совместимом реальном режиме 8086.
Однако, команды, которые пытаются находить и изменять бит
флага прерываний или выполнять ввод/вывод вызывают нарушение
основной защиты (13), возвращая управление программе
супервизора. Супервизор определяет, какая команда вызывает
нарушение и затем соответственно эмулирует команду.
Супервизор окончательно выполняет команду IRET, чтобы
возобновить программу 8086, которая выполнялась в виртуальном
режиме 8086. Работа в виртуальном режиме продолжается с
высокой скоростью до достижения следующей ограниченной
команды.
Быстрое выполнение переключения задач, разговор о котором
отложен до главы 15, единственный путь диспетчеризации в
виртуальном режиме 8086 лежит через команду IRET на
привилегированном уровне 0. Техника этого подобна
диспетчеризации программ в защищенном режиме на
пользовательском уровне, как показано на рис.11.5. Однако,
чтобы диспетчеризовать программу в виртуальном режиме 8086,
программатор устанавливает VM бит в EFLAG-образ в стеке. Бит
VM EFLAG-образа должен быть установлен 1. Введенная IRET
должна быть выполнена в защищенном режиме на
привилегированном уровне 0, т.к. только на этом уровне
возможно, чтобы бит VM фактически был установлен 1 внутри
80386. На каждом менее привилегированном уровне (1, 2, 3),
бит VM остается равным 0, даже если образ в EFLAG в стеке
содержит VM-образ 1. IRET должна быть в 32-битном кодовом
сегменте (или в 16-битнном кодовом сегменте с префиксом так,
что 32-битное значение загружается в EFLAG). VM-бит занимает
17-й бит, внутри вышележащего слова в EFLAG.
Т.к. команда IRET привилегированного уровня 0 читает кадр
стека, если она установит, что образ в EFLAG имеет VM=1,
80386 признает намерение войти в виртуальный 8086 режим.
Таким образом, он устанавливает, что соответствующий кадр
стека подготовлен, как показано на рис.12.1.
В кадре стека значения регистра таковы, что будут вначале
использованы программой, диспетчеризованной в виртуальном
режиме 8086. Биты EIP и ESP выше 16-го должны быть нулевыми,
что соответствует 16-битному виртуальному режиму работы 8086.
Значения селектора кадра стека для CS, SS, ES, DS, FS и GS
читаются 80386-м, и адреса базовых сегментов генерирутся как
умноженные на 16 значения селектора, что является обычным
использованием 8086-м значений селекторов. Адреса
базовых сегментов накапливаются в регистре дескриптора КЕШ
80386-го.
80386-й затем автоматически устанавливает границы сегмента
FFFFh для каждого виртуального сегмента 8086 в соответствии с
характеристиками 8086-го и имеет предел 64К в его внутренних
регистрах дескрипторов КЭШ. 80386 также устанавливает права
доступа в соответствии с работой 8086 и хранит их во
внутренних регистрах дескрипторов КЭШ. Всем виртуальным
сегментам 8086 даны права доступа для возможности чтения и
записи. Граница сегмента и права доступа не изменяются в
течении виртуального режима 8086.
Когда образ в EFLAG в кадре стека устанавливается 1, команда
IRET уровня 0 вводит виртуальный режим 8086 следующими шагами
(значение NT бита в образе EFLAG восстанавливается в 0, чтобы
избежать переключения задачи):
1. Чтение образа EFLAGS из стека, SS:[ESP+8], в регистр EFLAG.
Если образ EFLAGS имеет VM, установленный в 1, это
устанавливает VM в режим 80386.
2. Выталкивание (из стека) указателей команд виртуального
режима 8086 CS:EIP. EIP выталкивается первым, затем
выталкивается 32-битное слово, которое содержит CS в низших 16
битах. Если VM равен 1, загрузка CS будет выполняться как
загрузка сегмента в режиме реального времени.
3. Увеличение регистра ESP на 4, чтобы обойти образ EFLAGS,
который был вытолкнут на шаге 1.
4. Если VM равен 1 - загрузка сегментных регистров
виртуального режима 8086 ES, DS, FS и GS из ячеек стеков
SS:[ESP+8], SS:[ESP+12], SS[ESP+16] и SS:[ESP+20], соответственно,
где используется новое значение ESP, сохраненное на 3-м шаге.
5. Выталкивание указателя стека в виртуальном режиме 8086
SS:ESP из стека. ESP выталкивается первым, за ним следуют 32
бита, содержащие SS в низших 16 битах. Т.к. VM равно 1,
загрузка SS, будет выполняться как загрузка сегмента реального
режима.
6. Начало (или возобновление) выполнения виртуальной программы
8086 как программы 3-го уровня.
В виртуальном режиме 8086 размер операнда данных и размер
адреса по умолчанию 16 бит, как в реальном режиме. Некоторые
черты 80386, имеющихся в реальном режиме, такие как
дополнительные префиксы и дополнительные сегментные регистры FS
и GS, также имеются в виртуальном режиме 8086.
Загрузка сегментрых регистров выполняется так же, как в
реальном режиме: значение селектора умножается на 16 и прямо
устанавливает базовый адрес сегмента, который 80386-й сохраняет
в его внутреннем регистре дескриптора КЭШ для сегмента. Также
как в реальном режиме на границы сегмента и права доступа не
влияют загрузки сегментных регистров: они остаются FFFFh и
имеется доступ для чтения и записи.
В зависимости от уровня во время виртуального режима 8086,
установленного в битах 13 и 12 EFLAG-образа IRET кадра стека,
некоторые команды 8086 будут вызывать исключительную ситуацию.
Т.к. виртуальная программа 8086 выполняется как программа
привилегированного уровня 3, значения IOPL 2, 1 или 0 оказывают
препядствующее воздействие на некоторые команды во время
виртуального режима 8086.
Если IOPL - 2, 1 или 0, команды CLI, STI, PUSH, POPF и INTn
вызывают исключительную ситуацию общей защиты (исключительная
ситуация 13), когда они появляются во время виртуального режима
8086. Если супервизор защищенного режима устанавливает одно из
этих значений IOPL, виртуальной программе запрещена прямая
визуализация и изменение флага прерываний.
Таким же образом команды IN, INS, REP INS, OUT, OUTS и
REP OUTS могут вызывать исключительную ситуацию общей защиты
(исключительная ситуация 13),если поразрядная карта разрешения
ввода/вывода не разрешает ввод/вывод по специальному
включенному адресу ввода/вывода. Карта разрешения ввода/вывода
допускает очень специфическое управление вводом/выводом,
позволющее контролировать ввод/вывод на port-by-port основе.
Поразрядная карта, как произвольное расширение к каждому
32-битному TSS, показана на рис.12.3. Чтобы подвести итог,
заметим, что во время работы в виртуальном режиме 8086 IOPL не
влиет на возможность выполнения команд ввода/вывода. Только
карта разрешения ввода/вывода управляет разрешением
ввода/вывода во время виртуального режима 8086.
Незадолго до выполнения переключения задач, исключительная
ситуация общей защиты должна быть создана вентелем прерывания или
вентелем системного прерывания, который указывает на сегмент кода
привилегированного уровня 0 (т.е. на уровень супервизора). Когда
такая исключительная ситуация возникает, код супервизора
эмулирует команду, достигающую EIP кадра стека после команды
только что с`эмулированной, и выполняет команду IRET для
возобновления виртуальной программы 8086.
Конечно, команд защищенного режима, выполняяемых только на
привилегированном уровне 0, нет в виртуальном режиме 8086.
Попытки выполнить эти команды приводят к исключительной ситуации
общей защиты (исключительная ситуация 13). Однако, на практике,
существующие программы 8086 не пытаются выполнить такие команды,
т.к. их коды операций и регистры защищенного режима не
реализованы в 8086.
80386 выходит из виртуального режима 8086 только при
возникновении исключительной ситуации (такой как ситуация,
вызванная чуствительной командой) или прерыванием. Эти события
направляются через вентиль системного прерывания или вентиль
прерывания в кодовый сегмент привилегированного уровня 0 для
обслуживания. Все исключительные ситуации и прерывания
направляются через IDT защищенного режима, а не через таблицу
прерываний 8086.
Стек привилегированного уровня 0 после прерывания в
виртуальном режиме 8086 показан на рис.12.2, слева. Это, конечно,
то же самое, что и на рис.12.1, т.к. команда IRET используется в
обоих случаях для диспетчеризации виртуальной программы 8086.
Стек привилегированного уровня 0 после исключительной ситуации
во время виртуального режима 8086 также показан на рис.12.2. В
зависимости от типа исключительной ситуации в стеке может
появиться или не появиться ошибочный код. Каждый данный номер
исключительной ситуации ведет себя определенным образом; или он
всегда проталкивает (по стеку) ошибочный код, или не делает
этого, как показано в табл.12.1. В основном исключительные
ситуации, относящиеся к специфическим сегментам, проталкивают
ошибочный код. Исключительная ситуация отсутствия страницы в
оперативной памяти также проталкивает ошибочный код. Более
детальная информация об исключительных ситуациях и прерываниях,
включая точный формат кода ошибки, есть в главе 16.
Действие, производимое 80386-м для вентиля прерывания или
системного прерывания, когда возникает прерывание или
исключительная ситуация во время работы в виртуальном режиме
8086, описано детально ниже.
1. Сохранение регистра EFLAG во временный регистр для
проталкивания в стек супервизора позже. Сброс битов VM и TF в
ноль, и , если прерывание/исключение обслуживается вентилем
прерывания, восстановление IF в ноль тоже.
2. Вентиль прерывания или системного прерывания должен выполнять
переключение с уровня 3, где виртуальная программа 8086
выполняется, на уровень 0 так, чтобы команда IRET могла
передиспетчеризовать программу виртуального режима 8086 в конце
обслуживающей программы. Процесс вводит переключатель стека в
стек нулевого уровня установленный в TSS для привилегированного
уровня 0. Загрузка SS и ESP регистров виртуального
режима 8086 во временный накопитель для проталкивания на более
позднем этапе. Загрузка сегментного регистра SS уровня 0
выполняется как загрузка сегмента защищенного режима, т.к. бит VM
был восстановлен раньше.
3. В стек на нулевом уровне проталкивание по порядку GS, FS, DS
и ES. Каждый из этих регистров проталкивается как 32-битная
величина, чтобы держать стек выровненным. Верхние 16 бит каждой
величины равны нулю. Затем загрузка этих четырех регистров
нулевыми селекторами внутри, чтобы предотвратить использование
старых значений программой нулевого уровня.
4. Проталкивание регистра SS как 32-битн. величины с верхними
битами равными 0. Проталкивание 32-битного регистра ESP.
5. Проталкивание 32-битного регистра EFLAGS, cохраненного
вначале на 1-м шаге.
6. Проталкивание регистра CS как 32-битн. величины с верхними
битами равными 0. Проталкивание 32-битного регистра EIP.
7. Загрузка новых CS и EIP из вентиля прерываний или вентиля
системных прерываний. Загрузка сегментного регистра CS будет
выполняться как загрузка сегмента защищенного режима, т.к. бит VM
был восстановлен выше. Начало выполнения обслуживающей программы
нулевого уровня в защищенном режиме.
Команды ввода/вывода (IN, INS, REP INS, OUT, OUTS, REP и OUTS)
не чувствительны к IOPL в виртуальном режиме 8086. Скорее, эти
команды становятся автоматически чувствительными к поразрядной
карте разрешения ввода/вывода, необязательной компоненте
32-битного сегмента состояния задачи. Карта разрешения
ввода/вывода показана на рис.12.3 и 12.4.
Как показывает рис.12.3, карта разрешения ввода/вывода - это
поразрядная карта, содержащаяся в 32-битном сегменте состояния
задачи. Размер карты и ее расположение в сегменте TSS различны.
Она начинается в памяти с Bit_Map_Offset в TSS. 16-битное
значение Bit_Map_Offset 15.....0 устанавливается у смещения 102
(десятичной.) в фиксированной части TSS. От базового смещения
(Bit_Map_Offset) поразрядная карта разрешения ввода/вывода
продолжается на 8 Кбайт или до границы TSS, до того, что меньше.
Благодаря использованию указателя базы побитной карты
разрешения ввода/вывода, карта может быть расположена в любом
месте внутри TSS или может быть игнорирована полностью указанием
смещения Bit_Map_Offset за пределами сегмента TSS. Из-за
регулирования предела TSS для усечения побитной карты только
малая низшая часть 64 Кбайтной необходимой области ввода/вывода
имеет связанную побитную карту. Это устраняет блокирование 8К па-
мяти для того чтобы,при желании, был доступен более общий случай.
Каждый бит в побитной карте представляет разрешение ввода/
вывода для однобайтового порта в области ввода/вывода, от 0-порта
до порта 66535. Если бит равен 0, ввод/вывод через
соответствующий однобайтовый порт может возникать в вирттуальном
режиме 8086 без генерации иключительной ситуации. Если бит равен
1 или если соответствующий бит находится за пределами сегмента
TSS, попытка выполнить команду ввода/вывода приводит к генерации
исключительной ситуации защиты (исключительная ситуация 13).
Для порта ввода/вывода шириной в слово оба соответствующих
бита должны быть равны 0 для того, чтобы ввод/вывод происходил
успешно; для порта ввода/вывода шириной в двойное слово все 4
соответствующих бита должны быть равны 0, чтобы ввод/вывод
выполнялся успешно.
Чтобы корректно реализовать побитную карту ввода/вывода
требуется, чтобы байт FFh находился за последним байтом
информации карты ввода/вывода. Байт FFh должен быть внутри
границы сегмента TSS. Это требуется от байта FFh из-за того, что
внутренний алгоритм 80386-го считывает 2 байта побитной карты
ввода/вывода, когда бы ни происходило обращение к побитной карте.
Содержание
Вперед