How do I set the PE flag to CR0 to enable protected mode?

I'm trying to figure out how a machine goes from kernel to kernel startup. From what I've gathered, it's helpful to switch to protected mode at boot time to access more addressable memory, even if we end up switching to a more conventional virtual memory plan with page directories and page tables and turn segmentation off.

It seems like you need to do 3 things to switch to protected mode:

  • Configure the global descriptor table (gdt) and load it using the command lgdt

  • Set the PE flag / bit in the control register CR0 to enable (that is, to the value 1)
  • Take a long jump with ljmp

I am wondering about the logic behind translating segment registers and instruction pointer to index and offset for use with gdt. Is this logic implemented in hardware? If so, what kind of hardware and why is it doing part of a process ljmp

? Why not just set the PE flag to CR0 to enable protected mode (without the following ljmp

)?

+3


source to share


1 answer


The first question is, why hasn't Intel built the chip in such a way that the PE setting will be enabled in Protected Mode?

Answer: It would be impossible; he would assume that the CS register contains a selector whose base address is 0x10 * CS.

In other words: If the address "mov CR0, EAX" is located at 0x0100: 0x1200, then the following instruction will be executed at 0x0100: 0x1203. Therefore, transition to protected mode is only possible in conjunction with a jump instruction; otherwise, the PE switch will itself make an unwanted jump (from 0x0100: 0x1203 Real Mode to 0x0100: 0x1203 Protected Mode).



Technically, the CPU internally stores the selector information of all the selectors it uses. When the selector register changes, the limit, base, etc. are loaded. This means that loading the CS register is necessary to update the base, the constraint, and therefore the CS register. This means: a big jump has to be made (because this will load the CS register). Maybe RETF will also work ...

I'm not sure if loading other segment registers (like DS) will already work before the far jump, so if you load the DS register before the far jump, the base address and limit will be taken from the GDT. It would be nice to try this ...

+1


source







All Articles