Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org

Protected Mode

Содержание


Node:Top, Next:, Up:(dir)

Содержание

Этот документ возник в результате DJGPP e-mail-подписки "protected mode". Документ включает детальную информацию о защищенном режиме.


Node:Introduction, Next:, Previous:Top, Up:Top

1 Введение в защищенный режим

  • Quick look: Краткий обзор
  • Advantages: Преимущества использования Protected Mode


Node:Quick look, Next:, Up:Introduction

1.1 Краткий обзор Protected Mode

Что такое Защищенный Режим?

80386+ обеспечивает такие фичи , как защита памяти , виртуальная память , многозадачность , совместимость с предыдущими версиями процессоров .

8086 работает только в одном режиме - реальном. При разработке 286 инженеры интел хотели убить 2 зайцев - обеспечить совместимость с 8086 и придать ему новые преимущества. Поэтому 286 поддерживает 2 режима - реальный и защищенный. Программы , разработанные для 8086 , не могут работать в защищенном режиме.

386 имеет все преимущества 8086 и 286 и новые качества. Режим по умолчанию остается прежним - реальный. Защищенный режим 386 имеет отличия. Он лучше защищен , чем в 286. Он также поддерживает 3-й режим - Virtual 8086 (V86) mode. В V86 mode программы , выполняемые в защищенном режиме , могут симулировать реальный режим. Это позволяет например досовским программам работать в защищенном режиме в обычном порядке .


Node:Advantages, Previous:Quick look, Up:Introduction

1.2 Преимущества использования Protected Mode

Доступ к 4 гигам памяти - Это наиболее существенная разница между защищенным и реальным режимом.

Виртуальная память - Специальный модуль - Memory Management Unit (MMU) на 386 реализует механизм виртуальной памяти.

Трансляция адресов - Блок MMU транслирует реальные физические адреса. Например , вам нужно скопировать адреса в видео-памяти начиная с сегмента 800H (CGA) в буффер данных вашей программы,а потом скопировать их обратно.

Программы работают с логическими адресами. 386 конвертирует их в 32-битные линейные (не-сегментная адресация). Затем MMU конвертирует эти линейные адреса в физические. Если рассматривать реальный режим , то например : адрес B800:0010 - это логический адрес , тогда линейный адрес - это B8010H , в реальном режиме он же есть и физический , поскольку здесь MMU не работает.

Улучшенная сегментация - В реальном режиме все сегменты - 64-килобитные и порядок расположения у них фиксированный. В защищенном режиме сегмент может состоять из одного байта , а может быть быть и на 4 гига. Сегменты могут начинаться с произвольного адреса. Программист обязан здесь указывать назначение каждого сегмента. Если программа попытается записать данные в сегмент кода , будет сгенерирована ошибка.

Защита памяти - В 386 память защищена.Например , пользовательский процесс не в состоянии что-либо записать в память , которую использует сама операционная система.

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

32-битные регистры - Основные регистры в 386 теперь 32-битные.К имени регистра добавляется префикс Е. Добавлены 2 новых сегментных регистра - FS и GS. Программы реального режима могут также использовать 32-битные регистры , но не могут использовать их для индексации. Использование 32-битных регистров само по себе делает код более компактным, оптимизируя его по размеру.

Режимы адресации - В реальном режиме адреса можно формировать с помощью 4-х регистров -BX,BP,SI,DI. В защищенном режиме любой регистр может быть адресом. Индекс может быть смасштабирован как 2.4 или 8-кратный. Что позволяет писать что-то типа :
MOV EBX,[EDI][EAX*8]+2.

Многозадачность - 386 может делать одномоментный слепок состояния своих регистров и переключиться на другую задачу - context switch. И делает его всего одна инструкция.

Hardware debugging - 386 может реализовать пошаговый break-point кода и данных.


Node:RM Addressing, Next:, Previous:Introduction, Up:Top

2 Адресация в Real Mode

В 8086 память организована побайтно. Если число бит не кратно 8 и равно например 2 байтам , то информация будет храниться так : младший байт будет сохранен в младшем по адресу байте памяти. Т.е. например слово B800H : сначала 00H , потом B8H.

Интеловские процессоры используют сегментированную модель памяти. Сегмент - кусок памяти. Сегментов может быть много. В реальном режиме каждый сегмент по размеру равен 64 кб , и всего их может быть 65536 штук. Адрес каждого сегмента тут кратен 16 байтам , поэтому общее количество памяти не может быть более меетра - 65536 * 16 = 1048576 = 1MB. И 8086 и 8088 имею всего 1MB адресов. 286, 386+ могут иметь больше , но 286 не ко всем имеет прямой доступ.

Сегменты пронумерованы - от 0000H до FFFFH. Поскольку размер сегмента фиксирован , нам достаточно знать смещение - offset - для определения адресного байта. В 8086 полный адрес состоит из сегмента и смещения.

Если например сегмент 0040H и смещение 0102H, мы пишем 0040:0102. Поскольку сегмент кратен 16 байтам (10H) , адрес 0000:0010 идентичен 0001:0000. Сегментный адрес хранится в перервернутом виде - например , 0040:1234 :
34 12 40 00
Для конвертации сегментного адреса в линейный нужно умножить значение сегмента на 16 (10H) и добавить смещение :
 0040 * 10 + 0000 = 00400
 0000 *  0 + 0400 = 00400
 0020 * 10 + 0200 = 00400
 
В данном случае мы имеем дело с одним и тем же адресом.


Node:80386 Registers, Next:, Previous:RM Addressing, Up:Top

3 Регистры в 80386

386 имеет 4 основных регистра , флаговый , 6 сегментных , 2 индексных , 2 стековых , базовый , указатель на текущую команду. Также имеются :

GDTR (Global Descriptor Table Register)
 IDTR (Interrupt Descriptor Table Register)
 LDTR (Local Descriptor Table Register)
 TR (Task Register)
 CR0-CR3 (Control Registers)
 DR0-DR7 (Debug Registers)
 

Следующая картинка показывает их отличия .


 


Node:RM Vector Table, Next:, Previous:80386 Registers, Up:Top

4 Real Mode Vector Table

8086 имеет 256 прерываний. Их адреса расположены в памяти начиная с адреса 0000:0000 в специальной таблице прерываний. Каждый адрес в этой таблице имеет длину 4 байта , куда умещается сегмент+смещение. На таблицу прерываний отведено 1024 байта - 1 килобайт. Если процессор получает например 2-е прерывание (INT 2), происходит следующее:записывается специальный флаг , регистры CS и IP пишутся в стек , берется адрес в ячейке 0000:0008 и выполняется процедура прерывания ISR по этому адресу , после чего оттуда происходит возврат в результате команды IRET.


Node:Hardware Interrupts, Next:, Previous:RM Vector Table, Up:Top

5 Hardware Interrupts

hardware interrupt - специальный сигнал от I/O-устройства процессору. Процессор немедленно останавливается и начинает обрабатывать прерывание. После обработки команды возобновляются.

Такие прерывания могут прийти от различных устройств. Например , отклавиатуры , часов , принтера , портов , диска и т.д. Некоторые прерывания может генерировать сам процессор. Например INT 0 возникает при делении на ноль.

Программируемый контролер - 8259 Programmable Interrupt Controller (PIC) обслуживает все hardware interruptrs.

Таблица ниже показывает hardware interrupts для реального режима и соответствующие генерируемые PIC interrupt request inputs (IRQ). Стандартные номера IRQ не совпадают с номерами прерываний. Их можно вообще по-своему перепрограммировать .

PIC также контролирует приоритет прерываний. Например , часы (IRQ 0) имеют наивысший приоритет, чем клавиатура (IRQ 1). Схема приоритетов может быть перепрограммирована.

Interrupt IRQ Number Description
00H - Divide by zero or divide overflow
02H - NMI (Non-maskable Interrupt)
04H - Overflow (generated by INTO)
08H 0 System timer
09H 1 Keyboard
0AH 2 Interrupt from second PIC
0BH 3 COM2
0CH 4 COM1
0DH 5 LPT2
0EH 6 Floppy Disk
0FH 7 LPT1
70H 8 Real Time Clock
71H 9 General I/O
72H 10 General I/O
73H 11 General I/O
74H 12 General I/O
75H 13 Coprocessor
76H 14 Hard Disk
77H 15 General I/O

Прерывания можно запретить с помощтю команды CLI


Node:Keyboard, Next:, Previous:Hardware Interrupts, Up:Top

6 Клавиатура и A20

Исторически так повелось , что AT-шные материнские платы реализовали шину A20 через контроллер клавиатуры . Контроллер блокирует эту шину. Разблокировать или заблокировать ее можно специальной командой. Доступ к расширенной памяти доступен через гейт A20 независимо от того , в реальном мы режиме или защищенном.


Node:Selectors and Descriptors, Next:, Previous:Keyboard, Up:Top

7 Селекторы и дескрипторы


Node:Segment Selectors, Next:, Up:Selectors and Descriptors

7.1 Селекторы

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


 

Селектор включает 3 специальных поля. Нижние 2 бита (RPL) отвечают за механизм защиты. Следующий бит - TI, определяет саму таблицу дескрипторов.

3 сегментных таблицы:

  1. Global Descriptor Table (GDT)
  2. Interrupt Descriptor Table (IDT)
  3. Local Descriptor Table (LDT)

Сегментный селектор может ссылаться либо на GDT , либо на LDT , но не на IDT. Если TI = 0 - это таблица GDT. Если TI = 1 - LDT .


Node:Tables, Next:, Previous:Segment Selectors, Up:Selectors and Descriptors

7.2 Таблицы в Protected Mode

Любая дескрипторная таблица может хранить 8192 дескрипторов. Индексные биты - INDEX - (биты с 15 по 3) в селекторе определяют дескриптор.

Регистры GDTR и IDTR определяют расположение таблиц GDT и IDT. Он состоит из 32-битного адреса и 16-битного ограничения. Т.е. эти 2 регистра 48-битные.

GDT - единая глобальная таблица для всех процессов.

Регистр LDTR определяет расположение LDT. В отличие от GDT, каждая задача имеет свою собственную LDT. В LDTR сегментный сеектор глобальной таблицы , который указывает на LDT.

Таблица прерываний IDT в защищенном режиме аналогична таблице прерываний в реальном режиме. Как правило , она состоит из 256 прерываний.

Следующий рисунок показывает формат дескрипторной таблицы.

 fig4.jpg
 fig5.jpg
 fig6.jpg
 


Node:Descriptors, Previous:Tables, Up:Selectors and Descriptors

7.3 Дескрипторы

В сегментном дескрипторе представляют интерес бит P (bit 47) , в случае если он равен нулю , означает создание виртуального сегмента. Если программа попытается его использовать,возникнет ошибка. После этого операционная система загружает сегмент с диска. Если бит Р=0 , биты 0-39 48-63 могут иметь произвольные значения.

Другой интересный бит - A (bit 40). Если он равен 1 , значит в сегмент можно писать.

Для определения размера сегмента используется бит G (bit 55). Если бит G равен нулю , сегмент может иметь размер от одного байта до одного метра. Если бит G равен 1 , сегмент может иметь размер от 4 килобайт до 4 гигабайт.

Можно создать 2 дескриптора , которые указывают на одну и ту же область памяти. Например , можно загрузить данные сегмент и стартовать с него же. Такой процесс называется aliasing.

