国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
保護(hù)模式簡(jiǎn)介
保護(hù)模式簡(jiǎn)介

轉(zhuǎn)自:http://www.pagoda-ooos.org/

在8086/8088時(shí)代,處理器只存在一種操作模式(Operation Mode),當(dāng)時(shí)由于不存在其它操作模式,因此這種模式也沒有被命名。自從80286到80386開始,處理器增加了另外兩種操作模式——保護(hù)模式PM(Protected Mode)和系統(tǒng)管理模式SMM(System Management Mode),因此,8086/8088的模式被命名為實(shí)地址模式RM(Real-address Mode)。

PM是處理器的native模式,在這種模式下,處理器支持所有的指令和所有的體系結(jié)構(gòu)特性,提供最高的性能和兼容性。對(duì)于所有的新型應(yīng)用程序和操作系統(tǒng)來說,建議都使用這種模式。為了保證PM的兼容性,處理器允許在受保護(hù)的,多任務(wù)的環(huán)境下執(zhí)行RM程序。這個(gè)特性被稱做虛擬8086模式(Virtual-8086 Mode),盡管它并不是一個(gè)真正的處理器模式。Virtual-8086模式實(shí)際上是一個(gè)PM的屬性,任何任務(wù)都可以使用它。

RM提供了Intel 8086處理器的編程環(huán)境,另外有一些擴(kuò)展(比如切換到PM或SMM的能力)。當(dāng)主機(jī)被Power-up或Reset后,處理器處于RM下。

SMM是一個(gè)對(duì)所有Intel處理器都統(tǒng)一的標(biāo)準(zhǔn)體系結(jié)構(gòu)特性。出現(xiàn)于Intel386 SL芯片。這個(gè)模式為OS實(shí)現(xiàn)平臺(tái)指定的功能(比如電源管理或系統(tǒng)安全)提供了一種透明的機(jī)制。當(dāng)外部的SMM interrupt pin(SMI#)被激活或者從APIC(Advanced Programming Interrupt Controller)收到一個(gè)SMI,處理器將進(jìn)入SMM。在SMM下,當(dāng)保存當(dāng)前正在運(yùn)行程序的整個(gè)上下文(Context)時(shí),處理器切換到一個(gè)分離的地址空間。然后SMM指定的代碼或許被透明的執(zhí)行。當(dāng)從SMM返回時(shí),處理器將回到被系統(tǒng)管理中斷之前的狀態(tài)。

由于機(jī)器在Power-up或Reset之后,處理器處于RM狀態(tài),而對(duì)于Intel 80386以及其后的芯片,只有使用PM才能發(fā)揮出最大的作用。所以我們就面臨著一個(gè)從RM切換到PM的問題。

本文不討論SMM,本節(jié)的重點(diǎn)集中于在Booting階段如何從RM切換到PM,這里不會(huì)過多的討論P(yáng)M的細(xì)節(jié),因?yàn)椤禝ntel Architecture Software Developer’s Manual Volume 3: System Programming》中有非常詳盡和準(zhǔn)確的介紹。

1. What is GDT

 

在Protected Mode下,一個(gè)重要的必不可少的數(shù)據(jù)結(jié)構(gòu)就是GDT(Global Descriptor Table)。
為什么要有GDT?我們首先考慮一下在Real Mode下的編程模型:

在Real Mode下,我們對(duì)一個(gè)內(nèi)存地址的訪問是通過Segment:Offset的方式來進(jìn)行的,其中Segment是一個(gè)段的Base Address,一個(gè)Segment的最大長(zhǎng)度是64 KB,這是16-bit系統(tǒng)所能表示的最大長(zhǎng)度。而Offset則是相對(duì)于此Segment Base Address的偏移量。Base Address+Offset就是一個(gè)內(nèi)存絕對(duì)地址。由此,我們可以看出,一個(gè)段具備兩個(gè)因素:Base Address和Limit(段的最大長(zhǎng)度),而對(duì)一個(gè)內(nèi)存地址的訪問,則是需要指出:使用哪個(gè)段?以及相對(duì)于這個(gè)段Base Address的Offset,這個(gè)Offset應(yīng)該小于此段的Limit。當(dāng)然對(duì)于16-bit系統(tǒng),Limit不要指定,默認(rèn)為最大長(zhǎng)度64KB,而16-bit的Offset也永遠(yuǎn)不可能大于此Limit。我們?cè)趯?shí)際編程的時(shí)候,使用16-bit段寄存器CS(Code Segment),DS(Data Segment),SS(Stack Segment)來指定Segment,CPU將段積存器中的數(shù)值向左偏移4-bit,放到20-bit的地址線上就成為20-bit的Base Address。

