x86 处理器如何在引导加载程序加载 GDT 后立即获取指令? [英] How can the x86 processor fetch the instruction just after GDT is loaded by a bootloader?

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

问题描述

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

lgdt gdtdescmovl %cr0, %eax或 $1, %eaxmovl %eax, %cr0# 跳转到下一条指令,但在 32 位代码段.# 将处理器切换到 32 位模式.ljmp $0x8, $protcseg.code32 # 汇编为 32 位模式保护段:

然而,就在 lgdt 之后,CS 为空,指向 GDT 中的空描述符.所以:

1.lgdt加载GDT后,CPU到底是怎么取到正确指令的?

2.远跳转到的代码段的DPL通常为0,CPU在进行远跳转时是否进行权限检查?

解决方案

在远跳转从 GDT 条目加载内部 CS 基础/限制/内容之前,您根本没有使用任何 GDT 条目.它甚至不是真的保护模式.

与启用分页不同(在写入 CR0 后,下一条指令的取指令将 CS:EIP 在下一条指令中视为虚拟),直到写入段寄存器导致 CPU 实际从GDT.

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

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

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:

However, just after lgdt CS is null, pointing to a null descriptor in GDT. So :

1.How on earth can the CPU fetch the correct instruction just after GDT is loaded by 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?

解决方案

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.

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.

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.

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