背景信息:我在QEMU下运行Xv6,并使用GDB作为调试器。我正逐步通过引导程序来查看它的功能。 Xv6旨在在加载内核之前切换到32位代码。
在汇编程序文件bootasm.S
中,跳转到32位。进行转换的指令如下:
# Complete transition to 32-bit protected mode by using long jmp
# to reload %cs and %eip. The segment descriptors are set up with no
# translation, so that the mapping is still the identity mapping.
ljmp $(SEG_KCODE<<3), $start32
在跳转之前,分段地址'寄存器(由CS
和EIP
寄存器组成)的值(可以从GDB's info reg
命令读取)是{{ 1}}。
跳转后,分段地址现在为CS=0x0:EIP=7c2c
,其中CS=0x8:EIP=0x7c31
是32位代码开头的地址(包含在0x7c31
下的bootasm.S中)。
我知道通过将start32
乘以16并将CS
作为偏移量添加到其中,将分段地址转换为物理地址。例如,EIP
时,物理地址为CS = 0x0
。
我的问题是关于(0x10 * 0xf000) + 0x7c2c = 0xf0000 + 0x7c2c = 0xf7c2c
寄存器如何具有内在价值。 CS
如何从CS
更改为0x0
等同于立即运行32位代码?如果我理解正确,请根据0x8
的方式,然后0x0 * 16 = 0xf0000
,对吧?但是这个分段地址如何等同于32位呢?或者我只是误解了0x8 * 16 = 0xf0080
寄存器的值代表什么?
CS
指令是相关的。这是跳转前的指令及其以下说明,可以在LGDT
:中找到
bootasm.S