到了Protected Mode,內(nèi)存的管理模式分為兩種,段模式和頁模式,其中頁模式也是基于段模式的。也就是說,Protected Mode的內(nèi)存管理模式事實(shí)上是:純段模式和段頁式。進(jìn)一步說,段模式是必不可少的,而頁模式則是可選的——如果使用頁模式,則是段頁式;否則這是純段模式。

既然是這樣,我們就先不去考慮頁模式。對(duì)于段模式來講,訪問一個(gè)內(nèi)存地址仍然使用Segment:Offset的方式,這是很自然的。由于Protected Mode運(yùn)行在32-bit系統(tǒng)上,那么Segment的兩個(gè)因素:Base Address和Limit也都是32位的。IA-32允許將一個(gè)段的Base Address設(shè)為32-bit所能表示的任何值(Limit則可以被設(shè)為32-bit所能表示的,以2^12為倍數(shù)的任何指),而不象Real Mode下,一個(gè)段的Base Address只能是16的倍數(shù)(因?yàn)槠涞?-bit是通過左移運(yùn)算得來的,只能為0,從而達(dá)到使用16-bit段寄存器表示20-bit Base Address的目的),而一個(gè)段的Limit只能為固定值64 KB。另外,Protected Mode,顧名思義,又為段模式提供了保護(hù)機(jī)制,也就說一個(gè)段的描述符需要規(guī)定對(duì)自身的訪問權(quán)限(Access)。所以,在Protected Mode下,對(duì)一個(gè)段的描述則包括3方面因素:[Base Address, Limit, Access],它們加在一起被放在一個(gè)64-bit長(zhǎng)的數(shù)據(jù)結(jié)構(gòu)中,被稱為段描述符。這種情況下,如果我們直接通過一個(gè)64-bit段描述符來引用一個(gè)段的時(shí)候,就必須使用一個(gè)64-bit長(zhǎng)的段積存器裝入這個(gè)段描述符。但I(xiàn)ntel為了保持向后兼容,將段積存器仍然規(guī)定為16-bit(盡管每個(gè)段積存器事實(shí)上有一個(gè)64-bit長(zhǎng)的不可見部分,但對(duì)于程序員來說,段積存器就是16-bit的),那么很明顯,我們無法通過16-bit長(zhǎng)度的段積存器來直接引用64-bit的段描述符。

怎么辦?解決的方法就是把這些長(zhǎng)度為64-bit的段描述符放入一個(gè)數(shù)組中,而將段寄存器中的值作為下標(biāo)索引來間接引用(事實(shí)上,是將段寄存器中的高13-bit的內(nèi)容作為索引)。這個(gè)全局的數(shù)組就是GDT。事實(shí)上,在GDT中存放的不僅僅是段描述符,還有其它描述符,它們都是64-bit長(zhǎng),我們隨后再討論。

GDT可以被放在內(nèi)存的任何位置,那么當(dāng)程序員通過段寄存器來引用一個(gè)段描述符時(shí),CPU必須知道GDT的入口,也就是基地址放在哪里,所以Intel的設(shè)計(jì)者門提供了一個(gè)寄存器GDTR用來存放GDT的入口地址,程序員將GDT設(shè)定在內(nèi)存中某個(gè)位置之后,可以通過LGDT指令將GDT的入口地址裝入此積存器,從此以后,CPU就根據(jù)此積存器中的內(nèi)容作為GDT的入口來訪問GDT了。

GDT是Protected Mode所必須的數(shù)據(jù)結(jié)構(gòu),也是唯一的——不應(yīng)該,也不可能有多個(gè)。另外,正象它的名字(Global Descriptor Table)所揭示的,它是全局可見的,對(duì)任何一個(gè)任務(wù)而言都是這樣。

除了GDT之外,IA-32還允許程序員構(gòu)建與GDT類似的數(shù)據(jù)結(jié)構(gòu),它們被稱作LDT(Local Descriptor Table),但與GDT不同的是,LDT在系統(tǒng)中可以存在多個(gè),并且從LDT的名字可以得知,LDT不是全局可見的,它們只對(duì)引用它們的任務(wù)可見,每個(gè)任務(wù)最多可以擁有一個(gè)LDT。另外,每一個(gè)LDT自身作為一個(gè)段存在,它們的段描述符被放在GDT中。

