Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
24
Добавлен:
20.06.2014
Размер:
1.08 Mб
Скачать

Порядок работы процессора в защищенном режиме

Глобальная (GDT) и локальная (LDT) таблицы дескрипторов

При работе в защищенном режиме все обращения к памяти происходят через глобальную таблицу дескрипторов (Global Descriptor Table, GDT) или (опционально) через локальную таблицу дескрипторов (Local Descriptor Table, LDT).

Глобальная и локальная таблицы дескрипторов содержат структуры, называемые дескрипторами сегментов. Дескриптор IA-32 имеет размер в восемь байт. Он содержит базовый (начальный) адрес сегмента, его тип, дополнительные свойства (разрядность адресов и операндов, единицу измерения величины сегмента, лимит), права доступа, информацию об использовании сегмента. Каждый дескриптор имеет связанный с ним селектор. Размер селектора — 16 бит. Он содержит индекс (номер) дескриптора в таблице, флаг, определяющий, где находится дескриптор, в локальной или глобальной таблице, а также права доступа. Линейный базовый адрес глобальной таблицы дескрипторов и ее размер содержатся в регистре глобальной таблицы дескрипторов (Global Descriptor Table Register, GDTR), локальной таблицы дескрипторов — в регистре локальной таблицы дескрипторов (Local Descriptor Table Register, LDTR). GDT может быть только одна, обычно в ней находятся описания сегментов операционной системы. LDT может быть любое количество: ни одной, одна на множество задач или по одной на каждую задачу. Они содержат описания сегментов программ, работающих под управлением операционной системы, т.е. отдельных задач. В каждый момент времени процессор может использовать только одну таблицу LDT.

Размер GDT, уменьшенный на единицу, называется пределом таблицы GDT (GDT limit). Он используется для проверки правильности задаваемых программой селекторов. Поле индекса селектора должно содержать ссылки только на существующие элементы таблицы GDT, в противном случае произойдет прерывание. Зная размер GDT, процессор блокирует использование селекторов со значениями поля индекса, выходящими за рамки разрешенных для таблицы GDT. Аналогичный механизм используется и для проверки селекторов, ссылающихся на LDT.

Для доступа к байту внутри сегмента необходимы селектор сегмента и смещение данного байта внутри сегмента. Процессор по значению селектора определяет соответствующий дескриптор, из которого берет базу сегмента — линейный начальный адрес сегмента (адрес первого байта сегмента), прибавляет к нему смещение искомого байта и получает его линейный адрес, который в случае использования только сегментирования (отключенной страничной адресации) является и физическим. Этот механизм используется для доступа к любому действительному сегменту кода, данных или стека при условии, что сегмент доступен из текущего уровня привилегий (current privilege level, CPL), с которым работает процессор. CPL определяется как уровень привилегий текущего исполняемого сегмента кода.

Обработка прерываний. Таблица дескрипторов прерываний (IDT)

Внешние прерывания, программные прерывания, исключения обрабатываются с использованием таблицы дескрипторов прерываний (Interrupt Descriptor Table, IDT). Исключение — это событие, которое происходит, если команда вызывает ошибку. Например, попытка деления на ноль генерирует исключение. Однако есть исключения, например, контрольные точки, которые происходят при других условиях. IDT содержит множество дескрипторов различных шлюзов: прерываний, ловушек и задач — которые предоставляют доступ к обработчикам прерываний и исключений. Так же как и GDT, IDT не является сегментом. Линейный базовый адрес и лимит IDT содержатся в регистре таблицы дескрипторов прерываний (Interrupt Descriptor Table Register).

Для вызова обработчика процессор должен вначале получить номер прерывания от внутренней логики, внешнего контроллера прерываний или программы посредством команд INT, INTO, INT 3 или BOUND.

Номер прерывания представляет собой индекс соответствующего дескриптора в IDT. Если это дескриптор шлюза задачи, то доступ к обработчику осуществляется через переключение задач. Если это дескриптор шлюза прерывания или ловушки, то вызов обработчика аналогичен вызову подпрограммы. Процессор читает из шлюза прерывания селектор сегмента кода, в котором находится обработчик прерывания и смещение обработчика прерывания от начала этого сегмента. По селектору он находит дескриптор, из которого извлекает базу сегмента и, таким образом, определяет полный логический адрес обработчика.

Повышение надежности функционирования системы в защищенном режиме

Функционирование системы в защищенном режиме значительно повышает ее надежность.

Во-первых, повышение надежности обусловлено возможностью задания необходимого размера сегмента и контролем адресации памяти вне пределов сегментов.

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

Процессор при обращении к памяти в защищенном режиме проверяет соблюдение всех необходимых условий: возможность доступа к сегменту по уровню привилегий, не превысил ли адрес предел сегмента, можно ли вообще обращаться к данному сегменту в данной ситуации. И если процессор обнаруживает нарушение какого-либо условия, то генерирует исключение и тем самым обеспечивает защиту (режим называется защищенным) и, следовательно, повышение надежности.

Переключение процессора между реальным и защищенным режимами

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

  • подготовить глобальную таблицу дескрипторов;

  • подготовить при необходимости другие системные структуры данных, например таблицу дескрипторов прерываний;

  • включить адресную линию А20;

  • загрузить регистр глобальной таблицы дескрипторов и при необходимости другие системные регистры, например регистр таблицы дескрипторов прерываний;

  • запретить маскируемые прерывания;

  • переключиться в защищенный режим установкой бита 0 в CR0;

  • осуществить переход на первую команду защищенного режима, загрузив CS селектором соответствующего сегмента кода, IP нужным смещением;

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

  • разрешить при необходимости прерывания.

Для возврата из защищенного режима в реальный необходимо:

  • запретить маскируемые прерывания;

  • осуществить переход в точку возврата, загрузив в CS селектор сегмента кода реального режима, а в IP смещение точки возврата в соответствующем сегменте;

  • переключиться в реальный режим сбросом бита 0 в CR0;

  • загрузить CS базой сегмента кода реального режима;

  • выполнить необходимую инициализацию;

  • разрешить прерывания.

Примеры программ

Программа "Hello from PM"

В данном примере происходит переключение процессора в защищенный режим, вывод сообщения "Hello from PM" в защищенном режиме и возврат в реальный режим.

Запускать программу необходимо в MS-DOS или подобной операционной системе. Поскольку программа загружается операционной системой, заполнение полей базы сегментов в дескрипторах необходимо осуществить уже в процессе работы программы в реальном режиме перед переключением в защищенный режим. Поля лимита сегментов для простоты не рассчитываются, а устанавливаются в максимальное значение.

;PM1Hello.asm

;пpогpамма выводит сообщение "Hello from PM" в защищенном pежиме

;tasm /m PM1Hello.asm

;tlink /3 PM1Hello.obj

.386p ;чтобы можно было использовать системные команды IA-32

;сегмент стека

SSeg segment stack use16

db 100h dup(?)

SSeg ends

;сегмент кода, котоpый начинает выполняться после запуска пpогpаммы в pеальном pежиме

CSeg16 segment use16

assume CS:CSeg16, DS:CSeg32, SS:SSeg

;точка входа в программу, инициализация DS

start: push CSeg32

pop ds

;включается адресная линия A20

in al, 92h

or al, 2

out 92h, al

;рассчитываются и заполняются поля базы дескрипторов сегментов

xor eax, eax

mov ax, cs

shl eax, 4

mov word ptr CS16Dsc+2, ax

shr eax, 16

mov byte ptr CS16Dsc+4, al

mov ax, CSeg32

shl eax, 4

push eax

mov word ptr CS32Dsc+2, ax

mov word ptr DS32Dsc+2, ax

shr eax, 16

mov byte ptr CS32Dsc+4, al

mov byte ptr DS32Dsc+4, al

;рассчитывается линейный адрес начала GDT (база GDT),

;заполняется соответствующее поле переменной gdtr

pop eax

add eax,offset GDT

mov dword ptr gdtr+2, eax

;загружается регистр GDTR значением одноименной переменной

lgdt fword ptr gdtr

;запрещаются маскируемые прерывания

cli

;устанавливается бит PE - процессор с этого момента в защищенном режиме

mov eax, cr0

or al, 1

mov cr0, eax

;JMP в код защищенного режима

db 66h

db 0EAh

dd offset PMentry

dw CS32Sel

;точка возврата из кода защищенного режима, сбрасывается бит PE,

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

RMret: mov eax, cr0

and al, 0FEh

mov cr0, eax

db 0EAh

dw $+4

dw CSeg16

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

sti

mov ah, 0

int 16h

;завершение работы программы

mov ah, 4Ch

int 21h

CSeg16 ends

;сегмент кода защищенного режима

CSeg32 segment use32

assume cs:CSeg32

;сообщение, выводимое в защищенном режиме

msg db 'H',7,'e',7,'l',7,'l',7,'o',7,' ',7,'f'

db 7,'r',7,'o',7,'m',7,' ',7,'P',7,'M',7

msg_l = $-msg ;длина сообщения

rest_scr = (80*25*2-msg_l)/4 ;остаток экрана

;Глобальная таблица дескрипторов

GDT label byte

db 8 dup(0) ;дескриптор 0

CS16Dsc db 0FFh,0FFh,0,0,0,10011010b,0,0 ;дескриптор 1

CS32Dsc db 0FFh,0FFh,0,0,0,10011010b,11001111b,0 ;дескриптор 2

DS32Dsc db 0FFh,0FFh,0,0,0,10010010b,11001111b,0 ;дескриптор 3

VSegDsc db 0FFh,0FFh,0,80h,0Bh,10010010b,11001111b,0 ;дескриптор 4 (Video)

GDT_l = $-GDT ;длина GDT

;переменная, значение которой загружается в GDTR

gdtr dw GDT_l-1 ;лимит GDT

dd ? ;база GDT

CS16Sel equ 0000000000001000b ;селектор дескриптора 1

CS32Sel equ 0000000000010000b ;селектор дескриптора 2

DS32Sel equ 0000000000011000b ;селектор дескриптора 3

VSegSel equ 0000000000100000b ;селектор дескриптора 4

;точка входа в код защищенного режима

PMentry:

;инициализация сегментных регистров

mov ax, DS32Sel

mov ds, ax

mov ax, VSegSel

mov es, ax

;инициализация указателя на сообщение

mov esi, offset msg

;инициализация указателя на начало видеопамяти

xor edi, edi

;инициализация счетчика длиной сообщения

mov ecx, msg_l

;вывод сообщения

rep movsb

;заполнение оставшейся части экрана пробелами

mov eax, 07200720h

mov ecx, rest_scr

rep stosd

;JMP в код реального режима

db 0EAh

dd offset RMret

dw CS16Sel

CSeg32 ends

end start

Соседние файлы в папке Задания к лабораторным