Первый слот в GDT зарезервирован. Это нулевой селектор.


Node:Protected Mode Privileges, Next:, Previous:Selectors and Descriptors, Up:Top

8 Привилегии защищенного режима

Каждая программа имеет свой уровень привилегии - PL, от 0 до 3. Уровень PL0 позволяет выполнять любой код и иметь доступ к любым данным. Уровень PL3 не может выполнять определенные инструкции и иметь доступ к данным более привилегированных программ. Каждый дескриптор имеет свой Descriptor Privilege Level (DPL).

Иерархия привилегий очень важна в современных операционных системах. В них ядро как правило выполняется с уровнем PL0. Некоторые части операционной системы могут работать с уровнем PL1. Драйвера могут работать в PL2. Пользовательские программы работают в PL3.

Уровень PL0 может выполнить следующие инструкции:
 
 •HLT
 •CLTS
 •LGDT
 •LIDT
 •LLDT
 •LTR
 •LMSW
 •MOV (to/from control/debug/test registers)
 
 На 486 :
 
 •INVD
 •WBINVD
 •INVLPG
 
 На Pentium и выше :
 
 •RDMSR
 •WRMSR
 •RDTSC
 
 

Поле IOPL (2 бита) флагового регистра позволяет операционной системе контролировать I/O. Если IOPL=0 , только PL0 может выполнять I/O. Если IOPL=3 , все программы могут выполнять I/O. Только PL0 может модифицировать IOPL.

Уровень привилегий программы эквивалентен селекторному полю RPL регистра CS. Модифицировать это поле из программы нельзя.

8.1 Доступ к данным

При загрузке сегментов данных (DS, ES, FS or GS) проверяются поля DPL , CPL , RPL.

При загрузке регистра SS поля DPL и CPL должны быть равны.


Node:Multitasking, Next:, Previous:Protected Mode Privileges, Up:Top

9 Многозадачность

На самом деле программы выполняются не одновременно , а последовательно.

Для поддержки многозадачности используется регистр Task State Segments (TSS) . Он указывает на буфер , который должен быть как минимум разамеров 104 байта. Он также может быть использован для прерываний. TSS оперирует с GDT.

В этом буфере хранится содержимое регистров при переключении задач. Процесс записи и чтения содержимого регистров из этого буфера критичен по времени и потому очень быстр.

386 поддерживает т.н. nested tasks. Для их управления используется бит NT флагового регистра. При вызове "calls" селектор TSS вызываемой задачи сохраняется в специальном поле , при этом бит NT=1. При возвращении срабатывает инструкция IRET.

Имеется указатель на область памяти обьемом 8К - I/O bitmap. Каждый бит в нем соответствует порту I/O. Если задача пытается сделать I/O , проверяются CPL и IOPL. Если CPL меньше или равно IOPL , прерывание разрешено. В противном случае происходит проверка бита. Если бит равен нулю,доступ к порту разрешен. bitmap должен оканчиваться на 0FFh.

fig7.jpg
 


Node:Exceptions, Next:, Previous:Multitasking, Up:Top

10 Исключения 80386

386 поддерживает 256 прерываний. Таблица IDT может иметь их 8192. IDT может включать trap gates, interrupt gates , task gates. trap gate срабатывает при возникновении исключения. interrupt gate отключает остальные прерывания.

Прерывания могут быть вызваны со стороны PIC. Прерывания также могут быть сгенерированы процессором.

Процессор генерирует 386 исключений , которые могут быть классифицированы как faults, traps , aborts.

fault - несмертельная исправляемая ошибка.При этом CS:EIP указывает на инструкцию, которая вызвала fault. Большинство faults известны как "General Protection Fault (GPF)".

Trap как правило вызывается софтом. В основном это инструкции INT и INTO.

Abort - серьезная ошибка. Например Double Fault и FPU Overrun - это aborts.

Таблица исключений:

