Я задал этот вопрос, потому что я не понимаю, как осуществляется преобразование адресов в области ядра.
Из того, что я понимаю, для перевода любого адреса выше 0xC0000000
нам просто нужно минусэтот адрес с PAGE_OFFSET
(кроме процесса инициализации ядра, где нам нужна таблица страниц для диапазона 8 МБ).Но это не имеет смысла, когда процессор выполняет инструкцию, которая требует адрес, скажем, 0xF0000020
, в то время как система имеет только 256 МБ ОЗУ.
По вышеуказанной причине, я думаю, что ядро действительно имеет таблицу страницчто позволяет MMU переводить виртуальный адрес выше 0xC0000000
в физический.Таким образом, в какой ситуации мы можем напрямую минус PAGE_OFFSET
и в какой ситуации нам нужна таблица страниц ядра?
Я могу ошибиться в начале, поэтому, пожалуйста, исправьте.
РЕДАКТИРОВАТЬ
Из << Понимание диспетчера виртуальной памяти Linux >>, где говорится, что таблица страниц ядра существует.Теперь более запутанно ...
3.6 Таблицы страниц ядра
При первом запуске системы подкачка страниц не включена, поскольку таблицы страниц сами по себе магически не инициализируются,Каждая архитектура реализует это по-своему, поэтому будет обсуждаться только случай x86.Инициализация таблицы страниц делится на две фазы.На этапе начальной загрузки таблицы страниц устанавливаются всего на 8 МБ, чтобы можно было включить модуль подкачки. Второй этап инициализирует остальные таблицы страниц .Обе эти фазы обсуждаются в следующих разделах.
3.6.1 Начальная загрузка
...
3.6.2 Завершение
Функция, отвечающая за финализацию таблиц страниц, называется paging_init ().График вызовов для этой функции на x86 можно увидеть на рисунке 3.4.
Функция сначала вызывает pagetable_init () для инициализации таблиц страниц, необходимых для ссылки на всю физическую память в ZONE_DMA и ZONE_NORMAL.Помните, что на высокую память в ZONE_HIGHMEM нельзя напрямую ссылаться, и что для нее временно установлены сопоставления.Для каждого pgd t, используемого ядром, для выделения страницы для PGD вызывается распределитель загрузочной памяти (см. Главу 5), и бит PSE будет установлен, если он доступен, для использования записей TLB 4 МБ вместо 4 КБ.Если бит PSE не поддерживается, страница для PTE будет выделена для каждого pmd t.Если процессор поддерживает флаг PGE, он также будет установлен таким образом, чтобы запись в таблице страниц была глобальной и видимой для всех процессов.
Далее, pagetable_init () вызывает fixrange_init () для установки фиксированного адресного пространства.сопоставления в конце виртуального адресного пространства, начиная с FIXADDR_START.Эти сопоставления используются для таких целей, как локальный расширенный программируемый контроллер прерываний (APIC) и атомарные сопоставления между FIX_KMAP_BEGIN и FIX_KMAP_END, требуемые kmap_atomic ().Наконец, функция вызывает fixrang_init (), чтобы инициализировать записи таблицы страниц, необходимые для нормальных отображений высокой памяти, с помощью kmap ().
После возврата pagetable_init () таблицы страниц для пространства ядра теперь полностью инициализированы, поэтомуstatic PGD (swapper_pg_dir) загружается в регистр CR3, так что статическая таблица теперь используется модулем подкачки.
Следующая задача paging_init () отвечает за вызов kmap_init () для инициализации каждого изPTE с флагами защиты PAGE_KERNEL.Последняя задача - вызвать zone_sizes_init (), которая инициализирует все используемые структуры зон.