[英]Far jump in gdt in bootloader
flush_gdt:
lgdt [gdtr]
jmp 0x08:complete_flush
complete_flush:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
ret
我无法理解这段代码的作用。 flush_gdt
是一个标签okay,然后lgdt [gdtr]
加载gdtr
寄存器中的48-bit
指针, gdtr
从jmp 0x08:complet_flush
。
jmp指令有什么作用? 然后我们为什么要将0x10移动到ax,然后移动到其他寄存器
x86支持两种虚拟内存方案( 在此处阅读 ):
大多数操作系统都希望使用分页而不希望分段,但必须禁用它。
所以诀窍是禁用它的效果,因为它不在那里。 这通常可以通过创建4个大的重叠段描述符(在空段旁边)来完成:
所有这些段从0x00000000
开始到0xffffffff
,因此您最终会得到重叠的大段,即特权代码和数据,以及同时非特权的代码和数据。 这应该打开虚拟内存并禁用分段效果。
处理器使用段选择器(段寄存器cs
, ds
, ss
...)来找出正确的段(再一次,必须进行分段)。
每个段选择器都是16位大小,并具有以下布局( 源 ):
前两位表示权限级别,x86支持4个级别,但实际使用的只有两个级别( 00
最高, 11
最低)。
第三位表示应该使用表格,大部分是0
,GDT。
如果您解释了在cs
加载的0x08
,它将是二进制的:
0000000000001 0 00
index 1 (code) GDT privileged
以及ds
, ss
,...中加载的0x10
:
0000000000010 0 00
index 2 (data) GDT privileged
如果您读取任何用户模式程序的段选择器,您应该看到cs
值为27
( 0x1b
),这意味着:
0000000000011 0 11
index 3 (code) GDT non-privileged
数据选择器ds
, ss
,...应存储35( 0x23
):
0000000000100 0 11
index 4 (data) GDT non-privileged
数据段选择器(寄存器)可以使用简单的mov
指令轻松修改,但cs
不能与mov
一起使用,因此使用jmp 0x08:OFFSET
将段配置加载到代码段选择器中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.