Intel VT-x: физическое и линейное адресное пространство не совпадает
В настоящее время я разрабатываю ядро x86-64 с нуля для исследовательских целей. Цель состоит в том, чтобы виртуализировать мою собственную ОС с использованием технологии виртуализации Intel (VT-x). Однако я наткнулся на чрезвычайно странную проблему, которая мешает мне продолжить мой проект:
Как только я вхожу в гостевую ОС, 32-битная точка входа моего ядра должна выбрать адрес 64-битной точки входа, чтобы ядро могло перейти к нему. Это делается путем извлечения значений заголовка ELF ядра, расположенного в гостевой физической памяти. Однако в этот момент, когда извлекается заголовок ELF ядра, моя ОС выдает ошибку, сообщающую, что по указанному адресу нет заголовка:
Чтобы объяснить изображение: нижняя половина экрана - это выход хоста, а верхняя половина - выход гостя.
Теперь мне стало интересно, почему ничего нет, хотя я был уверен, что разместил заголовок ELF ядра по указанному адресу в гостевой физической памяти (0x0019A000). Теперь очень важная информация, которую нужно иметь в виду: в этот момент, когда появляется сообщение об ошибке, подкачка еще не была включена. Это означает, как описано в документации Intel:
Если CR0.PG = 0, каждый линейный адрес обрабатывается как гостевой физический адрес.
На данный момент пейджинг определенно не включен, так как CR0 не имеет установленного бита 31. (Значение CR0: 0x60000011)
Поэтому я проверил дамп физической памяти через Bochs:
Кажется, что есть, но выполнение происходит в линейном адресном пространстве, указатель инструкций читает инструкции из линейного адресного пространства, а затем возникает проблема:
Итак, мой вопрос: какие существуют причины для физического и линейного адресного пространства отличаться друг от друга только в этой одной области памяти, в то время как подкачка отключена?
Я проверил:
- GDT (настройка CS и DS для 32-битной системы, base = 0x0, limit = 0xfffff)
- Селекторы для сегментов установлены соответственно
- EPT, используемый для сопоставления гостевых физических адресов (GPA) с физическими адресами хоста (HPA): адрес определенно сопоставлен, и даже выгрузка памяти в физическом адресном пространстве хоста показывает, что заголовок ELF ядра находится там так же, как так должно быть
- Пейджинг определенно не включен, поэтому memdump должен показывать одно и то же содержимое в памяти по одному адресу