Что такое виртуальная адресация

Виртуальное адресное пространство (управление памятью)

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

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

виртуальное адресное пространство для 32-разрядного Windows имеет размер 4 гигабайта (гб) и делится на две секции: одна для использования процессом, а другая зарезервирована для использования системой. дополнительные сведения о пространстве виртуальных адресов в 64-битном Windows см. в разделе виртуальное адресное пространство в 64-разрядной Windows.

Дополнительные сведения о виртуальной памяти см. в следующих разделах:

Виртуальное адресное пространство по умолчанию для 32-разрядного Windows

В следующей таблице показан диапазон памяти по умолчанию для каждой секции.

Диапазон памятиИспользование
Низкая 2 ГБ (от 0x00000000 до 0x7FFFFFFF)Используется процессом.
Высокий 2 ГБ (от 0x80000000 до 0xFFFFFFFF)Используется системой.

виртуальное адресное пространство для 32-разрядного Windows с 4GT

Если включена Настройка 4 гигабайта (4GT), диапазон памяти для каждой секции выглядит следующим образом.

Диапазон памятиИспользование
С низким 3 ГБ (0x00000000 до 0xBFFFFFFF)Используется процессом.
Высокий 1 ГБ (0xC0000000 до 0xFFFFFFFF)Используется системой.

Настройка виртуального адресного пространства для 32-разрядного Windows

Можно использовать следующую команду, чтобы задать параметр записи загрузки, который настраивает размер раздела, который может использоваться процессом, в диапазоне от 2048 (2 ГБ) до 3072 (3 ГБ):

BCDEdit/Set инкреасеусерва мегабайт

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

Источник

Виртуальный адрес

Виртуальный адрес — это адрес ячейки памяти с точки зрения программиста. Он может как совпадать, так и отличаться от физического адреса.

Виртуальный адрес в 32-разрядном режиме

В большинстве компьютерных архитектур виртуальный адрес является числом от нуля до некоего максимального значения, обычно определяемого разрядностью вычислительной машины, преобразуемым в физический адрес аппаратурой процессора. Архитектура IA-32 является одним из немногих исключений из этого правила. Во-первых, в программах используются сегментированные адреса, состоящие из 16-разрядного селектора сегмента и 32-разрядного смещения, т.е. адрес является не одним, а парой чисел. Во-вторых, фирма Intel не использует термин «виртуальный адрес», называя используемые в программах адреса логическими; таким образом, с точки зрения документации Intel, программист имеет дело именно с логическими адресами, а термин «виртуальный адрес» к архитектуре IA-32 вообще отношения не имеет. В-третьих, все операционные системы для архитектуры IA-32, поддерживающие механизм виртуальной памяти, а следовательно, оперирующие виртуальными адресами, пользуются механизмом сегментации IA-32 лишь в минимально необходимом объёме, предоставляя программам плоское адресное пространство, адресация внутри которого выполняется с помощью смещения, а селекторы сегментов остаются неизменными. Когда документация Windows или Linux говорит о передаче виртуальных адресов различным системным вызовам, во всех случаях передаётся только смещение из состава логического адреса.

Таким образом, можно считать, что термин «виртуальный адрес» применительно к 32-разрядным версиям распространённых ОС для платформы IA-32 является эквивалентом термина Intel «смещение, входящее в состав логического адреса для сегментов DS, SS, ES и CS» или другого, мало распространённого в реальной практике, но также используемого в документации Intel термина «эффективный адрес» (по отношению к тем же сегментам). Поскольку используется плоское адресное пространство с сегментами максимального размера (4 Гбайта), численно значение смещения (виртуального адреса) будет совпадать с линейным адресом, однако проводить знак равенства между терминами «виртуальный адрес» и «линейный адрес» некорректно, поскольку программист прямо работает именно с виртуальными адресами (в частности, передаёт их системным вызовам), а линейные адреса существуют лишь в глубинах процессора и для программиста недоступны в принципе.

Что касается сегментов FS и GS, они используются нестандартным образом. В Windows FS фактически является отправной точкой для доступа к TEB (в пользовательском режиме), т.к. адрес TEB в качестве базового адреса загружен в дескриптор сегмента, селектор которого хранится в FS. Сам TEB является частью «общего» сегмента кода, стека и данных, доступного через сегментные регистры CS, SS, DS и ES, поэтому доступ к нему можно получить и через указанные регистры, указав правильное смещение. Адресация через GS для прикладных программ недоступна вообще.

Виртуальный адрес в 64-разрядном режиме

В 64-разрядном режиме сегментация упразднена, поэтому программист работает с адресами, состоящими лишь из одного 64-разрядного числа и численно совпадающими с линейными адресами. Однако и здесь архитектура IA-32 является исключением из общего правила: линейный, а значит, и виртуальный адрес (логический в документации Intel) адрес фактически является числом со знаком, поскольку требуется, чтобы они были «каноническими», т.е. чтобы все старшие биты адреса были равны либо нулю, либо единице в зависимости от значения самого старшего физически реализованного разряда адреса. Например, в первых 64-разрядных микропроцессорах архитектуры IA-32 физически реализованы не 64-разрядные, а 48-разрядные линейные адреса, которые должны находиться в пределах от 0000_0000_0000_0000h до 0000_7FFF_FFFF_FFFFh или от FFFF_8000_0000_0000h до FFFF_FFFF_FFFF_FFFFh, т.е. как числа со знаком лежать в пределах от –2**47 до +2**47–1.

Источник

Организация виртуальной памяти

Что такое виртуальная адресация. Смотреть фото Что такое виртуальная адресация. Смотреть картинку Что такое виртуальная адресация. Картинка про Что такое виртуальная адресация. Фото Что такое виртуальная адресацияПривет, Хабрахабр!

В предыдущей статье я рассказал про vfork() и пообещал рассказать о реализации вызова fork() как с поддержкой MMU, так и без неё (последняя, само собой, со значительными ограничениями). Но прежде, чем перейти к подробностям, будет логичнее начать с устройства виртуальной памяти.

Конечно, многие слышали про MMU, страничные таблицы и TLB. К сожалению, материалы на эту тему обычно рассматривают аппаратную сторону этого механизма, упоминая механизмы ОС только в общих чертах. Я же хочу разобрать конкретную программную реализацию в проекте Embox. Это лишь один из возможных подходов, и он достаточно лёгок для понимания. Кроме того, это не музейный экспонат, и при желании можно залезть “под капот” ОС и попробовать что-нибудь поменять.

Введение

Любая программная система имеет логическую модель памяти. Самая простая из них — совпадающая с физической, когда все программы имеют прямой доступ ко всему адресному пространству.
При таком подходе программы имеют доступ ко всему адресному пространству, не только могут “мешать” друг другу, но и способны привести к сбою работы всей системы — для этого достаточно, например, затереть кусок памяти, в котором располагается код ОС. Кроме того, иногда физической памяти может просто не хватить для того, чтобы все нужные процессы могли работать одновременно. Виртуальная память — один из механизмов, позволяющих решить эти проблемы. В данной статье рассматривается работа с этим механизмом со стороны операционной системы на примере ОС Embox. Все функции и типы данных, упомянутые в статье, вы можете найти в исходном коде нашего проекта.

Будет приведён ряд листингов, и некоторые из них слишком громоздки для размещения в статье в оригинальном виде, поэтому по возможности они будут сокращены и адаптированы. Также в тексте будут возникать отсылки к функциям и структурам, не имеющим прямого отношения к тематике статьи. Для них будет дано краткое описание, а более полную информацию о реализации можно найти на вики проекта.

Общие идеи

Аппаратная поддержка

Обращение к памяти хорошо описанно в этой хабростатье. Происходит оно следующим образом:

Процессор подаёт на вход MMU виртуальный адрес
Если MMU выключено или если виртуальный адрес попал в нетранслируемую область, то физический адрес просто приравнивается к виртуальному
Если MMU включено и виртуальный адрес попал в транслируемую область, производится трансляция адреса, то есть замена номера виртуальной страницы на номер соответствующей ей физической страницы (смещение внутри страницы одинаковое):
Если запись с нужным номером виртуальной страницы есть в TLB [Translation Lookaside Buffer], то номер физической страницы берётся из нее же
Если нужной записи в TLB нет, то приходится искать ее в таблицах страниц, которые операционная система размещает в нетранслируемой области ОЗУ (чтобы не было промаха TLB при обработке предыдущего промаха). Поиск может быть реализован как аппаратно, так и программно — через обработчик исключения, называемого страничной ошибкой (page fault). Найденная запись добавляется в TLB, после чего команда, вызвавшая промах TLB, выполняется снова.

Таким образом, при обращении программы к тому или иному участку памяти трансляция адресов производится аппаратно. Программная часть работы с MMU — формирование таблиц страниц и работа с ними, распределение участков памяти, установка тех или иных флагов для страниц, а также обработка page fault, ошибки, которая происходит при отсутствии страницы в отображении.

