Отображение виртуальной памяти в реальную кратко

Обновлено: 04.07.2024

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

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

Из этого руководства по операционной системе вы узнаете:

Зачем нужна виртуальная память?

Вот причины использования виртуальной памяти:

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

Как работает виртуальная память?

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

Таким образом, в этом случае вместо предотвращения входа страниц в основную память, ОС ищет пространство ОЗУ, минимально используемое в последнее время или на которое не ссылаются во вторичной памяти, чтобы освободить место для новых страниц в основная память.

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

Например:

Давайте предположим, что ОС требуется 300 МБ памяти для хранения всех запущенных программ. Однако в настоящее время в оперативной памяти хранится только 50 МБ доступной физической памяти.

  • Затем ОС установит 250 МБ виртуальной памяти и будет использовать программу, называемую Virtual Memory Manager (VMM), для управления этими 250 МБ.
  • Таким образом, в этом случае VMM создаст на жестком диске файл размером 250 МБ для хранения дополнительной необходимой памяти.
  • Теперь ОС перейдет к адресной памяти, поскольку она считает 300 МБ реальной памяти, хранящейся в ОЗУ, даже если доступно только 50 МБ.
  • Работа VMM заключается в управлении 300 МБ памяти, даже если доступно только 50 МБ реальной памяти.

Что такое пейджинг по требованию?


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

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

Во время выполнения программы, если программа ссылается на страницу, которая может быть недоступна в основной памяти, поскольку она была заменена, то процессор считает ее недопустимой ссылкой на память. Это происходит из-за сбоя страницы и передачи управления обратно из программы в ОС, что требует сохранения страницы обратно в память.

Типы методов замены страниц

Вот несколько важных методов замены страниц

  • ФИФО
  • Оптимальный алгоритм
  • Замена страницы LRU

Замена страницы FIFO

Особенности:

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

Оптимальный алгоритм

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

Особенности:

  • Оптимальный алгоритм приводит к наименьшему количеству ошибок страниц. Этот алгоритм сложно реализовать.
  • Оптимальный метод алгоритма замены страниц имеет наименьшую частоту ошибок страниц среди всех алгоритмов. Этот алгоритм существует и который должен называться MIN или OPT.
  • Замените страницу, которую не хотите использовать в течение более длительного периода времени. Используется только время, когда страница должна быть использована.

Замена страницы LRU

Как это работает?

Особенности:

Частота отказов

Частота отказов — это частота, с которой отказывает разработанная система или компонент. Это выражается в сбоях за единицу времени. Обозначается греческой буквой λ (лямбда).

Модуль 5. Управление основной памятью

Тема 9. Понятие виртуальной памяти

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

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

Итак, виртуальной памятью называется основная память процесса, адресное пространство которого соответствует диапазону непосредственной адресации системы команд ЭВМ и которая обычно не совпадает с объемом реальной памяти ЭВМ.

EC ЭВМ> 24 разрядами адресует 16 Мб памяти машины.

Операционная система позволяет одновременно работать N процессов > N* 16 мб.

Начиная с Intel 386 (32 разрядные МП) – для каждого процесса выделяет адресное пространство размером 4 Gb. Одновременно работает N процессов > N* 4 Gb.

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

1.Обеспечить возможность создания и выполнения на ЭВМ программ максимально допустимого размера.

2.Облегчить жизнь программиста, сняв с него проблемы, связанные с ограниченным объемом РОП.

3.Устранить временную фрагментацию, максимально эффективно используя ОП ЭВМ, которая образуется при отсутствии необходимого участка программы/данных в РОП и определяется временем, необходимым для размещения необходимых данных в РОП.

Суть концепции виртуальной памяти (ВП) заключается в том, что адресное пространство (АП) процесса отделяется от адресов реальной оперативной памяти (РОП) и по необходимости динамически и по частям отображается в реальную память.

В ОС с реальной ОП привязка адресного пространства к реальным адресам осуществляется статически до выполнения программы на все время выполнения.

В ВС с виртуальной памятью адресное пространство (АП) процесса (образ процесса) во время выполнения хранится во внешней памяти ЭВМ и загружается в реальную память по частям динамически по необходимости в любое свободное место РОП. Однако программа ничего не знает об этом, написана и выполняется так, как будто полностью находится в РОП.

Виртуальная память - это моделирование оперативной памяти во внешней памяти.

Механизм отображения виртуальных и реальных адресов устанавливает между ними соответствие и называется динамическим преобразованием адресов (ДПА).

Компьютер здесь уже выступает как логическое устройство, а не физическая машина с уникальными характеристиками. ДПА поддерживается на аппаратно-микропрограммном уровне. В МП Intel, начиная с 386 процессора, выполняется поддержка виртуальной памяти.

Такая процедура выполняется для EC ЭВМ - ряд 2 и выше, для СМ ЭВМ- 1700, для IBM PC – I386 и выше.

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

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

Рисунок 1. Динамическое преобразование адресов

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

Еще один вопрос, который необходимо решать: Каким сделать размер блока?

Увеличение размера блока приводит к уменьшению размера таблицы отображения блоков, но увеличивает время обмена и, наоборот, уменьшение размера блока приводит к увеличению таблиц и уменьшению времени обмена с внешней памятью.

Блоки могут быть фиксированного размера (страницы) и переменного размера (сегменты). В этой связи существует четыре способа организации виртуальной памяти:

1.Динамическая страничная организация.

3.Комбинированная сегментно-страничная организация.

4.Двухуровневая страничная организация.

Виртуальные адреса в страничных и сегментных системах являются двухкомпонентными и представляют собой упорядоченную пару (p,d), где p - номер блока (страницы либо сегмента), в которой размещается элемент, а d - смещение относительно начального адреса этого блока. Преобразование виртуального адреса V=(p,d) в адрес реальной памяти r осуществляется следующим образом. При активизации очередного процесса в специальный регистр процессора загружается адрес таблицы отображения блоков данного процесса. В соответствии с номером блока p из таблице отображения блоков, считывается строка, в которой устанавливается соответствие между номерами виртуальных и физических страниц для страниц, загруженных в оперативную память, или делается отметка о том, что виртуальная страница выгружена на диск. Кроме того, в таблице страниц содержится управляющая информация, такая как признак модификации страницы, признак невыгружаемости (выгрузка некоторых страниц может быть запрещена), признак обращения к странице (используется для подсчета числа обращений за определенный период времени) и другие данные, формируемые и используемые механизмом виртуальной памяти. К считанному физическому адресу размещения выбранного блока добавляется размер смещения d и вычисляется требуемый реальный адрес.

Рисунок 2. Преобразование виртуального адреса в реальной адрес памяти

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

Стратегия вталкивания, определяющая, когда следует переписать страницу или сегмент из внешней памяти в ОП.

а) вталкивание по запросу - система ожидает ссылки на страницу/сегмент от выполняющегося процесса (прерывание по отсутствию страницы);

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

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

Достоинство: сокращается время ожидания.

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

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

Стратегия выталкивания (замещения), определяющая, какую страницу/сегмент удалить из ОП для освобождения места поступающей страницы.

Здесь основная проблема "пробуксовки", при которой вытолкнутая страница в следующий момент должна вновь размещаться в РОП.

Рассмотрим процедуры определения блоков для выталкивания из ОП.

а) выталкивание случайной страницы - в реальных системах не применяется;

б) выталкивание первой пришедшей страницы (FIFO - очередь). Для ее реализации необходимо устанавливать временные метки страниц.

Аргумент: у страницы уже были возможности использовать свой шанс.

Фактически: большая вероятность заместить активно используемые страницы, поскольку нахождение страниц длительное время может означать, что она постоянно в работе. Например, используемый редактор текстов.

в) выталкивание дольше всего неиспользованных страниц.

Для реализации необходимо реализовать обновляемые временные метки. Эвристический аргумент: - недавнее прошлое - хороший ориентир на будущее.

Недостаток - существенные издержки: постоянное обновление временных меток.

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

д) выталкивание не использующихся в последнее время страниц - самый распространенный алгоритм с малыми издержками. Реализуется двумя аппаратными битами на страницу:

1.признак обращения 0 - было

2.признак модификации записи 0 - неизменен.