IA-32為L(zhǎng)DT的入口地址也提供了一個(gè)寄存器LDTR,因?yàn)樵谌魏螘r(shí)刻只能有一個(gè)任務(wù)在運(yùn)行,所以LDT寄存器全局也只需要有一個(gè)。如果一個(gè)任務(wù)擁有自身的LDT,那么當(dāng)它需要引用自身的LDT時(shí),它需要通過LLDT將其LDT的段描述符裝入此寄存器。LLDT指令與LGDT指令不同的時(shí),LGDT指令的操作數(shù)是一個(gè)32-bit的內(nèi)存地址,這個(gè)內(nèi)存地址處存放的是一個(gè)32-bit GDT的入口地址,以及16-bit的GDT Limit。而LLDT指令的操作數(shù)是一個(gè)16-bit的選擇子,這個(gè)選擇子主要內(nèi)容是:被裝入的LDT的段描述符在GDT中的索引值——這一點(diǎn)和剛才所討論的通過段積存器引用段的模式是一樣的。

LDT只是一個(gè)可選的數(shù)據(jù)結(jié)構(gòu),你完全可以不用它。使用它或許可以帶來一些方便性,但同時(shí)也帶來復(fù)雜性,如果你想讓你的OS內(nèi)核保持簡(jiǎn)潔性,以及可移植性,則最好不要使用它。

引用GDT和LDT中的段描述符所描述的段,是通過一個(gè)16-bit的數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)的,這個(gè)數(shù)據(jù)結(jié)構(gòu)叫做Segment Selector——段選擇子。它的高13位作為被引用的段描述符在GDT/LDT中的下標(biāo)索引,bit 2用來指定被引用段描述符被放在GDT中還是到LDT中,bit 0和bit 1是RPL——請(qǐng)求特權(quán)等級(jí),被用來做保護(hù)目的,我們這里不詳細(xì)討論它。

前面所討論的裝入段寄存器中作為GDT/LDT索引的就是Segment Selector,當(dāng)需要引用一個(gè)內(nèi)存地址時(shí),使用的仍然是Segment:Offset模式,具體操作是:在相應(yīng)的段寄存器裝入Segment Selector,按照這個(gè)Segment Selector可以到GDT或LDT中找到相應(yīng)的Segment Descriptor,這個(gè)Segment Descriptor中記錄了此段的Base Address,然后加上Offset,就得到了最后的內(nèi)存地址。如下圖所示:

2. Setup GDT

由上一節(jié)的討論得知,GDT是Protected Mode所必須的數(shù)據(jù)結(jié)構(gòu),那么我們?cè)谶M(jìn)入Protected Mode之前,必須設(shè)定好GDT,并通過LGDT將其裝入相應(yīng)的寄存器。

盡管GDT允許被放在內(nèi)存的任何位置,但由于GDT中的元素——描述符——都是64-bit長(zhǎng),也就是說都是8個(gè)字節(jié),所以為了讓CPU對(duì)GDT的訪問速度達(dá)到最快,我們應(yīng)該將GDT的入口地址放在以8個(gè)字節(jié)對(duì)齊,也就是說是8的倍數(shù)的地址位置。

GDT中第一個(gè)描述符必須是一個(gè)空描述符,也就是它的內(nèi)容應(yīng)該全部為0。如果引用這個(gè)描述符進(jìn)行內(nèi)存訪問,則是產(chǎn)生General Protection異常。

如果一個(gè)OS不使用虛擬內(nèi)存,段模式會(huì)是一個(gè)不錯(cuò)的選擇。但現(xiàn)代OS沒有不使用虛擬內(nèi)存的,而實(shí)現(xiàn)虛擬內(nèi)存的比較方便和有效的內(nèi)存管理方式是頁式管理。但是在IA-32上如果我們想使用頁式管理,我們只能使用段頁式——沒有方法可以完全禁止段模式。但我們可以盡力讓段的效果降低的最小。

IA-32提供了一種被稱作“Basic Flat Model”的分段模式可以達(dá)到這種效果。這種模式要求在GDT中至少要定義兩個(gè)段描述符,一個(gè)用來引用Data Segment,另一個(gè)用來引用Code Segment。這2個(gè)Segment都包含整個(gè)線性空間,即Segment Limit = 4 GB,即使實(shí)際的物理內(nèi)存遠(yuǎn)沒有那么多,但這個(gè)空間定義是為了將來由頁式管理來實(shí)現(xiàn)虛擬內(nèi)存。

在這里,我們只是處于Booting階段,所以我們只需要初步設(shè)置一下GDT,等真正進(jìn)入Protected Mode,啟動(dòng)了OS Kernel之后,具體OS打算如何設(shè)置GDT,使用何種內(nèi)存管理模式,由Kernel自身來設(shè)置,Booting只需要給Kernel的數(shù)據(jù)段和代碼段設(shè)置全部線性空間就可以了。

段描述符的格式如下圖所示:

具體到代碼段和數(shù)據(jù)段,它們的格式如下圖所示:

下面就是在Booting階段為進(jìn)入Protected Mode而設(shè)置的臨時(shí)的gdt。這里定義了3個(gè)段描述符:第一個(gè)是系統(tǒng)規(guī)定的空描述符,第2個(gè)是引用4 GB線性空間的代碼段,第3個(gè)是引用4 GB線性空間的數(shù)據(jù)段。這是"Basic Flat Model"所要求的最下GDT設(shè)置,但就booting階段,只是為了進(jìn)入Protected Mode,并為內(nèi)核提供一個(gè)連續(xù)的,最大的線性空間這個(gè)目的而言,已經(jīng)足夠了。

# Descriptor tables

gdt:
.word 0, 0, 0, 0 # dummy

.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 # base address = 0
.word 0x9A00 # code read/exec
.word 0x00CF # granularity = 4096, 386
# (+5th nibble of limit)

.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 # base address = 0
.word 0x9200 # data read/write
.word 0x00CF # granularity = 4096, 386
# (+5th nibble of limit)

 

3. Load GDT

設(shè)置好GDT之后,我們需要通過LGDT指令將設(shè)定的gdt的入口地址和gdt表的大小裝入GDTR寄存器。

 

GDTR寄存器包括兩部分:32-bit的線性基地址,以及16-bit的GDT大?。ㄒ宰止?jié)為單位)。需要注意的是,對(duì)于32-bit線性基地址,必須是32-bit絕對(duì)物理地址,而不是相對(duì)于某個(gè)段的偏移量。而我們?cè)贐ooting階段,在進(jìn)入Protected Mode之前,我們CS和DS設(shè)置很可能不是0,所以我們必須計(jì)算出gdt的絕對(duì)物理地址。

 

為了執(zhí)行LGDT指令,你需要把這兩部分內(nèi)容放在內(nèi)存的某個(gè)位置,然后將這個(gè)位置的內(nèi)存地址作為操作數(shù)傳遞給LGDT指令。然后LGDT指令會(huì)自動(dòng)將保存在這個(gè)位置的這兩部分值裝入GDTR寄存器。

# 這是存放GDTR所需的兩部分內(nèi)容的位置

gdt_48:
.word 0x8000 # gdt limit=2048,

# 256 GDT entries

.word 0, 0 # gdt base (filled in later)

# 下面這段代碼用來計(jì)算GDT的32-bit線性地址,并將其裝入GDTR寄存器。

xorl %eax, %eax # Compute gdt_base
movw %ds, %ax # (Convert %ds:gdt to a linear ptr)
shll $4, %eax
addl $gdt, %eax
movl %eax, (gdt_48+2)
lgdt gdt_48 # load gdt with whatever is appropriate

4. Other Preparing Stuff

 

在進(jìn)入Protected Mode之前,除了需要設(shè)置和裝入GDT之外,還需要做如下一些事情:
屏蔽所有可屏蔽中斷;
裝入IDTR;
所有協(xié)處理器被正確的Reset。
由于在Real Mode和Protected Mode下的中斷處理機(jī)制有一些不同,所以在進(jìn)入Protected Mode之前,務(wù)必禁止所有可屏蔽中斷,這可以通過下面兩種方法之一:

使用CLI指令;
對(duì)8259A可編程中斷控制器編程以屏蔽所有中斷。
即使當(dāng)我們進(jìn)入Protected Mode之后,也不能馬上將中斷打開,這時(shí)因?yàn)槲覀儽仨氃贠S Kernel中對(duì)相關(guān)的Protected Mode中斷處理所需的數(shù)據(jù)結(jié)構(gòu)正確的初始化之后,才能打開中斷,否則會(huì)產(chǎn)生處理器異常。

在Real Mode下,中斷處理使用IVT(Interrupt Vector Table),在Protected Mode下,中斷處理使用IDT(Interrupt Descriptor Table),所以,我們必須在進(jìn)入Protected Mode之前設(shè)置IDTR。

IDTR的格式和GDTR相同,IDTR的裝入方式和GDTR也相同。由于IDT中相關(guān)的中斷處理程序需要讓OS Kernel來設(shè)定,所以在Booting階段,我們只需要將IDTR中IDT的基地址和Size都設(shè)為0就可以了,隨后,等進(jìn)入Protected Mode之后,由OS Kernel來真正設(shè)置它。

關(guān)于中斷機(jī)制和中斷處理,請(qǐng)參考 Interrupt & Exception ,這里不再贅述。

 

#

# 這是存放IDTR所需的兩部分內(nèi)容的位置

#

idt_48:
.word 0 # idt limit = 0
.word 0, 0 # idt base = 0L

 

# 對(duì)于IDTR的處理,只需要這一條指令即可

lidt idt_48 # load idt with 0,0

 

#

# 通過設(shè)置8259A PIC,屏蔽所有可屏蔽中斷

#

movb $0xFF, %al # mask all interrupts for now
outb %al, $0xA1
call delay

movb $0xFB, %al # mask all irq‘s but irq2 which
outb %al, $0x21 # is cascaded

 

# 保證所有的協(xié)處理都被正確的Reset

xorw %ax, %ax
outb %al, $0xf0
call delay

outb %al, $0xf1
call delay

 

# Delay is needed after doing I/O

delay:
outb %al,$0x80
ret


5. Let‘s Go

好了,一切準(zhǔn)備就緒,F(xiàn)ire!:)

進(jìn)入Protected Mode,還是進(jìn)入Real Mode,完全靠CR0寄存器的PE標(biāo)志位來控制:如果PE=1,則CPU切換到PM,否則,則進(jìn)入RM。

設(shè)置CR0-PE位的方法有兩種:

第一種是80286所使用的LMSW指令,后來的80386及更高型號(hào)的CPU為了保持向后兼容,都保留了這個(gè)指令。這個(gè)指令只能影響最低的4 bit,即PE,MP,EM和TS,對(duì)其它的沒有影響。

 

#

#通過LMSW指令進(jìn)入Protected Mode

#

movw $1, %ax # protected mode (PE) bit

lmsw %ax # This is it!

 

第二種是Intel所建議的在80386以后的CPU上使用的進(jìn)入PM的方式,即通過MOV指令。MOV指令可以設(shè)置CR0寄存器的所有域的值。

#

#通過MOV指令進(jìn)入Protected Mode

#

movl %cr0, %eax

xorb $1, %al # set PE = 1

movl %eax, %cr0 # go!!

 

OK,現(xiàn)在已經(jīng)進(jìn)入Protected Mode了。

 

很簡(jiǎn)單,right?But It‘s not over yet!

 


6. Start Kernel

我們已經(jīng)從Real Mode進(jìn)入Protected Mode,現(xiàn)在我們馬上就要啟動(dòng)OS Kernel了。

OS Kernel運(yùn)行在32-bit段模式,而當(dāng)前我們卻仍然處于16-bit段模式。這是怎么回事?為了了解這個(gè)問題,我們需要仔細(xì)探討一下IA-32的段模式的實(shí)現(xiàn)方法。

IA-32共提供了6個(gè)16-bit段寄存器:CS,DS,SS,ES,F(xiàn)S,GS。但事實(shí)上,這16-bit只是對(duì)程序員可見的部分,但每個(gè)寄存器仍然包括64-bit的不可見部分。

可見部分是為了供程序員裝載段寄存器,但一旦裝載完成,CPU真正使用的就只是不可見部分,可見部分就完全沒有用了。

不可見部分存放的內(nèi)容是什么?具體格式我沒有看到相關(guān)資料,但可以確定的是隱藏部分的內(nèi)容和段描述符的內(nèi)容是一致的(請(qǐng)參考段描述的格式),只不過格式可能不完全相同。但格式對(duì)我們理解這一點(diǎn)并不重要,因?yàn)槌绦騿T不可能能夠直接操作它。

我們以CS寄存器為例,對(duì)于其它寄存器也是一樣的:

在Real Mode下,當(dāng)我們執(zhí)行一個(gè)裝載CS寄存器的指令的時(shí)候(jmp,call,ret等),相關(guān)的值會(huì)被裝入CS寄存器的可見部分,但同時(shí)CPU也會(huì)根據(jù)可見部分的內(nèi)容來設(shè)置不可見部分。比如我們執(zhí)行"ljmp $0x1234, $go "之后,CS寄存器的可見部分的內(nèi)容就是1234h,同時(shí),不可見部分的32-bit Base Address域被設(shè)置為00001234h,20-bit的Limit域被設(shè)置為固定值10000h,也就是64 KB,Access Information部分的其它值我們不去考慮,只考慮其D/B位,由于執(zhí)行此指令時(shí)處于Real Mode模式,所以D/B被設(shè)置為0,表示此段是一個(gè)16-bit段。當(dāng)對(duì)CS寄存器的可見部分和不可見部分的內(nèi)容都被設(shè)置之后,CS寄存器的裝載工作完成。隨后當(dāng)CPU需要通過CS的內(nèi)容進(jìn)行地址運(yùn)算的時(shí)候,則僅僅引用不可見部分。

在Protected Mode下,當(dāng)我們執(zhí)行一個(gè)裝載CS寄存器的指令的時(shí)候,段選擇子(Segment Selector)被裝入CS寄存器的可見部分,同時(shí)CPU根據(jù)此選擇子到相應(yīng)的描述符表中(GDT或LDT)找到相應(yīng)的段描述符并將其內(nèi)容裝載入CS寄存器的不可見部分。隨后CPU當(dāng)需要通過CS的內(nèi)容進(jìn)行地址運(yùn)算的時(shí)候,也僅僅引用不可見部分。

從上面的描述可以看出,事實(shí)上CPU在引用段寄存器的內(nèi)容進(jìn)行地址運(yùn)算時(shí),Real Mode和Protected Mode是一致的。另外,也明白了為什么我們?cè)赗eal Mode下設(shè)置的段寄存器的內(nèi)容到了Protected Mode下仍然引用的是16-bit段。

那么我們?nèi)绾螌S設(shè)置為引用32-bit段?方法就像我們前面所討論的,使用jmp或call指令,引用一個(gè)段選擇子,到GDT中裝載一個(gè)引用32-bit段的段描述符。

需要注意的是,如果CS寄存器的內(nèi)容指出當(dāng)前是一個(gè)16-bit段,那么當(dāng)前的地址模式也就是16-bit地址模式,這與你當(dāng)前是出于Real Mode還是Protected Mode無關(guān)。而我們裝載32-bit段的jmp指令或call指令必須使用的是32-bit地址模式。而我們當(dāng)前的boot部分代碼是16-bit代碼,所以我們必須在此jmp/call指令前加上地址轉(zhuǎn)換前綴代碼66h。

下面的例子就是使用jmp指令裝入32-bit段。Jmpi指令的含義是段間跳轉(zhuǎn),其Opcode為Eah,其格式為:jmpi Offset, Segment Selector。

# 由于當(dāng)前的代碼是16-bit代碼,而我們要執(zhí)行32-bit地址模式的指令,指令前

# 需要有地址模式切換前綴66h,如果我們直接寫jmp指令,由編譯器來生成代碼

# 的話,是無法作到這一點(diǎn)的,所以我們直接寫相關(guān)數(shù)據(jù)。

  .byte 0x66, 0xea # prefix + jmpi-opcode

  .long 0x1000  # Offset
  .word __KERNEL_CS # CS segment selector

上面的代碼相當(dāng)于32-bit指令:

jmpi 0x1000,__KERNEL_CS

如果__KERNEL_CS段選擇子所引用的段描述符設(shè)置的段空間為線形地址[0,4 GB],而我們將OS Kernel放在物理地址1000h,那么此jmpi指令就跳轉(zhuǎn)到OS Kernel的入口處,并開始執(zhí)行它。

此時(shí),Booting階段結(jié)束,OS正式開始運(yùn)行!

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
保護(hù)模式Protected Mode 簡(jiǎn)寫為 pmode
Windows內(nèi)存管理
80x86保護(hù)模式系列教程(三.控制寄存器和系統(tǒng)地址寄存器)
Linux內(nèi)存管理圖解
Linux系統(tǒng)中段機(jī)制的實(shí)現(xiàn)
總結(jié)一下linux中的分段機(jī)制
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服