2016-10-15 11 views
0

Я работаю над простым ядром, которое следует спецификациям multiboot. Это для проекта класса, поэтому я не могу публиковать свой код напрямую, но по моему вопросу достаточно сказать, что мы используем модифицированную версию multiboot sample code.Структура стека во время инициализации защищенного режима

Я пытаюсь установить глобальный регистр таблицы дескрипторов (GDTR), чтобы указать на соответствующий адрес. Для этого я слежу за GDT Tutorial из вики OSDev. В учебнике их примерный код для режима с плоской защитой просто загружает два значения из стека и помещает их в GDTR. Это меня смущает, потому что я думал, что GDTR должен быть установлен до, когда инициализируется стек. Я не знаю, где ESP будет указывать, если ядро ​​еще не инициализировало его. Полагаю, что GRUB может это сделать, прежде чем переходить на какой-либо код в boot.S, но я не смог найти какую-либо документацию, чтобы предложить это.

tl; dr - Почему OSDev GDT Tutorial извлекает данные из адреса относительно ESP при загрузке адреса и размера глобальной таблицы дескрипторов?

ответ

1

Вы не можете сделать многое в защищенном режиме без надлежащей настройки GDT в любом случае, и GRUB, очевидно, должен сделать это не только для вас, но и для себя. Слова

«CS» Должен быть 32-разрядный сегмент кода чтения/выполнения со смещением «0» и пределом «0xFFFFFFFF».

следует GDT с правильно настроенным дескриптором сегмента кода и регистром CS, загруженным селектором, выбирающим этот дескриптор.

Подпрограмма setGdt принимает свои аргументы в стеке. Это делает его удобным для вызова из кода C (32-разрядные компиляторы x86 C/C++, такие как gcc и Microsoft Visual C++, а некоторые другие поддерживают это соглашение о вызове, см. cdecl).

Однако, прежде чем позвонить setGdt, даже прежде чем поместить аргументы в стек, вам необходимо настроить стек из-за этого языка:

«ESP» образа ОС должен создать свой собственный стек, как как только он понадобится.

Обратите внимание, что пример кода из файла boot.S этой страницы делает это:

/* The size of our stack (16KB). */ 
#define STACK_SIZE      0x4000 
... 
multiboot_entry: 
      /* Initialize the stack pointer. */ 
      movl $(stack + STACK_SIZE), %esp 
... 
      /* Our stack area. */ 
      .comm stack, STACK_SIZE 

Должно быть довольно понятно.

Теперь базовый адрес сегмента и предел сегмента (вместе с правами доступа к сегменту) получают кеширование в ЦП при загрузке селектора в регистр сегмента. Таким образом, изменение GDT или GDTR под кодом будет недействительным до следующей загрузки в регистр сегмента.

 Смежные вопросы

  • Нет связанных вопросов^_^