Главная ]
2.1.Подготовка к переключению в защищённый режим
Программирование
Базы данных



Перед тем, как переключить процессор в защищённый режим, надо выполнить некоторые подготовительные действия, а именно:

  1. Подготовить в оперативной памяти глобальную таблицу дескрипторов GDT. В этой таблице должны быть созданы дескрипторы для всех сегментов, которые будут нужны программе сразу после того, как она переключится в защищённый режим. Впоследствии, находясь в защищённом режиме, программа может модифицировать GDT (если, разумеется, она работает в нулевом кольце защиты). Программа может модифицировать имеющиеся дескрипторы или добавить новые, загрузив заново регистр GDTR.

  2. Для обеспечения возможности возврата из защищённого режима в реальный необходимо записать адрес возврата в реальный режим в область данных BIOS по адресу 0040h:0067h, а также записать в CMOS-память в ячейку 0Fh код 5. Этот код обеспечит после выполнения сброса процессора передачу управления по адресу, подготовленному нами в области данных BIOS по адресу 0040h:0067h.

  3. Запретить все маскируемые и немаскируемые прерывания.

  4. Открыть адресную линию A20.

  5. Запомнить в оперативной памяти содержимое сегментных регистров, которые необходимо сохранить для возврата в реальный режим, в частности, указатель стека реального режима.

  6. Загрузить регистр GDTR.

Первый шаг, связанный с подготовкой GDT, мы уже описали, когда рассказывали о преобразовании адресов в защищённом режиме.

Что же касается возврата из защищённого режима в реальный, то он выполняется сбросом процессора, инициированного выводом определённого байта в процессор клавиатуры 8042. Это связано с тем, что разработчики процессора i80286 не предусмотрели никакой команды для переключения процессора из защищённого режима в реальный. Есть ещё один способ возврата в реальный режим, основанный на переводе процессора в состояние отключения, он будет описан в главе, посвящённой обработке прерываний в защищённом режиме.

После выполнения сброса (или после отключения) процессор переходит в реальный режим и управление передаётся в BIOS. BIOS анализирует содержимое ячейки CMOS-памяти с адресом 0Fh - байта состояния отключения. Дальнейшие действия определяются содержимым этой ячейки.

Байт состояния отключения 0Fh используется BIOS для определения способа возврата из защищённого режима в реальный после аппаратного сброса. В таблице 3 перечислены возможные значения для байта состояния отключения.

 

Таблица 3. Значения байта состояния отключения.
Значение Причина отключения
0 Программный сброс при нажатии комбинации клавиш CTRL-ALT-DEL или неожиданный сброс. Выполняется обычный перезапуск системы, но процедуры тестирования при включении питания не выполняются.
1 Сброс после определения объёма памяти.
2 Сброс после тестирования памяти.
3 Сброс после обнаружения ошибки в памяти (контроль чётности).
4 Сброс с запросом перезагрузки.
5 После сброса перезапускается контроллер прерываний, затем управление передаётся по адресу, который находится в области данных BIOS 0040h:0067h.
6,7,8 Сброс после выполнения теста работы процессора в защищённом режиме.
9 Сброс после выполнения пересылки блока памяти из основной памяти в расширенную.
0Ah После сброса управление немедленно передаётся по адресу, взятому из области данных BIOS 0040h:0067h.


Для обеспечения возврата в реальный режим после сброса по адресу, записанному в области данных BIOS 0040h:0067h можно использовать байты 5 и 0Ah.

Из за особенностей обработки прерываний в защищённом режиме, которые мы рассмотрим в третьей главе, перед переключением в защищённый режим необходимо перепрограммировать контроллер прерываний. Восстановить состояние контроллера после возврата в реальный режим можно автоматически, если использовать значение 5 для байта состояния отключения.

Если же вы не используете прерывания и, соответственно, не перепрограммируете контроллер прерываний, можно использовать значение 0Ah, при этом после сброса управление будет сразу передано по адресу, взятому из области данных BIOS 0040h:0067h. В этом случае затраченное на возврат в реальный режим время будет меньше.

В следующем фрагменте программы мы записываем в ячейку CMOS-памяти с адресом 0Fh значение 5.

Напомним, что для записи числа в ячейку CMOS-памяти необходимо вначале в порт с адресом 70h записать номер нужной ячейки, а затем в порт 71h - записываемые данные.

Не удивляйтесь, что в этом фрагменте программы вместо ячейки 0Fh указано значение 8Fh - это не ошибка. Напомним, что единственный способ замаскировать немаскируемые прерывания в компьютере IBM AT - это записать в порт 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]

Всё! Можно переключаться в защищённый режим!

 

Перед тем, как переключить процессор в защищённый режим, надо выполнить некоторые подготовительные действия, а именно:

  1. Подготовить в оперативной памяти глобальную таблицу дескрипторов GDT. В этой таблице должны быть созданы дескрипторы для всех сегментов, которые будут нужны программе сразу после того, как она переключится в защищённый режим. Впоследствии, находясь в защищённом режиме, программа может модифицировать GDT (если, разумеется, она работает в нулевом кольце защиты). Программа может модифицировать имеющиеся дескрипторы или добавить новые, загрузив заново регистр GDTR.

  2. Для обеспечения возможности возврата из защищённого режима в реальный необходимо записать адрес возврата в реальный режим в область данных BIOS по адресу 0040h:0067h, а также записать в CMOS-память в ячейку 0Fh код 5. Этот код обеспечит после выполнения сброса процессора передачу управления по адресу, подготовленному нами в области данных BIOS по адресу 0040h:0067h.

  3. Запретить все маскируемые и немаскируемые прерывания.

  4. Открыть адресную линию A20.

  5. Запомнить в оперативной памяти содержимое сегментных регистров, которые необходимо сохранить для возврата в реальный режим, в частности, указатель стека реального режима.

  6. Загрузить регистр GDTR.

Первый шаг, связанный с подготовкой GDT, мы уже описали, когда рассказывали о преобразовании адресов в защищённом режиме.

Что же касается возврата из защищённого режима в реальный, то он выполняется сбросом процессора, инициированного выводом определённого байта в процессор клавиатуры 8042. Это связано с тем, что разработчики процессора i80286 не предусмотрели никакой команды для переключения процессора из защищённого режима в реальный. Есть ещё один способ возврата в реальный режим, основанный на переводе процессора в состояние отключения, он будет описан в главе, посвящённой обработке прерываний в защищённом режиме.

После выполнения сброса (или после отключения) процессор переходит в реальный режим и управление передаётся в BIOS. BIOS анализирует содержимое ячейки CMOS-памяти с адресом 0Fh - байта состояния отключения. Дальнейшие действия определяются содержимым этой ячейки.

Байт состояния отключения 0Fh используется BIOS для определения способа возврата из защищённого режима в реальный после аппаратного сброса. В таблице 3 перечислены возможные значения для байта состояния отключения.

Таблица 3. Значения байта состояния отключения.
Значение Причина отключения
0

Программный сброс при нажатии комбинации клавиш CTRL-ALT-DEL или неожиданный сброс. Выполняется обычный перезапуск системы, но процедуры тестирования при включении питания не выполняются.

1 Сброс после определения объёма памяти.
2 Сброс после тестирования памяти.
3 Сброс после обнаружения ошибки в памяти (контроль чётности).
4 Сброс с запросом перезагрузки.
5 После сброса перезапускается контроллер прерываний, затем управление передаётся по адресу, который находится в области данных BIOS 0040h:0067h.
6,7,8 Сброс после выполнения теста работы процессора в защищённом режиме.
9 Сброс после выполнения пересылки блока памяти из основной памяти в расширенную.
0Ah После сброса управление немедленно передаётся по адресу, взятому из области данных BIOS 0040h:0067h.


Для обеспечения возврата в реальный режим после сброса по адресу, записанному в области данных BIOS 0040h:0067h можно использовать байты 5 и 0Ah.

Из за особенностей обработки прерываний в защищённом режиме, которые мы рассмотрим в третьей главе, перед переключением в защищённый режим необходимо перепрограммировать контроллер прерываний. Восстановить состояние контроллера после возврата в реальный режим можно автоматически, если использовать значение 5 для байта состояния отключения.

Если же вы не используете прерывания и, соответственно, не перепрограммируете контроллер прерываний, можно использовать значение 0Ah, при этом после сброса управление будет сразу передано по адресу, взятому из области данных BIOS 0040h:0067h. В этом случае затраченное на возврат в реальный режим время будет меньше.

В следующем фрагменте программы мы записываем в ячейку CMOS-памяти с адресом 0Fh значение 5.

Напомним, что для записи числа в ячейку CMOS-памяти необходимо вначале в порт с адресом 70h записать номер нужной ячейки, а затем в порт 71h - записываемые данные.

Не удивляйтесь, что в этом фрагменте программы вместо ячейки 0Fh указано значение 8Fh - это не ошибка. Напомним, что единственный способ замаскировать немаскируемые прерывания в компьютере IBM AT - это записать в порт 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]

Всё! Можно переключаться в защищённый режим!

 

<< Назад ] Содержание ] Далее >> ]

Дизайн: Piton Alien
Rambler's Top100 Рейтинг@Mail.ru
Сайт создан в системе uCoz