Exception (#num) Type
Divide Error (0) Fault
Debug (1) F/Trap
Breakpoint (3) Trap
Overflow (4) Trap
Bounds Check (5) Fault
Bad Opcode (6) Fault
No Coprocessor (7) Fault
Double Fault (8) Abort
Coprocessor Overrun (9) Abort
Invalid TSS Segment (0A) Fault
Segment not Present (0B) Fault
Stack Fault (0C) Fault
General Protection Fault (0D) Fault
Page Fault (0E) Fault
Coprocessor Error (10) Fault


Node:MMU, Next:, Previous:Exceptions, Up:Top

11 Memory Management Unit (MMU)

386 имеет 2 фичи для управления памятью :

  1. Segmentation
  2. Paging

Paging позволяет реализовать механизм виртуальной памяти , который используется большинством операционных систем.

Для реализации paging, нужно установить бит 31 регистра CR0. Также необходимо проинициализировать Page Directory Entries и Page Table Entries, PDEs и PTEs. PDEs и PTEs - это таблицы для конвертации логических адресов в физические.

Только уровень PL0 может активизировать MMU. Пользовательские программы о существовании MMU не знают.

MMU использует 2 типа таблиц для перевода адресов - Page Directory Entry и Page table Entries. Одна PDE соответствует 4 метрам памяти. PDE включает указатель на начало page table. PTE используется для раздачи пермишинов 4-килобайтным блокам внутри одной 4-метровой PDE. PTEs также включает физический адрес. PDE включает Physical Address самой page tables. Для перевода линейного адреса в физический , MMU берет биты 22-31 у линейного адреса. Биты 12-21 используются для выбора одного из 1024 PTE. Нижние 12 бит формируют младшие биты физического адреса.

Регистр CR3 хранит базовый адрес PDE.Он еще называется PDBR (Page Directory Base Register)

fig8.jpg
 


Node:V86 Mode, Next:, Previous:MMU, Up:Top

12 Virtual 8086 (V86/VM86) Mode

В этом режиме 386 ведет себя также , как и 8086 , с небольшими исключениями. Здесь не выполняются инструкции LGDT, LIDT, LLDT, SLDT, ARPL, LAR, LSL, LTR, VERR, VERW, INVD, WBINVD, WRMSR, RDMSR, и т.д. MMU активен. Задачи выполняются так , как и реальном режиме.

Нужно установить бит VM флагового регистра. Это можно сделать из PL0. Выполнение программ в этом режиме быстрее , чем в реальном.

Задача может иметь доступ к 1 метру памяти. Задача всегда выполняется в PL3. Задача может делать I/O , если IOPL=3.


Node:Interrupt Handling, Next:, Previous:V86 Mode, Up:Top

13 Управление прерываниями в Protected Mode

Управление прерываниями - важная часть любой операционной системы. Без этого с любой системой может произойти чио угодно.

Управление прерываниями , генерируемыми железом , в V86 более комплексное. Фактически это управление в защищенном режиме. Перед вызовом обработчика прерываний сегментные регистры обнуляются. Структура стека VM68 показана ниже :

fig9.jpg
 

Когда происходит General Protection Fault , программа может быть остановлена , или вызвана инструкция типа CLI , STI.


Node:Working in Protected Mode, Next:, Previous:Interrupt Handling, Up:Top

14 Работа в Protected Mode

Для этого сначала нужно переключиться в защищенный режим. Для этого :

  1. Setup the Global Descriptor Table (GDT)
  2. Setup the Interrupt Descriptor Table (IDT)
  3. Reprogram the PICs so that they generate different interrupts
  4. Setup the TSS
  5. Setup Page Tables and CR3 (perhaps you may not require this)
  6. Set bit 0 of CR0
  7. Load the Task Register (TR)
  8. Jump to the TSS selector

Инициализация GDT и IDT проста. Для этого нужно создать таблицу и загрузить регистр GDTR.


Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье