---
# System prepended metadata

title: Memory Mapping

---

# Memory Mapping

## Принцип работы кратко

Отображение содержимого файла ( так-то не только файлов ) на виртуальное адресное пространство процесса 

## Зачем?

+ Ускорить работу с файлами, так как операции чтения и записи с диска медленные
+ Не копировать каждый раз в RAM содержимое используемых процессами файлов 

## Что значит отображение?

Адресам виртуальной памяти ставится в соответствие файл, устройство или анонимный регион памяти ( `MAP_ANONYMOUS` ). Таким образом, чтение и запись по этим адресам, соответствует чтению и запись в файл, устройство или заполнение анонимного региона.

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

__Виртуальное адресное пространство__ — это множество диапазонов виртуальных адресов, которые ОС делает доступными для каждого процесса. Данные диапазон зависит в первую очередь от архитектуры системы команд ( hardware ) и возможностью поддержки Операционной системой ( Software ), а именно размером ее указателей.
Таким образом, если размер указателя равен 64-бит, то диапазон адресов доступных каждому процессу равен $[ 0; 2^{64} - 1 ]$.

## Что можно отобразить?

1. __Файл__, тогда региону ставится в соответствии i-node этого файла
    + `/usr/bin/bash`
    + `/usr/lib/x86_64-linux-gnu/libc2.31.so`
2. __Устройство__, тогда региону ставится в соответствии i-node ( так как на \*NIX, устройства тоже файлы ). Например, `/dev/urandom`, `/dev/random`, `/dev/zero`.
3. Отображаются также __анонимные регионы__ такие как __стэк__ или __куча__ `( stack, heap )`.

## Когда подгрузится содержимое отображенного

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

Т.н. "lazy loading" или "demand paging"

## Кто и как подгружает содержимое отображенного

1. Когда происходит обращение по виртуальным адресам, к которым в соответствие не было сопоставлено физического адреса, MMU генерирует исключение `Page Fault ( Page Fault )`. Вызывается обработчик данного исключения, проваливаемся в kernel-space.
2. Затем ОС начинает выяснять: какая виртуальная страница нужна
    1. Либо она выясняет это с помощью специального аппаратного регистра
    2. Либо берет инструкцию по значению регистру rip и разбирает ее, чтобы узнать к какой странице произошло обращение
3. Когда виртуальный адрес определен, происходит проверка этого адреса на валидность (?) и его флаги защиты `( PROT_READ, PROT_WRITE, PROT_EXEC, PROT_NONE )`
4. Если проверку прошли, то проверяем, если свободен page frame. __Отступление:__
    + __физическая память ( RAM ), состоит из `page frames`, размер которых зависит от системы и часто это степень двойки в байтах__
    + __просто `pages`, это то из чего состоит виртуальная память, и размер которых зависит от архитектуры процессора `( PowerPC, IA32, x86, x86_64, IA64, amd64, SPARC, MIPS )`__
5. Если нету свободных page frames, то запускается frame replacement algorithm, которые заменяет ненужные страницы. Основные стратегии замены:
    + __FIFO__ — first-in-first-out
    + __LRU__ — least-recently-used
    + __Optimal Page Replacement__ — заменяются те, которые в долгой перспективе будут не нужны ( как в задаче про Машинки на контесте: алгоритмы 2021 )
6. Если алгоритм избрал страницу, которая была модифицирована, то инициируется ее запись на диск в swap-файл. Контекст исполнения меняется. Обработка PF прерывается. Другой процесс начинает исполняться, пока запись на диск не будет завершена.
7. Как только мы освободили __page frame__ ( !физическая память ), ОС инициирует чтение файла с диска, чтобы занять освободившийся page frame.
8. Когда страница подгружена, обновляются таблицы страниц в MMU, в соответствии с текущим состоянием виртуальной памяти
9. Возвращаемся из обработчика.
10. Восстанавливаем состояние до исключения. Продолжаем работу как ни в чем не бывало в user-space.