Возможны следующие варианты комбинаций 00,10,01,11>. Если изменений на странице не было, то страницу можно просто переписать, а не сохранять на диске.


Привет, Хабрахабр!

В предыдущей статье я рассказал про 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 быстрее получится записать несколько больших страниц, чем много маленьких такого же суммарного размера.

Отдельного внимания заслуживают так называемые большие страницы: huge pages и large pages [вики] .

Платформа Размер обычной страницы Размер страницы максимально возможного размера
x86 4KB 4MB
x86_64 4KB 1GB
IA-64 4KB 256MB
PPC 4KB 16GB
SPARC 8KB 2GB
ARMv7 4KB 16MB

Действительно, при использовании таких страниц накладные расходы памяти повышаются. Тем не менее, прирост производительности программ в некоторых случаях может доходить до 10% [ссылка] , что объясняется меньшим размером страничных директорий и более эффективной работой TLB.

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

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

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

  • MMU_PAGE_WRITABLE — Можно ли менять страницу
  • MMU_PAGE_SUPERVISOR — Пространство супер-пользователя/пользователя
  • MMU_PAGE_CACHEABLE — Нужно ли кэшировать
  • MMU_PAGE_PRESENT — Используется ли данная запись директории

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

Здесь 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 — это исключение, возникающее при обращении к странице, которая не загружена в физическую память — или потому, что она была вытеснена, или потому, что не была выделена.
В операционных системах общего назначения при обработке этого исключения происходит поиск нужной странице на внешнем носителе (жёстком диске, к примеру).

В нашей системе все страницы, к которым процесс имеет доступ, считаются присутствующими в оперативной памяти. Так, например, соответствующие сегменты .text, .data, .bss; куча; и так далее отображаются в таблицы при инициализации процесса. Данные, связанные с потоками (например, стэк), отображаются в таблицы процесса при создании потоков.

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

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

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

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

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

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


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

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

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

Подразумевается, что некоторый участок физической памяти уже выделен. Для того, чтобы выделить соответствующие виртуальные страницы и привязать их к физическим, используется функция 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.

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

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

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


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

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

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

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

Содержание

История появления

В 1940-ых и 50-ых все крупные программы должны были реализовывать логику управления памятью - оверлеи. Виртуальная предназначалась не только, чтобы расширить реальную оперативную память, но и облегчить использование памяти программистам. [Источник 1] .Чтобы использовать мультипрограммирование и многозадачность многие ранние системы разделяли память между множеством программ без использования виртуальной памяти (например ранние модели PDP-10 через регистры).

Концепция виртуальной памяти впервые была разработана немецким физиком Fritz-Rudolf Güntsch в Берлинском техническом университете в его докторской диссертации "Логическое построение цифровых компьютеров несколькими асинхронными вращающимеся барабанами и автоматическими высокоскоростными операциями с памятью" (англ. Logical Design of a Digital Computer with Multiple Asynchronous Rotating Drums and Automatic High Speed Memory Operation ). В диссертации описывалась машина с 6 блоками по 100 машинным слов основной памяти и адресное пространство из 1000 блоков по 100 машинных слов, с специальными аппаратными средствами автоматические перемещающие блоки между основной и вторичной памятью. Подкачка страниц впервые была реализована в Манчестерском университете как способ расширить реальную оперативную память компьютера Atlas совместив 16 тысяч слов основной памяти с дополнительными 96 тысячами слов вторичной памяти. Первый Atlas был введён в эксплуатацию в 1962-ом году, но рабочие прототипы подкачки страниц были реализованы к 1959-му году. [Источник 2] [Источник 3] В 1961-ом году, Burroughs Corporation самостоятельно выпустила первый коммерческий компьютер с виртуальной памятью - B5000, с сегментной адресацией памяти, но без подкачки страниц.

