Переключение режимов работы процессора

11/07/94 02:55pm zr_prej.lek
А.В.Фролов, Г.В.Фролов "Защищенный режим процессоров Intel 80286/80386/80486. Практическое руководство по использованию защищенного режима" БСП том 6 М "Диалог-МИФИ" 1993
--"i486tm микропроцессор" в 2-х книгах Библиотека программиста "И.В.К.-СОФТ" М 1993

Переключение режимов работы процессора.

ПРИМЕЧАНИЕ: Изложенный материал (примеры) можно применить только на компьютерах, совместимых с IBM AT. Должна использоваться ОС MS DOS с неактивными драйверами "верхней памяти" (QEMM, EMM386).
Описание выполнено для процессора i80286.

Переключение в защищенный режим:

  1. Необходимо подготовить глобальную таблицу дескрипторов GDT. Она должна содержать описание всех используемых областей, в том числе иметь ссылку на себя. В этом случае ее можно будет изменять, программами с наивысшим уровнем привилегий (0).

  2. Необходимо подготовить возможность возврата в реальный режим. Механизм возврата в процессоре i286 отличается от механизма в i386+, но совместимость поддерживается.
    Возврат осуществляется выполнением аппаратного сброса процессора.

    При поступлении сигнала начальной установки начинается выполнение программы начальной инициализации, расположенной в BIOS. Эта программа обращается к энергонезависимой памяти и читает байт, определяющий особенности выполнения загрузки (адрес этого байта в CMOS-памяти 0Fh, а интересующее нас значение 0Ah или 05h). Если прочитанное значение 0Ah, то никаких специальных действий не выполняется, а просто передается управление по адресу, взятому из ячейки BIOS 0040:0067h. Если указано 05h, то перед пердачей управления будет произведена инициализация контроллера прерываний (это необходимо, если в защищенном режиме использовалась работа с прерываниями и настройка контроллера была изменена).

  3. 3 Далее необходимо запретить маскируемые и немаскируемые прерывания. Запрет маскируемых прерываний выполняется соответствующей коммандой процессора. Немаскируемые прерывания блоккируются внешними схемами.

  4. Разрешается работа старших линий адреса - линии A20. Управление этой линией в компьютере AT осуществляет процессор клавиатуры.

  5. Сохраняется необходимая информация (указатель стека).

  6. Загружается указатель на таблицу глобальных дескрипторов в регистр GDTR.

  7. Осуществляется переключение в защищенный режим, установкой младшего бита в регистре слова состояния машины (MSW).

  8. Поскольку выполнение команд зависит от установленного режима, необходимоочистить очередь команд. Это осуществляется командой JMP непосредственно после LMSW. Значение сегментных регистров после входа в защишенный режим сохраняется. Выполнение программы начинается при CPL=0.

Возврат в реальный режим:

  1. Выполняется сброс процессора.

  2. Восстанавливаются регистры реального режима.

  3. Уже находясь в реальном режиме необходимо закрыть линию A20.

  4. Затем разрешаются маскируемые и немаскируемые прерывания.
    Для полного демаскирования прерываний следует сбросить маску в контроллере прерываний.

RADIX 16 ; Все числа 16-ные

P286 ; Процессор i286

; Память для хранения регистров SS, SP. Содержимое

; этих регистров будет записано здесь перед входом в

; защищённый режим и восстановлено отсюда после возврата

; из защищённого режима в реальный.

real_ss dw ?

real_sp dw ?

; Выполняем все подготовительные действия для перехода

; в защищённый режим и обеспечения возможности возврата

; в реальный режим

; Считаем, что таблица создана и полностью заполнена!

; Записываем адрес возврата в реальный режим в область

; данных BIOS по адресу 0040h:0067h

mov ax,40 ; сегмент области данных BIOS

mov ds,ax

mov [WORD 67],OFFSET shutdown_return ; точка возврата

mov [WORD 69],cs

; Маскируем все прерывания, в том числе немаскируемые.

; Записываем в CMOS-память в ячейку 0Fh код 5,

; этот код обеспечит после выполнения сброса процессора

; передачу управления по адресу, подготовленному нами

; в области данных BIOS по адресу 0040h:0067h.

; Для того, чтобы немаскируемые прерывания были запрещены,

; устанавливаем в 1 старший бит при определении ячейки CMOS.

cli

mov al,8f ; 0f - регистр CMOS-памяти, а ст. бит маскирует

; немаскируемое прерывание

out 70h,al ; порт для доступа к CMOS-памяти

jmp next1 ; небольшая задержка

next1:

mov al, 5

out 70h+1,al ; код возврата

; ------------------------------------------------------------

; Открываем адресную линию A20

; ------------------------------------------------------------

mov al,0d1h ; команда управления линией A20

out 64h,al ; порт состояния клавиатуры

mov al,0dfh ; открыть A20

out 60h,al ; адрес клавиатурног порта

 

mov [real_ss],ss ; запоминаем указатель стека

mov [real_es],es ; для реального режима

 

 

; Загружаем регистр GDTR

lgdt [QWORD gdt_gdt]

; Устанавливаем защищённый режим работы процессора

mov ax,0001h ; бит перехода в защищённый режим

lmsw ax

;--------------------------------------------------------------------------

; Процессор находится в защищенном режиме

;--------------------------------------------------------------------------

; Очищаем внутреннюю очередь команд процессора

; Выполняем команду межсегментного прерхода,

; в качестве селектора указываем селектор текущего

; сегмента кода, в качестве смещения - метку flush

; далее аналог команды "jmp far flush"

db 0ea ; код межсегментного JMP

dw OFFSET flush ; смещение

dw CS_DESCR ; селектор

LABEL flush FAR

 

; ------------------------------------------------------------

; Возвращаемся в реальный режим

; ------------------------------------------------------------

; Выполняем сброс процессора

mov al,0feh ; команда сброса процессора

out 64h,al ; порт состояния клавиатуры

; Ожидаем сброса процессора

wait_reset:

hlt

jmp wait_reset

;--------------------------------------------------------------------------

LABEL shutdown_return FAR

; ------->> В это место мы попадём после сброса процессора,

; теперь мы снова в реальном режиме

; Восстанавливаем указатель стека

mov ss,[real_ss]

mov sp,[real_sp]

; ------------------------------------------------------------

; закрываем адресную линию A20

; ------------------------------------------------------------

mov al,0d1h ; команда управления линией A20

out 64h,al ; порт состояния клавиатуры

mov al,0ddh ; закрыть A20

out 60h,al ; адрес клавиатурног порта

; Разрешаем все прерывания

mov ax,000dh ; разрешаем немаскируемые прерывания

out 70h,al ; порт для доступа к CMOS-памяти

; разрешаем маскируемые прерывания

in al,21h ; порт для маскирования прерываний

and al,0 ; сбрасываются все биты

out 21h,al ; порт для маскирования прерываний

sti


Stay-at-home