Предполагается, что вы пытаетесь идентифицировать первые 4 Мбайт физического адресного пространства:
a) для unsigned int __FIRST_PAGE_TABLE__[0x400] __attribute__((aligned(0x1000)));
это локальная переменная (например, вероятно, помещена в стек); и оно не сохранится после возврата функции (например, используемое ею пространство стека будет перезаписано другими функциями позже), что приведет к повреждению таблицы страниц. Это вряд ли закончится хорошо.
b) Для __FIRST_PAGE_TABLE__[i] = ((i * 0x1000) << 12) | PAGE_PRESENT(1) | PAGE_READ_WRITE;
вы сдвигаете i
дважды, один раз с * 0x1000
(что совпадает с << 12
) и снова с << 12
. Это слишком много, и это должно быть больше похоже на __FIRST_PAGE_TABLE__[i] = (i << 12) | PAGE_PRESENT(1) | PAGE_READ_WRITE;
.
c). Для __PAGE_DIRECTORY__[0] = ((unsigned int)__FIRST_PAGE_TABLE__ << 12) | PAGE_PRESENT(1) | PAGE_READ_WRITE;
адрес уже является адресом (а не "номером страницы", который необходимо сместить ), так что это должно быть больше похоже на __PAGE_DIRECTORY__[0] = ((unsigned int)__FIRST_PAGE_TABLE__) | PAGE_PRESENT(1) | PAGE_READ_WRITE;
.
Помимо этого; Я бы очень предпочел лучшее использование типов. В частности, вы, вероятно, должны привыкнуть использовать uint32_t
(или uint64_t
, или typedef
своего) для физических адресов, чтобы не случайно случайно перепутать виртуальный адрес с физическим адресом (и убедиться, что компилятор жалуется на неправильный тип при совершении ошибки); потому что (хотя это не очень важно сейчас, потому что вы отображаете личность), это станет важным "скоро". Я также рекомендовал бы использовать uint32_t
для записей таблицы страниц и записей каталога страниц, потому что они должны быть 32-битными, а не «какого бы размера не считал компилятор int
» (обратите внимание, что это разница в том, как вы думаете о коде, который важнее того, что на самом деле делает компилятор, или о том, что int
в любом случае 32-битный).