远跳GDT的引导程序 [英] 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
我无法理解这code做了什么。 flush_gdt
是一个标签还好,那么 LGDT [GDTR]
加载 48位
在 GDTR
指针寄存器后,从 JMP 0x08的:complet_flush
I am unable to understand what this code does . flush_gdt
is a label okay , then lgdt [gdtr]
loads the 48-bit
pointer in gdtr
register and after that from jmp 0x08:complet_flush
.
这是什么jmp指令呢?然后为什么我们移动为0x10斧子,随后到其它寄存器
What does jmp instruction do ? and then why are we moving 0x10 to ax and then subsequently to other registers
推荐答案
86支持两个虚拟内存方案(的阅读它这里):
x86 supports two virtual memory schemes (read about it here):
- 分割,必须使用段表管理,GDT。
- 分页,可选,采用了页表管理,PDT。
大多数操作系统要使用寻呼和不想分割,但其必须的,不能只是被禁用。
Most operating systems want to to use paging and don't want the segmentation, but its must and can't just be disabled.
所以,关键是因为它是不存在禁用其效果。这通常可以通过创造来完成4个大的重叠段描述符(空段旁):
So the trick is to disable its effect as it wasn't there. This can usually be done by creating 4 large overlapped segments descriptors (beside the null segment):
- 段指数0:空的段描述符
- 段索引1:特权(内核)模式code段描述符
- 段索引2:数据段描述符特权(内核)模式
- 段索引3:非特权(用户)模式code段描述符
- 段索引4:数据段描述符非特权(用户)模式
所有的领域从 00000000
启动以为0xffffffff
,所以你最终重叠的很大一部分是特权code和数据,和非特权code和数据在同一时间。这应该打开了虚拟内存和禁用分割效果。
all these segments starts from 0x00000000
up to 0xffffffff
, so you end up with overlapped large segments that is privileged code and data, and non-privileged code and data in the same time. This should open up the virtual memory and disable the segmentation effect.
该处理器使用段选择(段寄存器 CS
, DS
, SS
...),找出正确的段(再次分割是必须)。
The processor uses the segment selectors (segment registers cs
, ds
, ss
...) to find out the right segment (once again, the segmentation is must).
每一个段选择16位的大小,并具有以下布局(源):
Every segment selector is 16 bit size and has the following layout (source):
-
前两位表示权限级别,X86支持4个级别,但只有两个人实际使用(
00
最高,11
最低)。
第三位指示表应使用,大多是 0
的GDT。
The third bit indicates the table should be used, mostly 0
, the GDT.
如果您间preTED的 0×08
是在 CS
加载,这将是二进制的:
If you interpreted the 0x08
that is loaded in cs
, it will be in binary:
0000000000001 0 00
index 1 (code) GDT privileged
而在 DS加载
, 0×10
SS
...
0000000000010 0 00
index 2 (data) GDT privileged
如果你看过任何用户模式程序的段选择,你应该看到 CS
值为 27
( 0x1b
),这意味着:
If you read the segment selectors of any user mode program you should see that the cs
value is 27
(0x1b
) which means:
0000000000011 0 11
index 3 (code) GDT non-privileged
和数据选择器 DS
, SS
,...,应该储存35( 0x23
)
and the data selectors ds
, ss
, ..., should store 35 (0x23
):
0000000000100 0 11
index 4 (data) GDT non-privileged
数据段选择器(寄存器),可以用简单的 MOV
指令来方便地进行修改,但 CS
CAN 'T与 MOV
使用,所以你用 JMP 0x08的:OFFSET
来段配置加载到了code段选择。
The data segments selectors (registers), can be easily modified using simple mov
instruction, but the cs
can't be used with mov
, so you use jmp 0x08:OFFSET
to load the segment configurations into the the code segment selector.
这篇关于远跳GDT的引导程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!