问题描述
在为 x86 编写的典型简单引导加载程序中,我们有以下代码来加载 GDT 并执行远跳转(注意在执行以下代码之前 CS 为 0x0):
In a typical simple bootloader writing for x86, we have the following code to load the GDT and perform a far jump (note that CS is 0x0 before executing the following code):
lgdt gdtdesc
movl %cr0, %eax
orl $1, %eax
movl %eax, %cr0
# Jump to next instruction, but in 32-bit code segment.
# Switches processor into 32-bit mode.
ljmp $0x8, $protcseg
.code32 # Assemble for 32-bit mode
protcseg:
然而,就在 lgdt
之后,CS 为空,指向 GDT 中的空描述符.所以:
However, just after lgdt
CS is null, pointing to a null descriptor in GDT. So :
1.在lgdt
加载GDT之后,CPU究竟如何获取正确的指令?
1.How on earth can the CPU fetch the correct instruction just after GDT is loaded by lgdt
?
2.要远跳的代码段的DPL通常为0,做远跳时CPU是否进行权限检查?
2.DPL of the code segment to far-jump to is usually 0, does the CPU perform privilege check when doing the far jump?
推荐答案
在远跳转从 GDT 条目加载内部 CS 基础/限制/东西之前,您根本没有使用任何 GDT 条目.真的甚至不是保护模式.
Until the far jump loads the internal CS base/limit/stuff from a GDT entry, you're not using any GDT entry at all. It's not really even protected mode.
与启用分页不同(其中下一条指令的取指在写入 CR0 后的下一条指令中将 CS:EIP 视为虚拟),直到写入段寄存器导致 CPU 实际从GDT.
Unlike enabling paging (where instruction fetch for the next instruction treats CS:EIP as virtual in the next instruction after writing CR0), segment stuff doesn't happen until after a writing a segment register causes the CPU to actually read from the GDT.
LGDT 不会更改 CS 基地址,并且您仍处于操作数大小 = 地址大小 = 16 的最大特权级别,因此 ljmp
指令的代码获取只是发生.(假设此代码段的执行以实模式或虚模式开始.)处于保护模式会影响将 CS 更新为 8
的含义,但不会影响获取和运行执行此操作的指令.
The CS base address isn't changed by LGDT, and you're still at maximum privilege level with operand-size = address-size = 16, so code-fetch of the ljmp
instruction just happens. (Assuming execution of this snippet started in real or unreal mode.) Being in protected mode affects the meaning of updating CS to 8
, but doesn't affect fetching and running the instruction that does that.
我不知道它是否算作 CPL=0 或者它是否是一种特殊情况,或者如果您的第一次远跳是到呼叫门会发生什么的正式细节.如果您想要更多,请查看 https://wiki.osdev.org/GDT_Tutorial和/或英特尔或 AMD 的手册,或者其他人可能会回答这个问题.
I don't know the formal details of whether it counts as CPL=0 or if it's a special case, or what would happen if your first far jump was to a call gate. If you want more than that, have a look at https://wiki.osdev.org/GDT_Tutorial and/or Intel or AMD's manuals, or maybe someone else will answer this question.
这篇关于x86 处理器如何在引导加载程序加载 GDT 之后获取指令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!