Сегментация памяти — это метод управления памятью операционной системы , заключающийся в разделении первичной памяти компьютера на сегменты или разделы . В компьютерной системе, использующей сегментацию, ссылка на ячейку памяти включает значение, которое идентифицирует сегмент и смещение ( ячейку памяти) внутри этого сегмента. Сегменты или разделы также используются в объектных файлах скомпилированных программ, когда они связаны вместе в образ программы и когда образ загружается в память.
Сегменты обычно соответствуют естественным разделам программы, таким как отдельные процедуры или таблицы данных [1], поэтому сегментация, как правило, более заметна для программиста, чем просто разбиение на страницы . [2] Сегменты могут быть созданы для программных модулей или для классов использования памяти, таких как сегменты кода и сегменты данных . [3] Некоторые сегменты могут совместно использоваться программами. [1] [2]
Сегментация изначально была изобретена как метод, с помощью которого системное программное обеспечение могло изолировать программные процессы ( задачи ) и данные, которые они используют. Она была предназначена для повышения надежности систем, выполняющих несколько процессов одновременно. [4]
В системе, использующей сегментацию, адреса памяти компьютера состоят из идентификатора сегмента и смещения внутри сегмента. [3] Аппаратный блок управления памятью (MMU) отвечает за преобразование сегмента и смещения в физический адрес , а также за выполнение проверок, чтобы убедиться, что преобразование может быть выполнено и что ссылка на этот сегмент и смещение разрешена.
Каждый сегмент имеет длину и набор разрешений (например, чтение , запись , выполнение ), связанных с ним. [ 3] Процессу разрешено делать ссылку на сегмент, только если тип ссылки разрешен разрешениями, и если смещение внутри сегмента находится в диапазоне, указанном длиной сегмента. В противном случае возникает аппаратное исключение , такое как ошибка сегментации .
Сегменты также могут использоваться для реализации виртуальной памяти . В этом случае каждый сегмент имеет связанный с ним флаг, указывающий, присутствует ли он в основной памяти или нет. Если осуществляется доступ к сегменту, которого нет в основной памяти, возникает исключение, и операционная система считывает сегмент в память из вторичного хранилища.
Сегментация — один из методов реализации защиты памяти . [5] Страничная организация — другой, и их можно комбинировать. Размер сегмента памяти обычно не фиксирован и может быть всего лишь одним байтом . [6]
Сегментация реализована несколькими способами на различном оборудовании, с подкачкой или без нее. Сегментация памяти Intel x86 не подходит ни под одну из моделей и обсуждается отдельно ниже, а также более подробно в отдельной статье.
С каждым сегментом связана информация, указывающая, где сегмент расположен в памяти — база сегмента . Когда программа ссылается на ячейку памяти, смещение добавляется к базе сегмента для генерации адреса физической памяти.
Реализация виртуальной памяти в системе с использованием сегментации без подкачки требует, чтобы целые сегменты обменивались между основной памятью и вторичным хранилищем. Когда сегмент обменивается, операционная система должна выделить достаточно непрерывной свободной памяти для хранения всего сегмента. Часто фрагментация памяти возникает, если недостаточно непрерывной памяти, даже если в целом ее может быть достаточно.
Вместо расположения в памяти информация о сегменте включает адрес таблицы страниц для сегмента. Когда программа ссылается на расположение в памяти, смещение преобразуется в адрес памяти с использованием таблицы страниц. Сегмент можно расширить, выделив еще одну страницу памяти и добавив ее в таблицу страниц сегмента.
Реализация виртуальной памяти в системе, использующей сегментацию с подкачкой страниц, обычно перемещает только отдельные страницы вперед и назад между основной памятью и вторичным хранилищем, аналогично страничной несегментированной системе. Страницы сегмента могут располагаться в любом месте основной памяти и не обязательно должны быть смежными. Обычно это приводит к уменьшению объема ввода/вывода между первичным и вторичным хранилищем и уменьшению фрагментации памяти.
Компьютер Burroughs Corporation B5000 был одним из первых, кто реализовал сегментацию, и «возможно, первым коммерческим компьютером, который предоставил виртуальную память» [7] на основе сегментации. B5000 оснащен таблицей информации о сегментах, называемой таблицей ссылок на программы (PRT), которая используется для указания того, находится ли соответствующий сегмент в основной памяти, для поддержания базового адреса и размера сегмента. [8] Более поздний компьютер B6500 также реализовал сегментацию; версия его архитектуры все еще используется сегодня на серверах Unisys ClearPath Libra. [ необходима цитата ]
Компьютер GE 645 , модификация GE-635 с добавленной поддержкой сегментации и страничного обмена, был разработан в 1964 году для поддержки Multics .
Intel iAPX 432 [9] , разработка которого началась в 1975 году, пытался реализовать настоящую сегментированную архитектуру с защитой памяти на микропроцессоре.
Версия 960MX процессоров Intel i960 поддерживала инструкции загрузки и сохранения с источником или местом назначения, являющимся «дескриптором доступа» для объекта, и смещением в объекте, при этом дескриптор доступа находился в 32-битном регистре, а смещение вычислялось из базового смещения в следующем регистре и из дополнительного смещения и, опционально, индексного регистра, указанного в инструкции. Дескриптор доступа содержит биты разрешения и 26-битный индекс объекта; индекс объекта является индексом в таблице дескрипторов объектов, давая тип объекта, длину объекта и физический адрес для данных объекта, таблицу страниц для объекта или таблицу страниц верхнего уровня для двухуровневой таблицы страниц для объекта, в зависимости от типа объекта. [10]
Компьютеры Prime , Stratus , Apollo , IBM System/38 и IBM AS/400 (включая IBM i ) используют сегментацию памяти.
Слова в B5000, B5500 и B5700 имеют длину 48 бит. [11] Дескрипторы имеют самый верхний бит, установленный в слове. Они находятся либо в таблице ссылок на программы (PRT), либо в стеке и содержат бит присутствия , указывающий, присутствуют ли данные в памяти. Существуют отдельные дескрипторы данных и программ. [11] : 4-2–4-4
Слова в B6500 и его последователях имеют 48 бит данных и 3 бита тега. [12] : 2-1 Биты тега указывают тип данных, содержащихся в слове; существует несколько типов дескрипторов, обозначенных различными значениями бит тега. [12] : 6-5–6-10 Линейка включает B6500, B6700, B7700, B6800, B6900, B5900, машины Burroughs и Unisys серии A и текущие системы Clearpath MCP (Libra). Хотя за эти годы было несколько улучшений, особенно аппаратных, архитектура изменилась мало. Схема сегментации осталась прежней, см. Сегментированная память .
В моделях IBM System/370 [a] с виртуальным хранилищем [13] [14] (DAT) и 24-битными адресами регистр управления 0 определяет размер сегмента 64 КиБ или 1 МиБ и размер страницы 2 КиБ или 4 КиБ; регистр управления 1 содержит указатель таблицы сегментов (STD), который определяет длину и реальный адрес таблицы сегментов. Каждая запись таблицы сегментов содержит местоположение таблицы страниц, длину таблицы страниц и недопустимый бит. Позднее IBM расширила размер адреса до 31 бита и добавила два бита к записям таблицы сегментов:
Каждая из реализаций DAT от IBM включает кэш трансляции, который IBM назвала буфером трансляции Lookaside (TLB). Хотя в Principles of Operation TLB обсуждается в общих чертах, детали не являются частью архитектуры и различаются от модели к модели.
Начиная с процессорных комплексов 3031, 3032 и 3033 , IBM предложила функцию под названием Dual-address Space [14] : 5-13–5-17, Dual-Address-Space Control : 5-17–5-20, DAS Authorization Mechanisms : 5-21–5-24, PC-Number Translation [15] (DAS), которая позволяет программе переключаться между таблицами трансляции для двух адресных пространств, называемых первичным адресным пространством (CR1) и вторичным адресным пространством (CR7), и перемещать данные между адресными пространствами с учетом ключа защиты. DAS поддерживает таблицу трансляции для преобразования 16-битного номера адресного пространства (ASN) в STD с привилегированными инструкциями для загрузки STD в CR1 (первичный) или CR7 (вторичный).
Ранние процессоры x86 , начиная с Intel 8086 , обеспечивают грубую сегментацию памяти и не защищают память . (Каждый байт каждого сегмента всегда доступен любой программе.) 16-битные регистры сегментов позволяют использовать 65 536 сегментов; каждый сегмент начинается с фиксированного смещения, равного 16-кратному номеру сегмента; гранулярность начального адреса сегмента составляет 16 байт. Каждый сегмент предоставляет доступ для чтения-записи к 64 КБ (65 536 байт) адресного пространства (этот предел задается 16-битными регистрами PC и SP; процессор не проверяет границы). Смещение+адрес, превышающие 0xFFFFF, возвращаются к 0x00000. Каждый сегмент размером 64 КБ перекрывает следующие 4095 сегментов; каждый физический адрес может быть обозначен 4096 парами сегмент-смещение. Эта схема может адресовать только 1 МиБ (1024 КиБ) физической памяти (и отображенный в память ввод/вывод). (Дополнительное расширенное аппаратное обеспечение памяти может добавлять память с переключением банков под программным управлением.) Intel задним числом назвала единственный режим работы этих моделей процессоров x86 « реальным режимом ».
Процессоры Intel 80286 и более поздние версии добавляют « защищенный режим 286 », который сохраняет 16-битную адресацию и добавляет сегментацию (без подкачки) и защиту памяти по сегментам. Для обратной совместимости все процессоры x86 запускаются в «реальном режиме» с теми же фиксированными перекрывающимися сегментами по 64 КиБ, без защиты памяти, только 1 МиБ физического адресного пространства и некоторыми тонкими различиями ( область верхней памяти , нереальный режим ). Чтобы использовать его полное 24-битное (16 МиБ) физическое адресное пространство и расширенные функции MMU , процессор 80286 или более поздний версии должен быть переключен в «защищенный режим» программным обеспечением, обычно операционной системой или расширителем DOS . Если программа не использует регистры сегментов или только помещает в них значения, которые она получает от операционной системы, то идентичный код может работать в реальном режиме или защищенном режиме, но большинство программ реального режима вычисляют новые значения для регистров сегментов, нарушая эту совместимость.
Процессоры Intel i386 и более поздние версии добавляют « защищенный режим 386 », который использует 32-битную адресацию, сохраняет сегментацию и добавляет страничную подкачку памяти . В этих процессорах таблица сегментов, вместо указания на таблицу страниц для сегмента, содержит адрес сегмента в линейной памяти . Когда страничная подкачка включена, адреса в линейной памяти затем сопоставляются с физическими адресами с помощью отдельной таблицы страниц. Большинство операционных систем не использовали возможность сегментации, предпочитая сохранять базовый адрес во всех регистрах сегмента равным 0 в любое время и обеспечивать защиту памяти на каждой странице и подкачку с использованием только страничной подкачки. Некоторые используют регистр CS для обеспечения защиты исполняемого пространства на процессорах, не имеющих бита NX , или используют регистры FS или GS для доступа к локальному хранилищу потока. [16] [17]
Архитектура x86-64 не поддерживает сегментацию в « длинном режиме » (64-битном режиме). [18] Четыре из регистров сегмента: CS, SS, DS и ES принудительно устанавливаются в 0, а предел — в 2 64 . Регистры сегмента FS и GS по-прежнему могут иметь ненулевой базовый адрес. Это позволяет операционным системам использовать эти сегменты для специальных целей, таких как локальное хранилище потока. [16] [17]