Сегменты
Сегменты
Семейство процессоров Intel позволяет разделить память на несколько логических частей, называемых сегментами. При этом адресное пространство процесса может быть представлено в виде нескольких логических сегментов, каждый из которых состоит из непрерывной последовательности адресов, лежащих в заданном диапазоне. Трансляция адресов, основанная на сегментации, предусматривает однозначное отображение адресов сегмента в непрерывную последовательность физических адресов. Виртуальный адрес при этом состоит из двух частей: селектора сегмента и смещения относительно начала сегмента. Селектор (точнее, поле селектора INDEX) указывает на так называемый дескриптор сегмента, содержащий такие параметры, как его расположение в памяти, размер и права доступа.
Процессор поддерживает косвенную адресацию сегментов через дескрипторы сегментов, которые располагаются в специальных таблицах — областях памяти, на которые указывают предназначенные для этого регистры процессора. Ядро операционной системы отвечает за заполнение этих таблиц и установку значений регистров. Другими словами, ядро задает отображение, а процессор выполняет отображение на аппаратном уровне. Благодаря такой косвенной адресации логические сегменты защищены друг от друга, что обеспечивает целостность адресного пространства процесса и ядра.
Дескрипторы сегментов расположены в двух системных таблицах — локальной таблице дескрипторов (Local Descriptor Table — LDT) и глобальной таблице дескрипторов (Global Descriptor Table — GDT). Как следует из названия, LDT обеспечивает трансляцию виртуальных адресов сегментов процесса, в то время как GDT обслуживает адресное пространство ядра (например, при обработке системного вызова или прерывания). Для каждого процесса создается собственная LDT, в то время как GDT разделяется всеми процессами. Информация о таблице, на которую указывает селектор, находится в самом селекторе, вид которого представлен на рис. 3.5.
Рис. 3.5. Селектор сегмента
Если бит TI равен 0, то селектор указывает на GDT, в противном случае используется LDT. Поле RPL задает уровень привилегий сегмента и является одним из механизмов обеспечения защиты сегментов. Например, если процесс, находясь в режиме задачи, попытается обратиться к сегменту, принадлежащему ядру, процессор сгенерирует особую ситуацию, в ответ на это ядро отправит процессу сигнал SIGSEGV.
Каждая запись LDT или GDT является дескриптором сегмента. Определено несколько типов дескрипторов, используемых для сегментов кода, данных и стека, а также ряд дескрипторов, с помощью которых обеспечивается многозадачность и передача управления от непривилегированной задачи, например, процесса в режиме задачи, к привилегированной задаче, например, ядру. Дескрипторы, используемые в последнем случае, называются шлюзами.
Дескрипторы сегментов (кода, данных, стека) имеют несколько полей:
Базовый адрес В этом поле хранится 32-битный адрес начала сегмента. Процессор добавляет к нему смещение и получает 32-битный линейный адрес. Предел Это поле определяет размер сегмента. Если результирующий линейный адрес выходит за пределы сегмента, процессор генерирует особую ситуацию. Границы сегмента позволяют процессору обнаруживать такие распространенные ошибки, как переполнение стека, неверные указатели, неверные адреса вызовов и переходов. В случае, когда операционная система считает, что обращение за пределы сегмента не является ошибкой (например, при переполнении стека), она может расширить сегмент путем выделения дополнительной памяти и запросить выполнение команды вновь. Привилегии Это поле, имеющее название Descriptor Privilege Level (DPL), определяет уровень привилегий сегмента и используется совместно с полем RPL селектора для разрешения или запрещения доступа к сегменту. Для получения доступа к сегменту задача должна иметь по крайней мере такой же уровень привилегий, как и сегмент, т.е. RPL ? DPL. Признак присутствия Этот бит обеспечивает один из механизмов реализации виртуальной памяти. Если бит не установлен, при попытке обращения к сегменту процессор генерирует особую ситуацию отсутствия сегмента, позволяя ядру подгрузить сегмент из вторичной памяти и вновь повторить инструкцию, не затрагивая при этом выполнение процесса. Однако в большинстве современных версий UNIX виртуальная память основана на страничном механизме, при котором сегмент всегда присутствует в памяти, а обмен между оперативной и вторичной памятью происходит на уровне страниц. Тип Это поле определяет тип сегмента. Процессор проверяет тип сегмента на соответствие исполняемой команде. Это, в частности, не позволяет интерпретировать информацию сегмента данных как инструкции процессора. Права доступа Это поле определяет права доступа, ограничивающие множество операций, которые можно производить с сегментом. Например, сегмент кода обычно отмечается как исполняемый и читаемый. Сегменты данных могут иметь право доступа только для чтения, или для чтения и записи.Комбинация селектора и смещения образует логический адрес. Блок управления памятью процессора использует селектор для определения соответствующего ему дескриптора. Складывая базовый адрес сегмента, хранящийся в дескрипторе, со смещением, процессор создает линейный адрес (рис. 3.6).
Рис. 3.6. Трансляция адреса с использованием механизма сегментации
Если страничный механизм не используется, полученный линейный адрес является физическим, используемым для непосредственного доступа к оперативной памяти. Однако реализация виртуальной памяти, основанная только на сегментах, не обладает достаточной гибкостью и не используется в современных версиях UNIX. Управление памятью в большинстве систем основано на страничном механизме. Сегменты используются ядром для размещения кода, данных и стека процесса, причем каждый из них имеет нулевой базовый адрес и предел — 3 Гбайт, т.е. всю адресуемую виртуальную память за вычетом 1 Гбайт, занимаемых ядром системы. Распределение виртуального адресного пространства между ядром и процессами рассмотрено в разделе "Адресное пространство процесса".
Данный текст является ознакомительным фрагментом.