Пишем свою операционную систему Менеджер виртуальной памяти
В этом выпуске мы наконец-то реализуем менеджер виртуальной памяти, который знает не только "что спроецировать", но и "куда спроецировать". Его реализацию на текущий момент можно считать черновой (в отличии от менеджера физической памяти) и безупречную работу я гарантировать не могу.
Теперь следует усовершенствовать код memcpy, чтобы он полностью корректно обрабатывал перекрывающиеся блоки памяти (ошибки в коде нет, просто реализация была упрощённой):
Все таблицы блоков хранятся в адресном пространстве ядра. При необходимости они могут расширяться (по сути это динамический массив). Выделение адресов начинается с конца адресного пространства. Почти полностью реализована обработка ошибок выделения памяти (для личных адресных пространств процессов полностью, для адресного пространства ядра - нет).
Ну и наконец добавим в конец функции init_memory_manager инициализацию структуры адресного пространства ядра:
Вот и всё! Теперь у нас есть относительно полноценный менеджер памяти (не хватает только реализации подкачки памяти и выделения блоков произвольного размера, а не только кратного размеру страницы, однако первое нам пока делать рано, а второе можно переложить на плечи прикладных программ, если писать микроядро).
Замечание по использованию менеджера памяти:
1) Как я уже сказал обработка нехватки виртуальных адресов для адресного пространства ядра реализована не полностью. Список блоков
растёт с начала адресного пространства, а адреса выделяются с конца. То, что они встретятся крайне маловероятно, но всё же возможно. В данном случае ошибки выделения памяти не случится - список блоков "наедет" на самый нижний блок памяти и это приведёт к непредсказуемым последствиям. А вот защита от обратной ситуации реализована - менеджер памяти никогда не выделит блок памяти, который бы пересекался со списком блока, проблема лишь в том, когда последний начинает расти. В общем, будте осторожны, хотя
и вряд ли наткнётесь на эту проблему.
2) В init_memory_manager, init_interrupts и init_tty я не произвожу проверку успешности выделения оперативной памяти, потому что вряд ли нашу ОС запустят на компьютере с объёмом памяти менее двух мегабайт. Да и если такие извращенцы найдутся, то не вижу ничего плохого в том, чтобы система упала - всё равно у нас даже драйвер экрана без верхней (выше 1 МБ) памяти не сможет работать. Однако вы, особенно если будете манипулировать большими блоками памяти, должны проверять,
что alloc_virt_pages вернул не NULL (признак того, что по какой-то причине выделить память не удалось).
На этом заканчиваю этот выпуск. Все вопросы вы можете задать на мой электронный адрес - kiv.apple@gmail.com.