Сегментация со страничной организацией памяти: система Intel x86

До появления x86-64 виртуальная память в системе x86 во многих отношениях напоминала память в системе MULTICS, включая наличие как сегментации, так и страничной организации. Но система MULTICS имела 256 K независимых сегментов, каждый до 64 К 36-разрядных слов, а система x86 поддерживает 16 K независимых сегментов, каждый до 1 млрд 32-разрядных слов.
Хотя в последней системе меньше сегментов, их больший размер куда важнее, поскольку программы, которым требуется более чем 1000 сегментов, встречаются довольно редко, в то время как многим программам необходимы большие по размеру сегменты. Что же касается x86-64, то сегментация считается устаревшей и больше не поддерживается, исключая работу в унаследованном режиме. Хотя некоторые остатки старых механизмов сегментации в исходном режиме работы систем x86-64 все еще доступны, главным образом для обеспечения совместимости, они
больше не играют ту же роль и не предлагают реальную сегментацию. Но системы x86-32 до сих пор поставляются оборудованными по полной схеме, и именно этот центральный процессор и будет рассматриваться в данном разделе.

Основа виртуальной памяти системы x86 состоит их двух таблиц: локальной таблицы дескрипторов (Local Descriptor Table (LDT)) и глобальной таблицы дескрипторов

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


Чтобы получить доступ к сегменту, программа, работающая в системе x86, сначала загружает селектор для этого сегмента в один из шести сегментных регистров машины. Во время выполнения программы регистр CS содержит селектор для сегмента кода, а регистр DS хранит селектор для сегмента данных. Каждый селектор (рис. 3.35) представляет собой 16-разрядное целое число.


Один из битов селектора несет информацию о том, является ли данный сегмент локальным или глобальным (то есть к какой таблице дескрипторов он относится, локальной или глобальной). Следующие 13 битов определяют номер записи в таблице дескрипторов, поэтому в каждой из этих таблиц не может содержаться более чем 8 К сегментных дескрипторов. Остальные 2 бита имеют отношение к защите и будут рассмотрены позже. Дескриптор 0 запрещен. Его можно без всякой опаски загрузить в сегментный регистр, чтобы обозначить, что этот сегментный регистр в данный момент недоступен. Попытка им воспользоваться приведет к системному прерыванию.

Во время загрузки селектора в сегментный регистр из локальной или глобальной таблицы дескрипторов извлекается соответствующий дескриптор, который, чтобы ускорить к нему обращение, сохраняется в микропрограммных регистрах. Как показано на рис. 3.36, дескриптор состоит из 8 байтов, в которые входят базовый адрес сегмента, размер и другая информация.

Чтобы облегчить определение местоположения дескриптора, был искусно подобран формат селектора. Сначала на основе бита 2 селектора выбирается локальная или глобальная таблица дескрипторов. Затем селектор копируется во внутренний рабочий регистр, и значения трех младших битов устанавливаются в 0. Наконец, к этой копии прибавляется адрес одной из таблиц, LDT или GDT, чтобы получить прямой указатель на дескриптор. Например, селектор 72 ссылается на запись 9 в глобальной таблице дескрипторов, которая расположена по адресу в таблице GDT + 72.

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

Рис. 3.36. Дескриптор сегмента кода в системе Pentium. Сегменты данных имеют незначительные отличия


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

Затем аппаратура использует поле предела Limit, чтобы проверить, не выходит ли смещение за предел сегмента, и в этом случае также возникает системное прерывание. По логике, для предоставления размера сегмента в дескрипторе должно быть 32-разрядное поле, но доступны только 20 бит, поэтому используется другая схема. Если поле Gbit (Granularity — степень детализации) равно 0, в поле Limit содержится точный размер сегмента вплоть до 1 Мбайт. Если оно равно 1, то в поле Limit предоставляется размер сегмента в страницах, а не в байтах. При размере страниц, равном 4 Кбайт, 20 битов вполне достаточно для сегментов размером до 232 байт.

Предположим, что сегмент находится в памяти и смещение попало в нужный интервал, тогда система x86 прибавляет 32-разрядное поле Base (база) в дескрипторе к смещению, формируя то, что называется линейным адресом (рис. 3.37). Поле Base разбито на три части, которые разбросаны по дескриптору для совместимости с процессором Intel 80286, в котором поле Base имеет только 24 бита. В сущности, поле Base позволяет каждому сегменту начинаться в произвольном месте внутри 32-разрядного линейного адресного пространства.

