How does setting the PE flag in CR0 enable protected mode?
Asked Answered
S

1

7

I am trying to understand how a machine goes from power on to running a kernel. From what I've gathered, it is useful to switch into protected mode during boot up in order to gain access to more addressable memory even if we will eventually switch to a more conventional virtual memory plan with page directories and page tables and segmentation turned off.

It seems that to switch into protected mode 3 things must be done:

  1. Set up a global descriptor table (gdt) and load it using the lgdt instruction
  2. Set the PE flag/bit in the control register CR0 to enabled (ie. to the value 1)
  3. Execute a long jump with ljmp

I am wondering about the logic for translating a segment register and instruction pointer into an index and offset for use with the gdt. Is this logic accomplished by hardware? If so which piece of hardware and why is the execution of a ljmp part of the process? Why not simply set the PE flag in CR0 to enable protected mode (with no following ljmp)?

Sordid answered 31/10, 2014 at 15:21 Comment(2)
I am wondering why you did not search for text pattern protected mode in the Intel® 64 and IA-32 Architectures Software Developer’s Manual and what is your research effort and why are you asking, what problem are you trying to solve/understand? BTW: did you know that frequent answer to similar questions is: read wiki.osdev.org ?Extinguisher
@Extinguisher I did search in Intel's Developer's manual but could not find the information I wanted. I am trying to understand how the transition from real mode to protected mode is achieved. I was not aware of the osdev wiki, so I will take a look at it next time I have a question like this.Sordid
P
7

The first question could be: Why didn't Intel design the chip in a way that setting PE will enter protected mode?

The answer: This would not really be possible; it 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 address 0x0100:0x1200 then the next instruction executed will be at address 0x0100:0x1203. So switching to protected mode will only be possible in conjunction with a jump instruction; otherwise switching PE itself would do an unwanted jump (from 0x0100:0x1203 Real Mode to 0x0100:0x1203 Protected Mode).

Technically the CPU internally stores the selector information of all selectors used. Whenever a selector register changes then the limit, base and so on are loaded. This means that loading the CS register is required for updating the base, limit and so of the CS register. This means: A far jump must be done (because this will load the CS register). Maybe a RETF would also work...

I'm not sure if loading the other segment registers (for example DS) would 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. Would be nice to try this out...

Preterition answered 31/10, 2014 at 21:26 Comment(2)
Hmm, so a ljmp consults the GDT (since a ljmp loads the CS register)? Does it always do this, or only if CR0's PE flag is set?Sordid
Hmm, dear @PedroCattori please read at least chapter "ACTIVATING THE PROTECTED MODE" from article linked from the OSDev.org wiki as Protected Mode → pragmatic tutorial on pmode and also please read chapter "9.9.1 Switching to Protected Mode" in the Intel® 64 and IA-32 Architectures Software Developer’s Manual as it should answer both basic and more advanced questionsExtinguisher

© 2022 - 2024 — McMap. All rights reserved.