Схема разбивки физической памяти в Linux

Теперь мы обсудим макросы, которые упаковывают адрес страницы и набор флагов защиты в запись таблицы страниц или выполняют обратную операцию по извлечению адреса страницы из записи в таблице страниц. Обратите внимание, что некоторые из этих макросов ссылаются на страницу с помощью линейного адреса так называемого дескриптора страницы, а не линейного адреса самой страницы.
На этапе инициализации ядро должно построить карту физических адресов, определяющую, какие интервалы физических адресов будут использоваться ядром, а какие недоступны (либо потому что они отображают память, совместно используемую аппаратными устройствами для ввода/вывода, либо потому что соответствующие страничные кадры содержат данные BIOS).
Следующие страничные кадры ядро считает зарезервированными:
- попадающие в недоступные интервалы физических адресов;
- содержащие код ядра и инициализированные структуры данных;
- страничный кадр 0 используется системой BIOS для хранения аппаратной конфигурации системы, определяемой на этапе самотестирования при включении питания (POST, Power-On Self-Test). Кроме того, BIOS многих портативных компьютеров записывает данные в эту страницу даже после инициализации системы;
- физические адреса с 0х000а0000 по 0x000fffff обычно резервируются под рабочие процедуры BIOS, а также для отображения внутренней памяти графических карт ISA. Это знаменитая дыра” между 640 Кбайт и 1 Мбайт во всех IBM-совместимых персональных компьютерах: физические адреса существуют, но они зарезервированы, и операционная система не может использовать соответствующие страничные кадры.
В некоторых моделях компьютеров могут быть зарезервированы дополнительные страничные кадры в пределах первого мегабайта. Например, в IBM ThinkPad страничный кадр ОхаО отображается в страничный кадр 0x9f.
На раннем этапе начальной загрузки ядро опрашивает BIOS и узнает размер физической памяти. В современных моделях компьютеров ядро также вызывает одну из процедур BIOS, чтобы построить список интервалов физических адресов и соответствующих им типов памяти.
Затем ядро выполняет функцию machine_specif ic_memory_setup (), которая строит карту физических адресов. Конечно, ядро строит эту таблицу на базе списка BIOS, если он доступен. В противном случае оно строит таблицу, следуя консервативному подходу, принятому по умолчанию: все страничные кадры с номерами от 0x9f (lowmemsizeo) до 0x100 (high memory) помечаются как зарезервированные.
Диапазон физических адресов с 0x07ff0000 по 0x07ff2fff содержит информацию об аппаратных устройствах в системе, записанную системой BIOS на этапе самотестирования. На этапе инициализации ядро копирует эту информацию в соответствующую структуру данных ядра, а затем считает эти страничные кадры годными к использованию. Физические адреса с 0x07ff3000 по 0x07ffffff отображаются на микросхемы постоянной памяти аппаратных устройств. Диапазон физических адресов, начинающийся с адреса 0xffff0000, помечен как зарезервированный, потому что он аппаратно отображается на микросхему постоянной памяти BIOS. Обратите внимание, что BIOS может и не предоставить никакой информации для некоторых диапазонов физических адресов (в таблице это диапазон с 0х000а0000 по 0x000effff). На всякий случай, Linux предполагает, что такие диапазоны использовать нельзя.
В этом случае оперативная память не может быть целиком отображена в пространство линейных адресов ядра. Самое большее, что может сделать Linux на этапе инициализации, - это отобразить окно оперативной памяти размером 896 Мбайт в пространство линейных адресов ядра. Если программе понадобится обратиться к другим областям оперативной памяти, нужно будет отобразить на эти области какой-нибудь другой интервал линейных адресов. Для инициализации глобального каталога страниц ядро выполняет тот же код, что и в предыдущем случае.