Подготовка к переключению в защищённый режим
Перед тем, как переключить процессор в защищённый режим, надо выполнить некоторые подготовительные действия, а именно:
- Подготовить в оперативной памяти глобальную таблицу дескрипторов GDT. В этой таблице должны быть созданы дескрипторы для всех сегментов, которые будут нужны программе сразу после того, как она переключится в защищённый режим. Впоследствии, находясь в защищённом режиме, программа может модифицировать GDT (если, разумеется, она работает в нулевом кольце защиты). Программа может модифицировать имеющиеся дескрипторы или добавить новые, загрузив заново регистр GDTR.
- Для обеспечения возможности возврата из защищённого режима в реальный необходимо записать адрес возврата в реальный режим в область данных BIOS по адресу 0040h:0067h, а также записать в CMOS-память в ячейку 0Fh код 5. Этот код обеспечит после выполнения сброса процессора передачу управления по адресу, подготовленному нами в области данных BIOS по адресу 0040h:0067h.
- Запретить все маскируемые и немаскируемые прерывания.
- Открыть адресную линию A20.
- Запомнить в оперативной памяти содержимое сегментных регистров, которые необходимо сохранить для возврата в реальный режим, в частности, указатель стека реального режима.
- Загрузить регистр GDTR.
Первый шаг, связанный с подготовкой GDT, мы уже описали, когда рассказывали о преобразовании адресов в защищённом режиме.
Что же касается возврата из защищённого режима в реальный, то он выполняется сбросом процессора, инициированного выводом определённого байта в процессор клавиатуры 8042. Это связано с тем, что разработчики процессора i80286 не предусмотрели никакой команды для переключения процессора из защищённого режима в реальный. Есть ещё один способ возврата в реальный режим, основанный на переводе процессора в состояние отключения, он будет описан в главе, посвящённой обработке прерываний в защищённом режиме.
После выполнения сброса (или после отключения) процессор переходит в реальный режим и управление передаётся в BIOS. BIOS анализирует содержимое ячейки CMOS-памяти с адресом 0Fh - байта состояния отключения.
Дальнейшие действия определяются содержимым этой ячейки.
Байт состояния отключения 0Fh используется BIOS для определения способа возврата из защищённого режима в реальный после аппаратного сброса. В таблице 3 перечислены возможные значения для байта состояния отключения.
Таблица 3. Значения байта состояния отключения.
Значение | Причина отключения |
0 | Программный сброс при нажатии комбинации клавиш CTRL-ALT-DEL или неожиданный сброс. Выполняется обычный перезапуск системы, но процедуры тестирования при включении питания не выполняются. |
|
|
|
|
|
|
|
|
|
|
6,7,8 | Сброс после выполнения теста работы процессора в защищённом режиме. |
9 | Сброс после выполнения пересылки блока памяти из основной памяти в расширенную. |
0Ah | После сброса управление немедленно передаётся по адресу, взятому из области данных BIOS 0040h:0067h. |
Напомним, что единственный способ замаскировать немаскируемые прерывания в компьютере IBMAT - это записать в порт 70h байт, в котором старший бит установлен в 1. Поэтому наш фрагмент программы не только записывает байт состояния отключения, но и маскирует немаскируемые прерывания (!). Нам необходимо также замаскировать обычные прерывания, поэтому мы выдаём команду CLI. cli mov al,8f out CMOS_PORT,al jmp next1 ; небольшая задержка next1: mov al,5 out CMOS_PORT+1,al Следующий шаг - открытие адресной линии A20 - необходим в том случае, если ваша программа будет обращаться к оперативной памяти, лежащей за пределами первого мегабайта. Приведём процедуру, которую можно использовать для этой цели: ; ------------------------------------------------------------ ; Процедура открывает адресную линию A20 ; ------------------------------------------------------------ PROC enable_a20 NEAR mov al,A20_PORT out STATUS_PORT,al mov al,A20_ON out KBD_PORT_A,al ret ENDP enable_a20 Эта магическая последовательность команд выдаёт команду A20_ON клавиатурному процессору 8042, к которому подключены схемы управления адресной линией A20. После начального сброса линия A20 закрыта, и расширенная память за границами первого мегабайта недоступна. Следующий этап - запоминание содержимого сегментных регистров, которые будут нужны при возврате в реальный режим. Это сегментные регистры SS и ES: mov [real_ss],ss ; запоминаем указатель стека mov [real_es],es ; для реального режима На последнем перед переключением в защищённый режим этапе мы загружаем регистр GDTR адресом подготовленной заранее GDT: lgdt [QWORD gdt_gdt] Всё! Можно переключаться в защищённый режим!