В тексте статьи в основном будет рассматриваться трёхуровневая модель памяти, но это не является принципиальным ограничением: для получения модели с бóльшим количеством уровней можно действовать аналогичным образом, а особенности работы с меньшим количеством уровней (как, например, в архитектуре x86 — там всего два уровня) будут рассмотрены отдельно.

Программная поддержка

Виртуальный адрес

Page Global Directory (далее — PGD) — таблица (здесь и далее — то же самое, что директория) самого высокого уровня, каждая запись в ней — ссылка на Page Middle Directory (PMD), записи которой, в свою очередь, ссылаются на таблицу Page Table Entry (PTE). Записи в PTE ссылаются на реальные физические адреса, а также хранят флаги состояния страницы.

То есть, при трёхуровневой иерархии памяти виртуальный адрес будет выглядеть так:
Что такое виртуальная адресация. Смотреть фото Что такое виртуальная адресация. Смотреть картинку Что такое виртуальная адресация. Картинка про Что такое виртуальная адресация. Фото Что такое виртуальная адресация

Значения полей PGD, PMD и PTE — это индексы в соответствующих таблицах (то есть сдвиги от начала этих таблиц), а offset — это смещение адреса от начала страницы.

В зависимости от архитектуры и режима страничной адресации, количество битов, выделяемых для каждого из полей, может отличаться. Кроме того, сама страничная иерархия может иметь число уровней, отличное от трёх: например, на x86 нет PMD.

Для обеспечения переносимости мы задали границы этих полей с помощью констант: MMU_PGD_SHIFT, MMU_PMD_SHIFT, MMU_PTE_SHIFT, которые в приведённой выше схеме равны 24, 18 и 12 соответственно их определение дано в заголовочном файле src/include/hal/mmu.h. В дальнейшем будет рассматриваться именно этот пример.

На основании сдвигов PGD, PMD и PTE вычисляются соответствующие маски адресов.

Эти макросы даны в том же заголовочном файле.

Для работы с виртуальной таблицами виртуальной памяти в некоторой области памяти хранятся указатели на все PGD. При этом каждая задача хранит в себе контекст struct mmu_context, который, по сути, является индексом в этой таблице. Таким образом, к каждой задаче относится одна таблица PGD, которую можно определить с помощью mmu_get_root(ctx).

Страницы и работа с ними

Размер страницы

В реальных (то есть не в учебных) системах используются страницы от 512 байт до 64 килобайт. Чаще всего размер страницы определяется архитектурой и является фиксированным для всей системы, например — 4 KiB.

С одной стороны, при меньшем размере страницы память меньше фрагментируется. Ведь наименьшая единица виртуальной памяти, которая может быть выделена процессу — это одна страница, а программам очень редко требуется целое число страниц. А значит, в последней странице, которую запросил процесс, скорее всего останется неиспользуемая память, которая, тем не менее, будет выделена, а значит — использована неэффективно.

С другой стороны, чем меньше размер страницы, тем больше размер страничных таблиц. Более того, при отгрузке на HDD и при чтении страниц с HDD быстрее получится записать несколько больших страниц, чем много маленьких такого же суммарного размера.

В дальнейшем речь пойдёт о страницах обычного размера.

Устройство Page Table Entry

В реализации проекта Embox тип mmu_pte_t — это указатель.
Каждая запись PTE должна ссылаться на некоторую физическую страницу, а каждая физическая страница должна быть адресована какой-то записью PTE. Таким образом, в mmu_pte_t незанятыми остаются MMU_PTE_SHIFT бит, которые можно использовать для сохранения состояния страницы. Конкретный адрес бита, отвечающего за тот или иной флаг, как и набор флагов в целом, зависит от архитектуры.

Можно установить сразу несколько флагов:

Здесь vmem_page_flags_t — 32-битное значение, и соответствующие флаги берутся из первых MMU_PTE_SHIFT бит.

Трансляция виртуального адреса в физический

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

Для того, чтобы получить из виртуального адреса физический, необходимо пройти по цепочке таблиц PGD, PMD и PTE. Функция vmem_translate() и производит эти шаги.
Сначала проверяется, есть ли в PGD указатель на директорию PMD. Если это так, то вычисляется адрес PMD, а затем аналогичным образом находится PTE. После выделения физического адреса страницы из PTE необходимо добавить смещение, и после этого будет получен искомый физический адрес.

Пояснения к коду функции.
mmu_paddr_t — это физический адрес страницы, назначение mmu_ctx_t уже обсуждалось выше в разделе “Виртуальный адрес”.

