簡體   English   中英

在bootloader中遠程跳轉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

我無法理解這段代碼的作用。 flush_gdt是一個標簽okay,然后lgdt [gdtr]加載gdtr寄存器中的48-bit指針, gdtrjmp 0x08:complet_flush

jmp指令有什么作用? 然后我們為什么要將0x10移動到ax,然后移動到其他寄存器

x86支持兩種虛擬內存方案( 在此處閱讀 ):

  • 必須使用分段表GDT管理分段。
  • 分頁,可選,使用頁表管理,PDT。

大多數操作系統都希望使用分頁而不希望分段,但必須禁用它。

所以訣竅是禁用它的效果,因為它不在那里。 這通常可以通過創建4個大的重疊段描述符(在空段旁邊)來完成:

  • 段索引0:空段描述符
  • 段索引1:特權(內核)模式的代碼段描述符
  • segment index 2:特權(內核)模式的數據段描述符
  • 段索引3:非特權(用戶)模式的代碼段描述符
  • 段索引4:非特權(用戶)模式的數據段描述符

所有這些段從0x00000000開始到0xffffffff ,因此您最終會得到重疊的大段,即特權代碼和數據,以及同時非特權的代碼和數據。 這應該打開虛擬內存並禁用分段效果。

處理器使用段選擇器(段寄存器csdsss ...)來找出正確的段(再一次,必須進行分段)。

每個段選擇器都是16位大小,並具有以下布局( ):

在此輸入圖像描述

  • 前兩位表示權限級別,x86支持4個級別,但實際使用的只有兩個級別( 00最高, 11最低)。

  • 第三位表示應該使用表格,大部分是0 ,GDT。

  • 其余13位表示段索引。

如果您解釋了在cs加載的0x08 ,它將是二進制的:

0000000000001     0         00
index 1 (code)   GDT    privileged

以及dsss ,...中加載的0x10

0000000000010     0         00
index 2 (data)   GDT    privileged

如果您讀取任何用戶模式程序的段選擇器,您應該看到cs值為270x1b ),這意味着:

0000000000011     0         11
index 3 (code)   GDT   non-privileged

數據選擇器dsss ,...應存儲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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM