切换到保护模式
切换到保护模式很简单:只需在控制寄存器中设置一个位即可。但是保持在保护模式下,由于不知道接下来要做什么而没有 CPU 丢失并重置自己,需要做很多准备。
简而言之,所需的步骤如下:
-
需要设置全局描述符表的内存区域以定义至少三个描述符:
-
零,
NULL
描述符; -
代码段的另一个描述符;
-
数据段的另一个描述符。
这可以用于数据和堆栈。
-
-
需要初始化全局描述符表寄存器(
GDTR
)以指向该定义的存储区域;GDT_Ptr dw SIZE GDT dd OFFSET GDT ... lgdt [GDT_Ptr]
-
需要设置
CR0
中的PM
位:mov eax, cr0 ; Get CR0 into register or eax, 0x01 ; Set the Protected Mode bit mov cr0, eax ; We're now in Protected Mode!
-
需要从 GDT 加载段寄存器以删除当前的实模式值:
jmp 0x0008:NowInPM ; This is a FAR Jump. 0x0008 is the Code Descriptor NowInPM: mov ax, 0x0010 ; This is the Data Descriptor mov ds, ax mov es, ax mov ss, ax mov sp, 0x0000 ; Top of stack!
请注意,这是裸最小,只是为了让 CPU 进入保护模式。要实际使整个系统准备就绪可能需要更多步骤。例如:
- 可能必须启用高端存储区 - 关闭
A20
门; - 绝对应该禁用中断 - 但是在进入保护模式之前可能会设置各种故障处理程序,以便在处理过程中尽早发生错误。
本节的原作者编写了一个关于进入保护模式并使用它的完整教程 。