远跳GDT的引导程序 [英] Far jump in gdt in bootloader

查看:152
本文介绍了远跳GDT的引导程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

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