CPU Protected_Mode - seporaitis/xv6-public GitHub Wiki
Protected Mode
What are the requirements for switching to protected-mode?
Ref: (9.8, Intel Software Developer's Manual)
Before the processor can be switched to protected mode, the software initialization code must load a minimum number of protected mode data structures and code modules into memory to support reliable operation of the processor in protected mode. These data structures include the following:
- A IDT (Interrupt Descriptor Table)
- A GDT (Global Descriptor Table)
- A TSS (Task State Segment)
- (Optional) A Local Descriptor Table)
- If paging to be used, at least one page directory and one page table.
- A code segment that contains the code to be executed when the processor switches to protected mode.
- One or more code modules that contain the necessary interrupt and exception handlers.
Software initialization code must also initialize the following system registers before the processor can be switched to protected mode:
- The GDTR (Global Descriptor Table Register)
- (Optional) The IDTR (Interrupt Descriptor Table Register)
- Control Registers CR1 through CR4.
With these data structures, code modules, and system registers initialized the processor can be switched to protected mode by loading control register CR0 with a value that sets the PE flag (bit 0)
What are the recommended steps to switch to protected mode?
Ref: (9.9.1, Intel Software Developer's Manual)
-
Disable interrupts. A CLI instruction disables maskable hardware interrupts.
-
Execute LGDT instruction to load the GDTR register with the base address of GDT.
-
Execute MOV CR0 instruction, that sets the PE flag (and optionally PG flag) in control register CR0.
-
Immediately following the MOV CR0 instruction, execute a far JMP or CALL instruction. (This operation is typically a far jump or call to the next instruction in the instruction stream.)
-
The JMP or CALL instruction immediately after MOV CR0 changes the flow of execution and serializes the processor.
-
If paging is enabled, the code for the MOV CR0 and the JMP or CALL instruction must come from a page that is identity mapped (that is, linear address before the jump is the same as the physical address after paging and protected mode is enabled). The target instruction for the JMP or CALL instruction does not need to be identity mapped.
-
If a local descriptor table is going to be used, execute LLDT instruction to load the segment selector for the LDT and LDTR register.
-
Execute the LTR instruction to load the task register with a segment selector to the initial protected-mode task or to a writable area of memory that can be used to store TSS information on a task switch.
-
After entering protected mode, the segment registers continue to hold the contents they had in real-address mode. The JMP or CALL instruction in step 4 resets the CS register. Perform one of the following operations to update the contents of the remaining segment registers.
a. Reload segment registers DS, SS, ES, FS, and GS. If the ES, FS, and/or GS registers are not going to be used, load them with a null selector.
b. Perform a JMP or CALL instruction to a new task, which automatically resets the values of the segment registers and branches to a new code segment.
-
Execute the LIDT instruction to load the IDTR register with the address and limit of the protected-mode IDT.
-
Execute the STI instruction to enable maskable hardware interrupts and perform the necessary hardware operation to enable NMI interrupts.