С помощью функции vmem_get_idx_from_vaddr() находятся сдвиги в таблицах PGD, PMD и PTE.

Что такое виртуальная адресация. Смотреть фото Что такое виртуальная адресация. Смотреть картинку Что такое виртуальная адресация. Картинка про Что такое виртуальная адресация. Фото Что такое виртуальная адресация

Работа с Page Table Entry

Для работы с записей в таблице страниц, а так же с самими таблицами, есть ряд функций:

Эти функции возвращают 1, если у соответствующей структуры установлен бит MMU_PAGE_PRESENT

Page Fault

Page fault — это исключение, возникающее при обращении к странице, которая не загружена в физическую память — или потому, что она была вытеснена, или потому, что не была выделена.
В операционных системах общего назначения при обработке этого исключения происходит поиск нужной странице на внешнем носителе (жёстком диске, к примеру).

Выталкивание страниц во внешнюю память и их чтение в случае page fault не реализовано. С одной стороны, это лишает возможности использовать больше физической памяти, чем имеется на самом деле, а с другой — не является актуальной проблемой для встраиваемых систем. Нет никаких ограничений, делающих невозможной реализацию данного механизма, и при желании читатель может попробовать себя в этом деле 🙂

Выделение памяти

Для виртуальных страниц и для физических страниц, которые могут быть использованы при работе с виртуальной памятью, статически резервируется некоторое место в оперативной памяти. Тогда при выделении новых страниц и директорий они будут браться именно из этого места.
Исключением является набор указателей на PGD для каждого процесса (MMU-контексты процессов): этот массив хранится отдельно и используется при создании и разрушении процесса.
Выделение страниц
Итак, выделить физическую страницу можно с помощью vmem_alloc_page

Функция page_alloc() ищет участок памяти из N незанятых страниц и возвращает физический адрес начала этого участка, помечая его как занятый. В приведённом коде virt_page_allocator ссылается на участок памяти, резервированной для выделения физических страниц, а 1 — количество необходимых страниц.
Выделение таблиц
Тип таблицы (PGD, PMD, PTE) не имеет значения при аллокации. Более того, выделение таблиц производится также с помощью функции page_alloc(), только с другим аллокатором (virt_table_allocator).

Участки памяти (Memory Area)

После добавления страниц в соответствующие таблицы нужно уметь сопоставлять участки памяти с процессами, к которым они относятся. У нас в системе процесс представлен структурой task, содержащей всю необходимую информацию для работы ОС с процессом. Все физически доступные участки адресного пространства процесса записываются в специальный репозиторий: task_mmap. Он представляет из себя список дескрипторов этих участков (регионов), которые могут быть отображены на виртуальную память, если включена соответствующая поддержка.

brk — это самый большой из всех физических адресов репозитория, данное значение необходимо для ряда системных вызовов, которые не будут рассматриваться в данной статье.
ctx — это контекст задачи, использование которого обсуждалось в разделе “Виртуальный адрес”.
struct dlist_head — это указатель на начало двусвязного списка, организация которого аналогична организации Linux Linked List.

За каждый выделенный участок памяти отвечает структура marea

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

Отображение виртуальных участков памяти на физические (Mapping)

Ранее уже рассказывалось о том, как происходит выделение физических страниц, какие данные о виртуальной памяти относятся к задаче, и теперь всё готово для того, чтобы говорить о непосредственном отображении виртуальных участков памяти на физические.

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

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

В качестве параметров передаётся контекст задачи, адрес начала физического участка памяти, а также адрес начала виртуального участка. Переменная flags содержит флаги, которые будут установлены у соответствующих записей в PTE.

Основную работу на себя берёт do_map_region(). Она возвращает 0 при удачном выполнении и код ошибки — в ином случае. Если во время маппирования произошла ошибка, то часть страниц, которые успели выделиться, нужно откатить сделанные изменения с помощью функции vmem_unmap_region(), которая будет рассмотрена позднее.

Рассмотрим функцию do_map_region() подробнее.

Макросы GET_PTE и GET_PMD нужны для лучшей читаемости кода. Они делают следующее: если в таблице памяти нужный нам указатель не ссылается на существующую запись, нужно выделить её, если нет — то просто перейти по указателю к следующей записи.

В самом начале необходимо проверить, выровнены ли под размер страницы размер региона, физический и виртуальный адреса. После этого определяется PGD, соответствующая указанному контексту, и извлекаются сдвиги из виртуального адреса (более подробно это уже обсуждалось выше).
Затем последовательно перебираются виртуальные адреса, и в соответствующих записях PTE к ним привязывается нужный физический адрес. Если в таблицах отсутствуют какие-то записи, то они будут автоматически сгенерированы при вызове вышеупомянутых макросов GET_PTE и GET_PMD.

Освобождение виртуального участка памяти (Unmapping)

После того, как участок виртуальной памяти был отображён на физическую, рано или поздно её придётся освободить: либо в случае ошибки, либо в случае завершения работы процесса.
Изменения, которые при этом необходимо внести в структуру страничной иерархии памяти, производятся с помощью функции vmem_unmap_region().

Все параметры функции, кроме последнего, должны быть уже знакомы. free_pages отвечает за то, должны ли быть удалены страничные записи из таблиц.

try_free_pte, try_free_pmd, try_free_pgd — это вспомогательные функции. При удалении очередной страницы может выясниться, что директория, её содержащая, могла стать пустой, а значит, её нужно удалить из памяти.

нужны как раз для случая двухуровневой иерархии памяти.

Заключение

Конечно, данной статьи не достаточно, чтобы с нуля организовать работу с MMU, но, я надеюсь, она хоть немного поможет погрузиться в OSDev тем, кому он кажется слишком сложным.

Источник

Национальная библиотека им. Н. Э. Баумана
Bauman National Library

Персональные инструменты

Управление памятью в операционной системе

С понятием управления паметью в ОС связаны следующие технологии:

Содержание

Функции управления памятью в ОС

Операционная система решает следующие задачи:

Типы адресов

Для идентификации переменных и команд используются символьные имена (метки), виртуальные адреса и физические адреса.

Символьные имена

Символьные имена присваивает пользователь при написании программы.

Виртуальные адреса

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

Физические адреса

Физические адреса соответствуют номерам ячеек оперативной памяти, где в действительности расположены или будут расположены переменные и команды. Переход от виртуальных адресов к физическим может осуществляться двумя способами.

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

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

Методы распределения памяти в ОС

Выделяют следующие методы распределения памяти:

Источник

Большая Энциклопедия Нефти и Газа

Виртуальная адресация

Виртуальная адресация применяется для увеличения адресного пространства ПК при наличии ОП большой емкости ( простая виртуальная адресация) или при организации виртуальной памяти, в которую наряду с ОП включается и часть внешней ( обычно дисковой) памяти. При виртуальной адресации вместо начального адреса сегмента Лсегм в формировании абсолютного адреса Лабс принимает участие многоразрядный адресный код, считываемый из специальных таблиц. [1]

Принцип виртуальной адресации устранил трудности программирования, связанные с ограниченным объемом ОП, так как при виртуальной адресации в адресную область включается не только ОП, но и ВП на НМД. [2]

Управление виртуальной адресацией ( или обращениями к различным объектам) заключается в предоставлении процедурам определенных возможностей, задании имен для ссылок на объекты и проверки полномочий доступа. Указанные функции выполняются вне всякой связи с процессом переадресации. [3]

Микропроцессор 80386 имеет два режима работы: реальной адресации и виртуальной адресации с защитой. [7]

Кроме того, при любом объеме до 124 кслов осуществляется страничная организация с виртуальной адресацией и защитой памяти. [8]

Виртуальная адресация применяется для увеличения адресного пространства ПК при наличии ОП большой емкости ( простая виртуальная адресация ) или при организации виртуальной памяти, в которую наряду с ОП включается и часть внешней ( обычно дисковой) памяти. При виртуальной адресации вместо начального адреса сегмента Лсегм в формировании абсолютного адреса Лабс принимает участие многоразрядный адресный код, считываемый из специальных таблиц. [9]

Принцип виртуальной адресации устранил трудности программирования, связанные с ограниченным объемом ОП, так как при виртуальной адресации в адресную область включается не только ОП, но и ВП на НМД. [10]

Принцип виртуальной адресации устранил трудности программирования, связанные с ограниченным объемом ОП, так как при виртуальной адресации в адресную область включается не только ОП, но и ВП на НМД. [11]

Виртуальная адресация применяется для увеличения адресного пространства ПК при наличии ОП большой емкости ( простая виртуальная адресация) или при организации виртуальной памяти, в которую наряду с ОП включается и часть внешней ( обычно дисковой) памяти. При виртуальной адресации вместо начального адреса сегмента Лсегм в формировании абсолютного адреса Лабс принимает участие многоразрядный адресный код, считываемый из специальных таблиц. [12]

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *