简体   繁体   English

x86 处理器如何在引导加载程序加载 GDT 后立即获取指令?

[英]How can the x86 processor fetch the instruction just after GDT is loaded by a bootloader?

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):在为 x86 编写的典型简单引导加载程序中,我们有以下代码来加载 GDT 并执行远跳转(注意,在执行以下代码之前,CS 为 0x0):

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:

However, just after lgdt CS is null, pointing to a null descriptor in GDT.但是,就在lgdt CS 为空之后,指向 GDT 中的空描述符。 So :所以 :

1.How on earth can the CPU fetch the correct instruction just after GDT is loaded by lgdt ? 1.在lgdt加载GDT后,CPU lgdt如何获取正确的指令?

2.DPL of the code segment to far-jump to is usually 0, does the CPU perform privilege check when doing the far jump? 2.远跳转到的代码段的DPL通常为0,CPU在进行远跳转时是否进行权限检查?

Until the far jump loads the internal CS base/limit/stuff from a GDT entry, you're not using any GDT entry at all.在远跳从 GDT 条目加载内部 CS 基础/限制/内容之前,您根本没有使用任何 GDT 条目。 It's not really even protected mode.它甚至不是真正的保护模式。

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.与启用分页(在写入 CR0 后的下一条指令中,下一条指令的取指令将 CS:EIP 视为虚拟的)不同,在写入段寄存器导致 CPU 实际从 GDT 读取之后才会发生段填充。

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. CS 基地址不会被 LGDT 更改,并且您仍然处于最大特权级别,并且操作数大小 = 地址大小 = 16,因此会发生ljmp指令的代码提取。 (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. (假设此代码段的执行以实模式或非实模式开始。)处于保护模式会影响将 CS 更新为8的含义,但不会影响执行该操作的指令的获取和运行。

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.我不知道它是否算作 CPL=0 或是否是特殊情况的正式细节,或者如果您的第一次远跳是到呼叫门会发生什么。 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.如果您想要更多,请查看https://wiki.osdev.org/GDT_Tutorial和/或 Intel 或 AMD 的手册,或者其他人可能会回答这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM