[英]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.