Перед тем как виртуальная память могла быть реализована в основным популярных операционных системах, много проблем должны были быть решены. Динамическая трансляция адресов требовала дорогого и трудно реализуемого специализированного оборудования (первые реализации несколько замедляли доступ к памяти). Так же существовало беспокойство, что новые общесистемные алгоритмы будут не так эффективно использовать вторичную память, как ранее используемые специальные алгоритмы реализуемые каждым приложением в отдельности. В 1969-ом году дебаты касающиеся использования виртуальной памяти в коммерческих компьютерах закончились, исследовательская команда IBM, возглавляемая David Sayre показала, что их система виртуальной памяти работает лучше, чем любая управляемая вручную система. Первый миникомпьютер использующий виртуальную память был Норвежский NORD-1, в течении 1970-ых годов, появились другие компьютеры реализующие виртуальную память (например компьютер VAX с системой VMS).

Виртуальная память была реализована в архитектуре x86 вместе с |защищённым режимом в процессоре Intel 80286, но его способ подкачки сегментов плохо масштабировался для сегментов большего размера. В процессор Intel 80386 была реализована подкачка страниц под существующем слоем сегментации, позволяя исключение подкачки страниц связывать с другими исключениями не вызывая двойного сбоя. Однако, загрузка дескриптора сегмента была дорогостоящей операции, в результате чего, разработчики операционных систем полагались только на подкачку страниц, а не на комбинацию сегментации и подкачки страниц. [Источник 4]

Преимущества виртуальной памяти

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

Способы организации памяти

Страничный способ

Страничная память — способ организации памяти, при котором единицей отображения виртуальных адресов на физические является регион постоянного размера (т. н. страница). Типичный размер страницы — 4096 байт, для некоторых архитектур — до 128 КБ.
Основным достоинством страничного способа распределения памяти является минимально возможная фрагментация. Поскольку на каждую задачу может приходиться по одной незаполненной странице, то становится очевидно, что память можно использовать достаточно эффективно; этот метод организации виртуальной памяти был бы одним из самых лучших, если бы не два обстоятельства:

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

Решаемые задачи

Сегментный способ

Сегментная адресация памяти — схема логической адресации памяти компьютера в архитектуре x86. Линейный адрес конкретной ячейки памяти, который в некоторых режимах работы процессора будет совпадать с физическим адресом, делится на две части: сегмент и смещение. Сегментом называется условно выделенная область адресного пространства определённого размера, а смещением — адрес ячейки памяти относительно начала сегмента. Базой сегмента называется линейный адрес (адрес относительно всего объёма памяти), который указывает на начало сегмента в адресном пространстве. В результате получается сегментный (логический) адрес, который соответствует линейному адресу база сегмента+смещение и который выставляется процессором на шину адреса.

Достоинства сегментного способа

Недостатки сегментного способа

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

Подкачка страниц

Практические все реализации виртуальной памяти делят виртуальное адресное пространство на страницы: блоки непрерывных виртуальных адресов. Размер страницы на современной системе обычно не меньше 4 килобайт, системы с большим диапазоном виртуальных адресов или количеством реальной оперативной памяти обычно используют более большие размеры страниц.

Таблица страниц

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

В операционной системе может быть одна таблица страниц, по таблице страниц на каждое приложение или сегмент, дерево таблиц страниц для больших сегментов или комбинация перечисленного.

Супервизор страниц

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

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

Закреплённые страницы

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

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

  • Код супервизора страниц и драйвера доступа к вторичной памяти (на котором находятся страницы), должен быть постоянно закреплён, иначе подкачка страниц не может не работать, так как необходимый код будет недоступен.
  • Компоненты сильно зависимые от времени, должны быть закреплены, чтобы избежать задержек.
  • Буферы данных, напрямую обращающиеся к периферийным устройствам, которые используют прямой доступ к памяти или каналы ввода/вывода должны находится в закреплённых страницах, во время операций с вводом/выводом, потому что устройства ожидают, что буферы расположены в реальной оперативной памяти. Передача информации с устройства не может быть остановлена в случае исключения ошибки страниц, и перезапущена позже.

V=R режим

В OS/VS1 и похожих операционных системах, некоторые части системной памяти работают в режиме "Virtual-Real", часто сокращаемый до "V=R". В этом режиме каждый виртуальный адрес соответствует такому же реальному адресу. Этот режим используется для механизма прерываний, для супервизора страниц и таблицы страниц в старых операционных системах, и для приложений использующих не стандартное управление вводом/выводом.

Пробуксовка

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

Читайте также: