Пришло время начать писать менеджер памяти - важнейший компонент любой операционной системы. Однако до его реализации в коде почему-то не дошла ни одна из известных мне рассылок.
Напишем заголовочный файл memory_manager.h, обозначив задачи на этот выпуск:
Помимо описания функций в этом файле есть и описания адресов и размеров некоторых структур работы с виртуальной памятью, а также некоторые доступные флаги для проекции страниц (PAGE_VALID - обязательный флаг, PAGE_WRITABLE - страница доступна для записи, PAGE_USER - страница доступа для непривилегированного кода).
Начнём писать memory_manager.c с простой функции инициализации:
Эта функция сохраняет текущее значение CR3 в переменную kernel_page_dir (потом нам пригодится для вызова map_pages), а также интерпретирует карту памяти, полученную когда-то от BIOS. Для всех блоков памяти, которые выше 1-ого мегабайта, а также доступны для использования (тип 1) вызывается функция free_phys_pages, которая должна помечать указанный регион физической памяти как свободный. Параллельно с этим init_memory_manager вычисляет полный объём оперативной памяти, который будет доступен в глобальной
переменной memory_size.
Теперь напишем пару маленьких функций, одна из которых полезна для других модулей, а вторая вообще будет одной из самых часто используемых:
Самая главная функция - temp_map_page - она позволяет спроецировать любую физическую страницу по адресу TEMP_PAGE, через это "окно" многие другие функции обращаются к неспроецированным страницам, как это работает мы очень скоро увидим. Вторая функция нужна другим модулям, чтобы получить размер свободной незанятой памяти в байтах, а не страницах.
После того как написана функция temp_map_page, мы можем сделать и две других - map_pages и get_page_info. Первая позволяет спроецировать указанный
блок физических страниц по нужному виртуальному адресу, а вторая узнать куда же будет отображён виртуальный адрес и отображён ли он.
Теперь у нас есть функции для проецирования страниц в виртуальное адресное пространство, а также для получения информации о виртуальной странице. Хотя пока у нас нет функций для выделения и освобождения физических страниц, map_pages и get_page_info уже будут работать, пока нет необходимости создавать новую таблицу страниц (то есть мы можем проецировать страницы в первые и последние 4 МБ).
Управление физическими страницами требует отдельного обсуждения и если менеджер физической памяти описать
в этом же выпуске, он получится слишком большим, поэтому пока сделаем лишь функции-заглушки, а полный код рассмотрим в следующий раз: