# 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.