本文介绍了x86 处理器如何在引导加载程序加载 GDT 之后获取指令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在为 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 之后获取指令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-20 07:47