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

Содержание
  1. Виртуальная память компьютера: что такое, как устроена, как увеличить
  2. Что такое виртуальная память?
  3. Как работает виртуальная память?
  4. Как организована виртуальная память?
  5. Как увеличить виртуальную память?
  6. Виртуальная память: Что это и как ее увеличить?
  7. Что такое виртуальная память?
  8. Как узнать объем файла подкачки (swap file)
  9. Dump File и его типы
  10. Как изменить Dump File
  11. Как изменить объем виртуальной памяти через быстродействие
  12. Как добавить виртуальную память на Windows
  13. Рекомендации по использованию виртуальной памяти
  14. Виртуальная память или файл подкачки
  15. Что на самом деле может виртуальная память
  16. Как это работает
  17. Отображение адресов «один в один» (Identity Mapping)
  18. Рекурсивное отображение (Recursive Mapping)
  19. Отображение на одну страницу (Everything Mapped to the Same Page)
  20. Страничные нарушения (Page Faults Everywhere)
  21. Переключение контекста между двумя процессами (Context Switching Between 2 Processes)
  22. Решение проблемы внешней фрагментации (Solving External Fragmentation)
  23. Копирование при записи (Copy-On-Write)
  24. Эксперимент со страницами
  25. Вызов функции с помощью констант
  26. Организация виртуальной памяти
  27. Введение
  28. Общие идеи
  29. Аппаратная поддержка
  30. Программная поддержка
  31. Виртуальный адрес
  32. Страницы и работа с ними
  33. Размер страницы
  34. Устройство Page Table Entry
  35. Трансляция виртуального адреса в физический
  36. Работа с Page Table Entry
  37. Page Fault
  38. Выделение памяти
  39. Участки памяти (Memory Area)
  40. Отображение виртуальных участков памяти на физические (Mapping)
  41. Освобождение виртуального участка памяти (Unmapping)
  42. Заключение

Виртуальная память компьютера: что такое, как устроена, как увеличить

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

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

virtualnaya pamyat m

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

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

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

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

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

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

virtualnaya pamyat 1 m

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

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

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

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

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

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

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

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

Если вы хотите увеличить объем виртуальной памяти на своей системе, то ознакомьтесь с пошаговой инструкцией. (Для Windows XP):

virtualnaya pamyat 2 m

    Откройте меню «Пуск», выберите команду «Панель управления» Выберите пункт «Производительность и обслуживание» Далее выберите «Система» Выбираем вкладку «Дополнительно» Выбираем секцию «Быстродействие» и нажимаем кнопку Параметры Выбираем вкладку «Дополнительно» В секции «Виртуальная память» нажимаем на кнопку «Изменить» В списке Диск [метка тома] выберите диск, содержащий файл подкачки, если вы хотите изменить размер его виртуальной памяти. Вы можете выбрать объем памяти, который хотите зарезервировать для виртуальной памяти, введя начальный и максимальный размер. Нажмите кнопку «Задать» Перезагрузите компьютер

Если вам кажется, что ваш компьютер работает слишком медленно, то увеличение виртуальной памяти не поможет, это может быть только результатом «пробуксовки». Слишком частая перетасовка блоков виртуальной памяти между реальной памяти и дисков потребляет большую часть времени работы компьютера, тем самым вызывая пробуксовку. Хотя и существует некоторые меры, оптимизирующие работу виртуальной памяти, все же лучшим решением будет увеличение объема оперативной памяти.

Источник

Виртуальная память: Что это и как ее увеличить?

jpg

Виртуальная память — что это?

Виртуальная память является подкачкой (дополнением) оперативной памяти. Она присутствует практически во всех операционных системах.

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

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

Виртуальная память (Virtual Memory, ВП) — это метод управления памятью компьютера, использующий для работы файл подкачки (swap file). При недостатке существующего объема ОЗУ, позволяет запускать на ПК более ресурсозатратные программы. В таком случае данные приложения автоматически перемещаются между основной памятью и вторичным хранилищем.

Виртуальная память так же обладает рядом достоинств:

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

Как узнать объем файла подкачки (swap file)

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

jpg

Размер свапа подкачки можно узнать через штатную утилиту «Системный монитор».

Для этого:

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

Dump File и его типы

Swap используется не только для расширения физической памяти, но и для создания аварийных дампов при возникновении «внештатных» аварийных ситуаций.

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

Таким образом при автоматическом выборе размера свапа, Windows руководствуется настройками для создания аварийного дампа.

jpg

Загрузка и восстановление

Дампы можно разделить на 4 типа:

В него записывается все содержимое RAM на момент незапланированного завершения работы. С учетом этой информации файл подкачки должен иметь размер равный физической памяти компьютера +1 МБ (используется для создания записи в системном журнале).

В него записывается только информация и память, выделенная для ядра операционной системы. Он занимает сравнительно меньше места и его объема достаточно, чтобы Windows могла определить причины аварийного завершения работы.

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

Доступен только для операционных систем семейства Windows начиная от восьмерки и выше, либо Server 2012. Представляет собой аналог дампа ядра, но с тем отличием, что система может постоянно менять размер файла подкачки, позволяя ей выбирать оптимальный для работы вариант.

Как изменить Dump File

Перед тем, как менять размер виртуальной памяти, необходимо правильно определить и выбрать тип дампа. Сделать это можно используя штатные инструменты Windows. Для этого выполните следующие действия:

jpg

png

Загрузка и восстановление

Как изменить объем виртуальной памяти через быстродействие

Запустите системную утилиту «Выполнить» одновременным нажатием клавиш Windows+R или откройте ее через Пуск. После этого:

jpg

jpg

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

Как добавить виртуальную память на Windows

Как правило, среднестатистическому пользователю достаточно того объема ВП, которая выделяется устройством автоматически. Если на ПК мало физической RAM, то увеличить ее объем можно за счет свапа.

Для этого:

jpg

jpg

Рекомендации по использованию виртуальной памяти

jpg

Если вы не знаете, какой оптимальный объем для свапа выбрать и на что это будет влиять, то далее мы предлагаем ознакомиться вам с небольшими советами, которые помогут увеличить быстродействие ПК.

Итак, рассмотрим ряд советов:

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

Так же подробно про ВП можно посмотреть в видеоролике ниже:

Виртуальная память или файл подкачки

В видео рассматривается оптимальный размер файла подкачки

Сегодня мы ответили на вопрос «Виртуальная память, что это? И для чего она нужна?». Она помогает значительно повысить быстродействие системы и используется для хранения информации при сбоях. По умолчанию объем файла подкачки регулируется Windows полностью в автоматическом режиме.

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

Понравилась статья? Подпишитесь на канал, чтобы быть в курсе самых интересных материалов

Источник

Что на самом деле может виртуальная память

image loader

Мы в 1cloud стараемся рассказывать о различных технологиях — например, контейнерах, SSL или флеш-памяти.

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

Примечание: Исходный материал содержит большое количество сложных терминов и технологических описаний, поэтому если вы обнаружили какую-то ошибку или неточность — напишите нам личным сообщением, чтобы мы могли внести правки и сделать материал лучше.

Занявшись обновлением собственного компилятора C и написанием спецификации CPU Элдер понял, что с виртуальной памятью связано очень много вопросов, которые до конца не понятны начинающим разработчикам. По этой причине он решил написать свое интерактивное пособие.

Прежде чем переходить к статье Элдера, можете посмотреть видео, на котором Джейсон Питт (Jason Pitt) рассказывает о том, что такое виртуальная память.

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

Элдер создал на своем сайте таблицу с физическим и виртуальным представлениями 256-байтного адресного пространства. Ниже представлен скриншот этой таблицы. Интерактивная версия доступна в блоге инженера по этой ссылке.

image loader

Обозначения, встречающиеся в интерактивной таблице Элдера:

0x0 Это указатель на страничную структуру верхнего уровня. На машинах Intel это значение хранится в регистре CR3. С ARM все немного сложнее.
image loader Первая страничная структура. При двухуровневой организации таблиц часто называется «директорией» страниц. В нашем случае каждая запись в директории занимает 8 бит (1 байт) и содержит информацию о месторасположении таблицы страниц.
image loader Вторая страничная структура – это так называемая таблица страниц (page table). Каждая запись содержит информацию о расположении физической страницы.
image loader Физическая страница, с которой в настоящий момент ведется работа.
image loader Активная запись директории страниц или таблицы страниц.
image loader Выбранное расположение в памяти.
image loader Память, доступная для чтения (Readable Memory). В данном примере разрешения не анализируются, однако в реальной системе будет осуществляться проверка бита на соответствие требуемому методу доступа.
image loader Память, доступная для записи (Writeable Memory).
image loader Память, для которой разрешено выполнение (Executable Memory).
image loader Недоступная виртуальная память (Inaccessible Virtual Memory).
image loader Неинициализированная физическая память (Unitialised Physical Memory). К ней нельзя обратиться через адресное пространство виртуальной памяти – это вызовет страничное нарушение.
image loader Недоступная физическая память (Inaccessible Physical Memory). Участки памяти, к которым нельзя получить доступ.

Отображение адресов «один в один» (Identity Mapping)

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

Рекурсивное отображение (Recursive Mapping)

Чтобы управлять памятью, нужно знать, где в физической памяти располагаются страничные структуры. Когда блок управления памятью (MMU) начинает работу, вы можете взаимодействовать напрямую только с адресами виртуальной памяти. По этой причине отслеживать физические адреса бывает очень трудно.

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

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

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

Отображение на одну страницу (Everything Mapped to the Same Page)

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

Страничные нарушения (Page Faults Everywhere)

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

Переключение контекста между двумя процессами (Context Switching Between 2 Processes)

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

Решение проблемы внешней фрагментации (Solving External Fragmentation)

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

Из этой ситуации есть два выхода:

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

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

Копирование при записи (Copy-On-Write)

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

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

Эксперимент со страницами

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

Вот, что он получил на выходе:

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

Вызов функции с помощью констант

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

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

На выходе по-прежнему имеем число 37.

Источник

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

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

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

То есть, при трёхуровневой иерархии памяти виртуальный адрес будет выглядеть так:
image loader

Значения полей 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.

image loader

Работа с 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 тем, кому он кажется слишком сложным.

Источник

Поделиться с друзьями
DOMA35.RU