2. Адресация памяти в защищенном режиме.

2.1 Дескрипторы и таблицы дескрипторов.

2.2 Страничное управление памятью, виртуальная память.

 

2.1 Дескрипторы и таблицы дескрипторов.

 

Как отмечалось выше, защищенный режим сохранил сегментную модель памяти (адрес ячейки памяти определяется суммой компонент: адрес начала сегмента и внутрисегментного смещения). Но в отличие от режима реального адреса, где адрес сегмента находился непосредственно в одном из сегментных регистров – алгоритм формирования физического адреса в защищенном режиме абсолютно иной. Сегмент, в защищенном режиме, это не просто область памяти, ограниченная лишь максимально допустимым значением внутрисегментного смещения, как это было в реальном режиме, - это «объект», который имеет строго определенный размер, не пересекается с другими сегментами (хотя один и тот же сегмент можно описать дважды) и имеет ряд других атрибутов, по которым, в частности, происходит аппаратная защита памяти со стороны процессора. Каждый сегмент имеет свой дескриптор (описатель сегмента). Дескрипторы  сегментов собираются в специализированных системных сегментах – дескрипторных таблицах.

Существует три типа дескрипторных таблиц – глобальная таблица дескрипторов (одна в системе); локальная таблица дескрипторов (своя для каждой задачи); таблица дескрипторов прерываний (см. главу 4). Каждый дескриптор (элемент) таблицы описывает свой сегмент памяти. Сегменты памяти не пересекаются! Размер таблиц находится в пределах 8 байт – 64 Кбайт, что соответствует числу элементов в таблице от 1 до 8192.

Адрес начала каждой из таблиц (указатель на начало таблицы) хранится в специальных (программно доступных) регистрах процессора. Указатели на таблицу глобальных дескрипторов (GDTR) и таблицу прерываний (IDTR) имеют размер 48 байт, 32 из которых указывают линейный адрес начала таблицы, а остальные 16 – ее размер (предел).

У регистра-указателя локальной дескрипторной таблицы (LDTR) программно доступно только 16-битное поле селектора (индекса для GDT), по которому из GDT автоматически загружаются программно недоступные и невидимые поля базового адреса и размера таблицы. Регистр LDTR указывает на дескриптор в GDT, описывающий локальную дескрипторную таблицу для текущей задачи.

Команды загрузки регистров-указателей таблиц (GDTR, LDTR, IDTR) являются привилегированными (выполняются только на нулевом кольце привилегий (см. главу 3)).

Глобальная таблица (GDT)  содержит дескрипторы, доступные все задачам. Может содержать дескрипторы любых типов, кроме дескрипторов прерываний и ловушек (см. главу 4). Нулевой элемент этой таблицы процессором не используется.

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

Дескрипторные таблицы создаются и поддерживаются операционной системой.

 

Дескрипторы сегментов кода и данных имеют следующий формат:

Адрес сегмента – физический адрес начала сегмента (если нет страничного преобразования);

Размер  -  размер сегмента (Размер сегмента  – 1);

Байт доступа – содержит информацию о защите сегмента;

 

D  - бит разрядности выполняемых команд (для кодового сегмента):

0 – 16-разрядные; 

1 – 32-разрядные

 

G   - признак единицы измерения сегмента:

0 – в байтах;

1 – в страницах (по 4 Кб), при использовании страничной адресации памяти;

 

AVL   -   сегмент доступен для использования системным программным обеспечением (используются только ОС);

 

          Дескрипторы системных сегментов имеют следующий формат:

Системные сегменты предназначены для хранения локальных таблиц де­скрипторов LDT и состояния задач TSS (Task State Segment) (см. главу 5). Их дескрипторы определяют базовый адрес, лимит сегмента (1-64 Кбайт), права доступа (чтение, чтение/запись, только исполнение кода или исполнение/чтение) и присутствие сегмента в физической памяти. В байте управления доступом у этих дескрипторов бит Р определяет дейст­вительность (Р=1) или недействительность (Р=0) содержимого сегмента. Поле уровня привилегий DPL используется только в дескрипторах сегментов состоя­ния задач (TSS). Поскольку обращение к дескрипторам LDT возможно только по привилегированным командам, поле DPL для дескрипторов локальных таблиц не исполь­зуется. Поле ТYPE (1-3, 9-В) определяет тип сегмента:

 

· 0, 8 - недопустимые значения;

· 1 - доступный сегмент состояния задачи 80286 (Available TSS-286);

· 2 - таблица локальных дескрипторов (LDT);

· 3 - занятый сегмент состояния задачи 80286 (Busy TSS-286);

· 9 - доступный сегмент состояния задачи 386+ (Available TSS-386);

· А - не определено (зарезервировано);

· B - занятый сегмент состояния задачи 386+ (Busy TSS-386).

 

        Дескрипторы шлюзов имеют следующий формат:

В байте управления доступом у этих дескрипторов бит Р определяет действительность (Р=1) или недействительность (Р=0) содержимого сегмента. Поле DPL задает уровень привилегий. Поле TYPE определяет тип шлюза:

 

· 4 - шлюз вызова 80286 (Call Gate);

· 5 - шлюз задачи 80286 (Task Gate);

· 6 - шлюз прерывания 80286 (Interrupt Gate);

· 7 - шлюз ловушки 80286 (Trap Gate);

· C - шлюз вызова 386+ (Call Gate);

· D - шлюз задачи 386+ (Task Gate);

· Е - шлюз прерывания 386+ (Interrupt Gate);

· F - шлюз ловушки 386+ (Trap Gate).

 

Поле «Word Count» используется только в шлюзах вызовов и определяет число слов из стека вызывающего процесса, автоматически копируемых в стек вызывае­мой процедуры. Для сегментов 80286 слова 16-битные, для 386+ - 32-битные.

Слово «Селектор» для шлюзов вызова, прерываний и ловушек задает селектор целевого сегмента кода, а для шлюзов задачи - селектор целевого TSS.

Слово «Смещение» задает смещение (адрес) точки входа в целевом сег­менте.

При использовании шлюзов может возникнуть исключение #GP, которое озна­чает, что селектор указывает на некорректный тип дескриптора. При попытке ис­пользования недействительного шлюза (Р=0) возникает исключение #NР. (Подробнее о шлюзах см. главу 4, и главу 5).

Сегментные регистры в защищенном режиме играют роль селекторов (индексов дескрипторов в дескрипторных таблицах).

Формат селектора следующий:

I - номер (индекс) дескриптора в таблице (0¸213-1);

TI – тип дескрипторной таблицы: 0  - GDT; 1 - LDT;

RPL – номер запрашиваемого уровня привилегий;

 

Рассмотрим пример обращения процессора к памяти в сегмент (данных), описанный в глобальной дескрипторной таблице (GDT) – т.е. бит “TI” в селекторе сегмента равен нулю.

 

 

Старшие 13 байт селектора являются смещением искомого дескриптора от начала дескрипторной таблицы. Младшие байты играют роль атрибутов (см. выше), и при адресации внутри таблицы интерпретируются как нули – за счет чего происходит адресация таблицы по полю “i” с точностью до восьмибайтного слова, или (что в данном случае одно и тоже) до дескриптора. Адрес сегмента, прочитанный из дескриптора, складывается с внутрисегментным смещением и при отсутствии страничного преобразования адреса (см. ниже) выставляется на адресную шину.

 

Если бит “TI  в селекторе сегмента равен “1”, то происходит выборка сегмента из локальной дескрипторной таблицы. В этом случае регистр LDTR должен содержать селектор этой таблицы (индекс) – локальная дескрипторная таблица описывается дескриптором глобальной таблицы. Сам же селектор (в котором “TI”=1) определяет дескриптор сегмента памяти, описанного в локальной дескрипторной таблице. В регистре LDTR бит “TI” всегда нулевой – т.к. дескриптор-описатель локальной таблицы может находиться только в GDT.

 

 

2.2 Страничное управление памятью,

 виртуальная память.

 

Страничное управление (Paging) является средством организации виртуальной памяти с подкачкой страниц по запросу (Demand-Paged Virtual Memory). В от­личие от сегментации, которая организует программы и данные в модули раз­личного размера, страничная организация оперирует с памятью, как с набором страниц одинакового размера. В момент обращения страница может присутст­вовать в физической оперативной памяти, а может быть выгруженной на внеш­нюю (дисковую) память. При обращении к выгруженной странице памяти про­цессор вырабатывает исключение #PFотказ страницы, а программный обработчик исключения (часть ОС) получит необходимую информацию для свопинга — «подкачки» отсутствующей страницы с диска. Страницы не имеют прямой связи с логической структурой данных или программ. В то время как селекторы можно рассматривать как логические имена модулей кодов и данных, страницы представляют части этих модулей. Учитывая обычное свойство ло­кальности (близкого расположения требуемых ячеек памяти) кода и ссылок на данные, в оперативной памяти в каждый момент времени следует хранить толь­ко небольшие области сегментов, необходимые активным задачам. Эту возмож­ность (а следовательно, и увеличение допустимого числа одновременно вы­полняемых задач при ограниченном объеме оперативной памяти) как раз и обеспечивает страничное управление памятью. В первых 32-разрядных процессо­рах (начиная с i80386) размер страницы составлял 4 Кбайт. Начиная с Pentium, появилась возможность увеличения размера страницы до 4 Мбайт, одновре­менно с использованием страниц размером 4 Кбайт. В Р6 имеется возможность расширения физического адреса до 36 бит (64 Гбайт), при котором могут ис­пользоваться страницы размером 4 Кбайт и 2 Мбайт.