Рис. 3.37. Преобразование пары «селектор — смещение» в линейный адрес



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

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


У каждой работающей программы есть страничный каталог, состоящий из 1024 32-разрядных записей. Он расположен по адресу, который указан в глобальном регистре. Каждая запись в каталоге указывает на таблицу страниц, также содержащую 1024 32-разрядных записи. Записи в таблицах страниц, в свою очередь, указывают на страничные блоки. Эта схема показана на рис. 3.38.


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

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

Каждая таблица страниц включает в себя записи для 1024 страничных блоков размером по 4 Кбайт, таким образом, одна таблица страниц справляется с 4 Мбайт памяти. Сегмент, длина которого меньше 4 Мбайт, будет иметь страничный каталог с единственной записью — указателем на его единственную таблицу страниц. Следовательно, в случае короткого сегмента на поддержку таблиц страниц расходуется только две страницы вместо 1 млн, которые были бы нужны в одноуровневой таблице страниц.

Чтобы избежать повторных обращений к памяти, система x86, как и система MULTICS, имеет небольшой буфер быстрого преобразования адреса (TLB), который напрямую отображает наиболее часто использующиеся комбинации Каталог — Страница на физический адрес страничного блока. Механизм, показанный на рис. 3.38, задействуется лишь при отсутствии текущей комбинации в буфере TLB, при этом сам буфер обновляется. Если отсутствие нужной информации в буфере TLB встречается довольно редко, система достигает неплохой производительности.

Также следует отметить, что эта модель работает и в том случае, когда некоторые приложения не требуют сегментации, а просто довольствуются единым, разбитым на страницы 32-разрядным адресным пространством. Все сегментные регистры могут быть настроены тем же самым селектором, в дескрипторе которого поле Base = 0, а поле Limit установлено на максимум. Тогда смещение команды будет линейным адресом и будет использоваться только одно адресное пространство, что приведет к обычной страничной организации памяти. Фактически таким образом работают все современные операционные системы для компьютера x86. Единственным исключением была система OS/2, в которой использовались все возможности архитектуры диспетчера памяти (MMU) фирмы Intel.

Так почему же Intel отменила то, что было вариантом весьма неплохой модели памяти MULTICS, поддерживаемой на протяжении почти трех десятилетий? Возможно, основной причиной стало то, что ни UNIX, ни Windows никогда не использовали этот вариант, несмотря на его высокую эффективность, по причине исключения системных вызовов и превращения их в молниеносные вызовы процедур по соответствующим адресам внутри защищенного сегмента операционной системы. Ни один из разработчиков любой UNIX- или Windows-системы не захотел менять свою модель памяти на нечто присущее только x86, так как это нарушило бы переносимость на другие платформы. Поскольку эта возможность оказалась невостребованной со стороны программного обеспечения, компании Intel надоело тратить впустую площадь микросхемы на ее поддержку и из 64-разрядных процессоров она была убрана.

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

3.8.

<< | >>
Источник: Э. ТАНЕНБАУМ Х. БОС. СОВРЕМЕННЫЕ ОПЕРАЦИОННЫЕ СИСТЕМ Ы 4-е ИЗДАНИЕ. 2015

Еще по теме Сегментация со страничной организацией памяти: система Intel x86:

  1. 34. Социальная организация как вид социальной системы. Типы социальных организаций
  2. Организация как система.
  3. Организация как закрытая и открытая система.
  4. Фабричная система организации труда.
  5. § 5.2. Свойства и функции системы управления в организации
  6. § 2. Банковская система России. Взаимоотношения Банка России с кредитными организациями
  7. ПРЕДСТАВЛЕНИЕ ПАМЯТИ
  8. 33. Понятие «социальная система» и социальной организации
  9. Гигиена памяти.
  10. укрепление памяти
  11. ТЕОРИЯ ПАМЯТИ
  12. V. 2. 5. Структура парциального хранилища памяти.
  13. Сила памяти
  14. 9.11. С ПОМОЩЬЮ ПАМЯТИ
  15. В психологии различают четыре типа памяти.
  16. V. 2. МОДЕЛЬ ПАРЦИАЛЬНОГО ХРАНИЛИЩА ПАМЯТИ ЧЕЛОВЕКА
  17. следующие виды памяти