11/07/94 02:55pm
zr_prej.lek
А.В.Фролов, Г.В.Фролов "Защищенный
режим процессоров Intel 80286/80386/80486.
Практическое руководство по
использованию защищенного
режима" БСП том 6 М
"Диалог-МИФИ" 1993
--"i486tm микропроцессор" в 2-х
книгах Библиотека программиста
"И.В.К.-СОФТ" М 1993
Переключение режимов работы процессора.
ПРИМЕЧАНИЕ:
Изложенный материал (примеры) можно
применить только на компьютерах,
совместимых с IBM AT. Должна
использоваться ОС MS DOS с
неактивными драйверами "верхней
памяти" (QEMM, EMM386).
Описание выполнено для процессора
i80286.
Переключение в защищенный режим:
Необходимо подготовить глобальную таблицу дескрипторов GDT. Она должна содержать описание всех используемых областей, в том числе иметь ссылку на себя. В этом случае ее можно будет изменять, программами с наивысшим уровнем привилегий (0).
Необходимо
подготовить возможность
возврата в реальный режим.
Механизм возврата в процессоре
i286 отличается от механизма в
i386+, но совместимость
поддерживается.
Возврат осуществляется
выполнением аппаратного
сброса процессора.
При поступлении сигнала
начальной установки
начинается выполнение
программы начальной
инициализации, расположенной в
BIOS. Эта программа обращается к
энергонезависимой памяти и
читает байт, определяющий
особенности выполнения
загрузки (адрес этого байта в
CMOS-памяти 0Fh, а интересующее нас
значение 0Ah или 05h). Если
прочитанное значение 0Ah, то
никаких специальных действий
не выполняется, а просто
передается управление по
адресу, взятому из ячейки BIOS
0040:0067h. Если указано 05h, то перед
пердачей управления будет
произведена инициализация
контроллера прерываний (это
необходимо, если в защищенном
режиме использовалась работа с
прерываниями и настройка
контроллера была изменена).
3 Далее необходимо запретить маскируемые и немаскируемые прерывания. Запрет маскируемых прерываний выполняется соответствующей коммандой процессора. Немаскируемые прерывания блоккируются внешними схемами.
Разрешается работа старших линий адреса - линии A20. Управление этой линией в компьютере AT осуществляет процессор клавиатуры.
Сохраняется необходимая информация (указатель стека).
Загружается указатель на таблицу глобальных дескрипторов в регистр GDTR.
Осуществляется переключение в защищенный режим, установкой младшего бита в регистре слова состояния машины (MSW).
Поскольку выполнение команд зависит от установленного режима, необходимоочистить очередь команд. Это осуществляется командой JMP непосредственно после LMSW. Значение сегментных регистров после входа в защишенный режим сохраняется. Выполнение программы начинается при CPL=0.
Возврат в реальный режим:
Выполняется сброс процессора.
Восстанавливаются регистры реального режима.
Уже находясь в реальном режиме необходимо закрыть линию A20.
Затем
разрешаются маскируемые и
немаскируемые прерывания.
Для полного демаскирования
прерываний следует сбросить
маску в контроллере
прерываний.
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