Rambler's
Top100

Разработка операционных систем. Выпуск 19

Автор: lonesome [TSH/Digital Daemons]
Дата: 26.07.2003
Раздел: Разработка ОС

ПРЕДЫДУЩИЙ ВЫПУСК      СЛЕДУЮЩИЙ ВЫПУСК

Разработка операционных систем

Выпуск 19 от 2003-06-30

Сегодня в номере:

Реализация виртуальной памяти на IA-32 (x86)

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

Сегментация

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

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

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

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

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

Для начала отключим сегментацию, чтобы она нам не мешала. Фактически. сегментация в IA-32 действует всегда и отключить ее нельзя, но можно сделать ее максимально прозрачной. Для этого достаточно загрузить все сегментные регистры дескрипторами сегментов с базой 0 и лимитом 4Гб.Все! Теперь в нашем распоряжении в свободном доступе имеется все адресное пространство. (именно в такое состояние переводит процессор загрузчик, который мы написали ранее)

Страничная адресация, в отличие от сегментации, по умолчанию отключена и включается установкой бита 31 регистра CR0. Но прежде чем мы ее включим, нам необходимо создать рабочий каталог страниц и поместить его в регистр CR3 (также называемый PDBR - page directory base register).

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

Что представляет из себя каталог страниц? Он состоит из 1024 указателей на таблицы страниц (они именуются записями каталога страниц или PDE - page directory entry), которые имеют тип dword. (если указатель на каталог имеет вид int *pagedir, то pagedir[n] будет n-ым PDE)

Таблица страниц представляет из себя 1024 указателя на физические страницы (эти указатели именуются записями таблицы страниц или PTE - page table entry), которые также имеют тип dword

Каждая таблица страниц (и каждая страница) обязана быть выровнена по 4-кб адресу. А это означает, что младшие 12 бит PDE и PTE не используются при указании адреса

Эти 12 бит описывают параметры страницы или таблицы страниц и имеют следующий формат:

Разберемся, как же процессор получает физический адрес виртуальной страницы. Допустим было произведено обращение к адресу 0x80050075 (двоичное 1000 0000 0000 0101 0000 0000 0111 0101). Если страничная адресация включена, то:

Разумеется, кроме проверки на существование страницы (бит 0 PDE или PTE) осуществляются и другие, но для ясности их мы опустили. Чем же эта проверка так отличается от других? Дело в том, что если вдруг процессор замечает, что таблица/страница не существует, то он немедленно сигнализирует об этом с помощью Page Fault и не смотрит на остальные биты (в которых, к примеру, операционная система может хранить информацию о том, где же на самом деле находится эта страница). То есть, если бит 0 равен 0, то ВСЕ ОСТАЛЬНЫЕ биты PTE или PDE доступны для использования операционной системе

Алгоритм нахождения адреса, приведенный выше, слишком медлителен, и использование его при каждом обращении к памяти привело бы к существенному понижению скорости работы. Поэтому адреса страниц кэшируются и если обращение происходило недавно, то процессор достает адрес страницы из кэша TLB (translation lookaside buffer)

Установленный бит 8 "глобальная страница" определяет, что адрес страницы НЕ выгружается из TLB при перезагрузке CR3. Поясним на примере. В ОС Tyros младшие два гигабайта адресного пространства (0x00000000 - 0x7FFFFFFF) являются системными (флаг "пользователь" снят) и на равных принадлежат всем процессам. Разумеется, что при переключении процессов эта часть адресного пространства не изменяется. Соответственно установленный бит 8 приходится очень кстати - не теряется время на выгрузку этой части из TLB и загрузку ее заново

В следующем выпуске мы продолжим разговор о реализации виртуальной памяти

Outro

На сегодня все, уважаемые подписчики.
Как всегда, мой почтовый ящик открыт для вас: lonesome@lowlevel.ru
Также вы можете задавать интересующие вас вопросы в форуме lowlevel.ru
Предыдущие выпуски рассылки вы можете найти по этому адресу:
http://subscribe.ru/archive/comp.soft.prog.osdev
А все, исходники, опубликованые в рассылке, располагаются здесь:
http://www.lowlevel.ru/osdev/sources.htm
Всего наилучшего!
Lonesome


[Главная] [Другие статьи] [Обсудить в форуме]
©2003-2004 Lowlevel.RU

Rambler's Top100