10.6. Страничная адресация

Линейный адрес, который формируется процессором из логического адреса,

соответствует адресу из линейного непрерывного пространства памяти. В обыч­ном режиме в это пространство могут попадать области памяти, куда нежелатель­но разрешать запись, - системные таблицы и процедуры, ПЗУ BIOS и т. д. Чтобы этого избежать, система может позволять программам создавать только неболь­шие сегменты, но тогда теряется привлекательная идея flat-памяти. Сегментация -не единственный вариант организации памяти, который поддерживают процес­соры Intel. Существует второй, совершенно независимый механизм - странич­ная адресация (pagination).

При страничной адресации непрерывное пространство линейных адресов па­мяти разбивается на страницы фиксированного размера (обычно 4 Кб (4096 или 1000h байт), но Pentium Pro может поддерживать и страницы по 4 Мб). При об­ращении к памяти процессор физически обращается не по линейному адресу, а по тому физическому адресу, с которого начинается данная страница. Описание каж­дой страницы из линейного адресного пространства, включающее в себя ее физический адрес и дополнительные атрибуты, хранится в одной из специальных системных таблиц, как и в случае сегментации, но при этом страничная адреса­ция абсолютно невидима для программы.

Страничная адресация включается при установке бита PG регистра CR0, если бит РЕ зафиксирован в 1 (попытка установить PG, оставаясь в реальном режиме, приводит к исключению Кроме того, в регистр CR3 предварительно

надо поместить физический адрес начала каталога страниц - главной из таблиц,

описывающих страничную адресацию. Каталог страниц имеет размер 4096 байт (ровно одна страница) и содержит 10244-байтныхуказателя на таблицы страниц. Каждая таблица страниц тоже имеет размер 4096 байт и содержит указатели до 1024 страниц. Если одна страница описывает 4 Кб, то полностью

заполненная таблица страниц описывает 4 Мб, а полный каталог полностью за­полненных таблиц - 4 Гб, то есть все 32-битное линейное адресное пространство. Когда процессор выполняет обращение к линейному адресу, он сначала исполь­зует его биты как номер таблицы страниц в каталоге, затем биты как номер страницы в выбранной таблице, а затем биты 11-0 как смещение от физи­ческого адреса начала страницы в памяти. Поскольку эта процедура занимает много времени, в процессоре предусмотрен специальный кэш страниц - (бу­фер с ассоциативной выборкой), так что, если к странице обращались не очень

давно, ее физический адрес будет сразу определен.

Элементы каталога страниц и таблиц страниц имеют общий формат: биты 31-12: биты 31-12 физического адреса (таблицы страниц или самой страницы)

биты 11-9: доступны для использования операционной системой

бит 8: G - страница» - страница не удаляется из буфера при

переключении задач или перезагрузке регистра CR3 (только на Pentium

Pro, если установлен бит PGE регистра CR4) бит 7: PS - размер страницы. 1 - для страницы размером 2 или 4 Мб, иначе - О бит 6: D - «грязная страница» - устанавливается в 1 при записи в страницу;

всегда равен нулю для каталога страниц

бит 5: А - бит доступа (устанавливается в 1 при любом обращении к таблице

страниц или отдельной странице) бит - бит запрещения кэширования

бит 3: PWT - бит разрешения сквозной записи бит 2: U - страница/таблица доступна для программ с CPL = 3 бит 1: W - страница/таблица доступна для записи

бит 0: Р - страница/таблица присутствует. Если этот бит - 0, остальные биты

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

Процессоры Pentium Pro (и старше) могут поддерживать расширения стра­ничной адресации. Если установлен бит РАЕ, физический адрес оказывается не

32-битным (до 4 Гб), а 36-битным (до 64 Гб). Если установлен бит PSE регистрастраничная адресация

швшат

CR4, включается поддержка расширенных страниц размером 4 Мб для РАЕ = О и 2 Мб для РАЕ = 1, Такие страницы описываются не в таблицах страниц, а в ос­новном каталоге. Intel рекомендует помещать ядро операционной системы и все, что ему необходимо для работы, на .одну 4-мегабайтную страницу, а для приложе­ний пользоваться 4-килобайтнымистраницами. Расширенные страницыкэширу-ются в отдельном TLB, так что, если определена всего одна расширенная страни­ца, она будет оставаться в TLB все время.

Для расширенных страниц формат элемента каталога совпадает с форматом для обычной страницы (кроме того, что бит PS = І), но в качестве адреса исполь­зуются только биты ЗІ-22 - они соответствуют битам ЗІ-22 физического адреса начала страницы (остальные биты адреса - нули).

Для расширенного физического адреса (РАЕ = 1) изменяется формат регистра CR3 (см. раздел 1G.1.3), размеры всех элементов таблиц становятся равными 8 бай­там (причем используются только биты G-3 байта 4), поэтому их число сокраща­ется до 512 элементов в таблице и вводится новая таблица - таблица указателей на каталоги страниц. Она состоит из четырех элементов, каждый из которых может указывать на отдельный каталог страниц. В этом случае биты 31-3G линейного адреса определяют используемый каталог страниц, биты 29-21 -таблицу, биты 20-12 - страницу, а биты 11-0- смещение от начала страницы в фи­зическом пространстве (следовательно, если биты 29-2І выбрали расширенную

страницу, биты 2G-G соответствуют смещению в ней).

Основная цель страничной адресации - организация виртуальной памяти в ОС. Система может использовать внешние устройства (обычно диск) для расширения

виртуального размера памяти. При этом, если к какой-то странице долгое время нет обращений, система копирует ее на диск и помечает как отсутствующую в таблице страниц. Затем, когда программа обращается по адресу в отсутствую­щей странице, вызывается исключение #РЕ Обработчик исключения читает ад­рес, приведший к ошибке из CR2, определяет, какой странице он соответствует,

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

Кроме того, система может периодически сбрасывать бит доступа и, если он не установится за достаточно долгое время, копировать страницу на диск и объявлять

ее отсутствующей. Если при этом бит D равен нулю, в страницу не выполнялось никаких записей (с того момента, как этот бит последний раз обнулили) и ее во­обще можно не сохранять.

Второе не менее важное применение страничной адресации - безопасная реали­зация flat-модели памяти. Операционная система может разрешить программам обращаться к любому линейному адресу, но отображение линейного пространства

на физическое не будет взаимно однозначным. Скажем, если система использует

первые 4 Кб памяти, физическим адресом нулевой страницы будет не ноль, а 4G96 пользовательская программа даже не узнает, что обращается не к нулевому

Процессоры Intel в защищенном режиме

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

В следующем примере мы построим каталог и таблицу страниц (для первых 4 Мб), отображающие линейное пространство в физическое один в один, затем изменим физический адрес страницы с линейным адресом ОАЮООп и попытаем­ся выполнить обычный цикл закраски экрана в режиме 320x200x256, заполнив видеопамять байтом с номером цвета, но у нас останется участок,

соответствующий перенесенной странице.

pm3.asm

Программа,   демонстрирующая страничную адресацию. Переносит одну из страниц,  составляющих видеопамять,

; Компиляция: ; TASM:

;    tasm /т pm3.asm ;   tlink /х /3 pm3.obj ; MASM:

;   ml /с pm3.asm

;    link pm3.obj,,NUL,,,

; WASM:

;   wasm pm3.asm

;   wlink file pm3.obj form DOS .386p

RMjseg segment para public "CODE" use16

assume cs:RM_seg,ds:PM seg,ss:stack seg

start:

; Подготовить сегментные регистры.

в PM.

и пытается закрасить

push

PM_seg-

 

pop

ds

 

; Проверить,

не находимся

ли мы уже

mov

eax,crO

 

test

,al,1

 

jz

no_V86

 

; Сообщить и

выйти.

 

mov

dx,offset

v86_msg

err_exit:

 

 

push

cs

 

pop

ds

 

mov

ah, 9

 

int

21h

 

mov

ah,4Ch

 

int

21h

 

; Убедиться,

что мы не под

Windows.

no_V86:

 

 

mov

ах,1600h

 

int

2Fh

 

щ

test al.al

jz no.windows

;  Сообщить и выйти.

mov dx,offset winjnsg

jmp short err_exit

; Сообщения об ошибках при старте.

v86_msg db "Процессор в режиме V86 - нельзя

winjnsg db "Программа запущена под Windows ­переключиться в

нельзя перейти в кольцо

в реальном режиме.

• Итак, мы точно находимся nojvindows:

• Очистить экран и переключиться в нужный видеорежим.

mov

int 10h ; Вычислить базы для всех дескрипторов, хог еах,еах mov ax,RM_seg shl еах,4

mov     word ptr

shr еах,16

mov byte ptr mov

shl еах,4

mov word ptr GDTJ2bitCS+2,ax

shr eax,16

mov byte ptr GDT^32bitCS+4,al

; Вычислить линейный адрес GDT.

хог

mov shl posh add mov

; Загрузить GDT

"igdt

;  Открыть А20 -

mov out

; Отключить прерывания СИ

eax,eax ax,PM_seg eax, 4

eax

eax.offset GDT

dword ptr

ptr gdtr

в этом примере al,2 92h,al

мы будем пользоваться памятью выше l Мб.

и ММ1.

1П а1,7(Гп

ог а1,80гь

оиЬ 70й,а1

Перейти в защищенный режим (пока без страничной адресации),

тот еах.сгО

ог а1,1

тоу сгО.еах

Загрузить CS.

db db

dd

dw

66b

OEAh

offset PM_entry SEL_32bitCS

RM return:

Переключиться

mov

and . mov в реальный режим

eax, crO

eax, 7FFFF.FFEh

crO,eax

с отключением страничной адресации.

Сбросить очередь и db.

dw dw

загрузить OEAh S+4

RM_seg

CS.

Загрузить остальные регистры.

mov ax,PM_seg

mov ds.ax

mov es.ax Разрешить MI.

in al,70h

and       al,07FH .

out 70h,al Разрешить другие прерывания.

sti

нажатия клавиши. ah, 1

Подождать

mov

int

Переключиться

mov int

2lh

в текстовый

ax,3

lOh

режим

и завершить программу.

mov int

RM_seg ends

ah,4Ch

21h

PM_seg segment para public  "CODE" use32

assume cs:PM_seg ;  Таблица глобальных дескрипторов.

GOT

GDT_flatDS GOT_16bitCS GDT_32bitCS gdt_size = !f-

gdtr

SEL_flatDS

SEL_16bitCS

SEL_32bitCS

GDT

label

db db db db

dw dd

equ equ equ

byte

8 dup(O)

OFFh, OFFh, 0, 0, 0, 10010010b,111001111b,0

OFFh.OFFh, 0,0, 0,10O1101Ob, 0,0

OFFh,OFFh,0,0,0,10011010b,11001111b, 0

gdt_size-1 ?

001000b 010000b

O11OOOb

Ее лимит и адрес.

Селектор 4-гигабайтного сегмента данных. Селектор сегмента кода РМ_зед. Селектор сегмента кода РМ_зед.

32-битный защищенный режим.

; Точка входа в РМ_ептгу:

; Загрузить сегментные регистры, хог       еах,еах шоу       ах,SEL_flatOS тоу йэ.ах шоу еэ.ах

;  Создать каталог страниц.

шоу еа,1,00100000п шоу еах,00101007г1

включая стек.

Его физический адрес - 1 Мб. Адрес таблицы 0 = 1 Мб + 4 Кб. Записать первый элемент каталога. Остальные элементы каталога -нули.

0 - адрес страницы О. Число страниц в таблице.

Записать элемент таблицы. Добавить к адресу 4096 байт и повторить для всех элементов.

mov       есх,1023 xor .

rep stosd

; Заполнить таблицу страниц 0.

mov        еах,00000007П

mov       есх,1024 page_table:

stosd

add       еах,OOOOlOOOh

loop page.table Поместить адрес каталога страниц в CR3

mov       еах.ООЮООООп ; Базовый адрес = 1 Мб.

mov сгЗ.еах Включить страничную адресацию.

mov

or еах,80000000h

mov

А теперь изменить физический адрес страницы на mov eax,000A20O7h

mov .

Если закомментировать предыдущие две команды, следующие четыре закрасят весь экран синим цветом,  но из-за что мы переместили

страницу, останется черный участок.

одну

mov        есх,(320*200)/4 mov edi.OAOOOOh mov       eax,01010101h

rep stosd

; Вернуться, в реальный режим.

db OEAh

dd offset RM_return

dw SEL_16bitCS

PM_seg ends

;  Сегмент стека - используется как 16-битный. stack_seg segment para stack "STACK" stack_start       db        lOOh dup(?) stack_seg ends end start

Размер экрана в двойных словах. Линейный адрес начала видеопамяти. Код синего цвета в VGA - 1.