Базовый механизм страничного управления использует двухуровневую таб­личную трансляцию линейного адреса в физический.

Механизм имеет три части: каталог страниц (Page Directory), таблицы страниц (Page Table) и собственно страницы (Page Frame). Механизм вклю­чается установкой бита PG=1 в регистре CRO. Регистр CR2 хранит линейный адрес отказа (Page Fault Linear Address) — адрес памяти, по которому был обнаружен последний отказ страницы. Регистр CR3 хранит физический адрес каталога страниц (Page Directory Physical Base Address). Его младшие 12 бит всегда нулевые (каталог выравнивается по границе страницы).

 

 

Каталог страниц, размером 4 Кбайт содержит 1024 32-битных строки РDЕ (Page Directory Entry). Каждая строка (см. ниже рис. а) содержит 20 старших бит адреса таблицы следующего уровня (младшие биты этого адреса всегда нуле­вые) и признаки (атрибуты) этой таблицы. Индексом поиска в каталоге страниц являются 10 старших бит линейного адреса (А22-А31).

 

а — строка каталога; б — строка таблицы

 

Каждая таблица страниц также имеет 1024 строки РТЕ (Page Table Entry) аналогичного формата (рис. б), но эти строки содержат базовый физический адрес (Page Frame Address) и атрибуты самих страниц. Индексом поиска в таблице являются биты А12-А21 линейного адреса. Физический адрес получается из адреса страницы, взятого из таблицы, и младших 12 бит линейного адреса. Строки каталога и таблиц имеют следующие биты атрибутов:

Р (Present) — бит присутствия. Р=1 означает возможность использования данной строки для трансляции адреса. Бит присутствия вхождений в таб­лицы, используемые текущим исполняемым кодом, должен быть установ­лен. Программный код не должен его изменять «на ходу». Если Р=0, то все остальные биты доступны операционной системе и могут использо­ваться для получения информации о местонахождении данной страницы.

A (Accessed) — признак доступа, который устанавливается перед любым чтением или записью по адресу, в преобразовании которого участвует дан­ная строка.

D (Dirty) — признак, который устанавливается перед операцией записи по адресу, в преобразовании которого участвует данная строка. Таким образом, помечается использованная — «грязная» страница, которую в случае замещения необходимо выгрузить на диск.

Биты Р, А, D модифицируются процессором аппаратно в заблокированных шин­ных циклах. При их программной модификации в многопроцессорных системах должен использоваться префикс LOCK, гарантирующий сохранение целостности данных.                                                     

Поле OS Reserved программно используется по усмотрению ОС и может хра­нить, например, информацию о «возрасте» страницы, необходимую для реали­зации замещения по алгоритму LRU (Least Recently Used — наиболее долго не использовавшаяся страница замещается первой).

Бит PWT (Page Write Through) определяет политику записи при кэширова­нии, а бит PCD (Page Cache Disable) запрещает кэширование памяти для обслу­живаемых страниц или таблиц (используются на процессорах i486+).

Бит PS (Page Size) задает размер страницы (только в РОЕ). При PS=0 страница имеет размер 4 Кбайт, PS=1 используется в расширениях РАЕ и PSE.

Бит G (Global), появившийся в Р6, определяет глобальность страницы. Он анализируется только в строке, указывающей на страницу физической памяти (в РТЕ для страниц в 4 Кбайт, в PDE — для страниц 2 Мбайт или 4 Мбайт). Этот бит, управляемый только программно, позволяет пометить страницы гло­бального использования (например, ядра ОС). При установленном бите PGE в регистре CR4 строки с указателями на глобальные таблицы не будут аннулиро­ваться в TLB при загрузке CR3 или переключении задач, что снижает издержки обслуживания виртуальной памяти.