日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

80386的分段机制、分页机制和物理地址的形成

發(fā)布時(shí)間:2024/8/5 综合教程 32 生活家
生活随笔 收集整理的這篇文章主要介紹了 80386的分段机制、分页机制和物理地址的形成 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


MOVE REG,ADDR ;
它把地址為ADDR(假設(shè)為10000)的內(nèi)存單元的內(nèi)容復(fù)制到REG 中


在8086 的實(shí)模式下,把某一段寄存器(段基址)左移4 位,然后與地址ADDR 相加后被直接送到內(nèi)
存總線上,這個(gè)相加后的地址(20位)就是內(nèi)存單元的物理地址,而程序中的這個(gè)地址ADDR就叫邏輯地址
(或叫虛地址)。


在80386 的段機(jī)制中,邏輯地址由兩部分組成,即
段部分(選擇符)
及偏移部分。

段是形成邏輯地址到線性地址轉(zhuǎn)換的基礎(chǔ)。如果我們把段看成一個(gè)對(duì)象的話,那么對(duì)它
的描述如下。

(1)段的基地址(Base Address):在線性地址空間中段的起始地址。

(2)段的界限(Limit):表示在邏輯地址中,段內(nèi)可以使用的最大偏移量。

(3)段的屬性(Attribute): 表示段的特性。例如,該段是否可被讀出或?qū)懭耄蛘?br /> 該段是否作為一個(gè)程序來執(zhí)行,以及段的特權(quán)級(jí)等。


1、邏輯地址、線性地址和物理地址





所謂
描述符(Descriptor)
,就是描述段的屬性的一個(gè)8 字節(jié)存儲(chǔ)單元。


2、用戶段描述符(Descriptor)




一個(gè)段描述符指出了段的32 位基地址和20 位段界限(即段大小)。
第6 個(gè)字節(jié)的G 位是粒度位,當(dāng)G=0 時(shí),段長表示段格式的字節(jié)長度,即一個(gè)段最長可
達(dá)1M 字節(jié)。當(dāng)G=1 時(shí),段長表示段的以4K 字節(jié)為一頁的頁的數(shù)目,即一個(gè)段最長可達(dá)
1M×4K=4G 字節(jié)。D 位表示缺省操作數(shù)的大小,如果D=0,操作數(shù)為16 位,如果D=1,操作數(shù)
為32 位。


第7 位P 位(Present) 是存在位,表示段描述符描述的這個(gè)段是否在內(nèi)存中,如果在
內(nèi)存中。P=1;如果不在內(nèi)存中,P=0。


DPL(Descriptor Privilege Level)
,就是描述符特權(quán)級(jí),它占兩位,其值為0~3,
用來確定這個(gè)段的特權(quán)級(jí)即保護(hù)等級(jí)。0為內(nèi)核級(jí)別,3為用戶級(jí)別。


S 位(System)表示這個(gè)段是系統(tǒng)段還是用戶段。如果S=0,則為系統(tǒng)段,如果S=1,則
為用戶程序的代碼段、數(shù)據(jù)段或堆棧段。


類型占3 位,第3 位為E 位,表示段是否可執(zhí)行。當(dāng)E=0 時(shí),為數(shù)據(jù)段描述符,這時(shí)的
第2 位ED 表示地址增長方向。
第1 位(W)是可寫位

當(dāng)段為代碼段時(shí),第3 位E=1,這時(shí)第2 位為一致位(C)。當(dāng)C=1 時(shí),如果當(dāng)前特權(quán)級(jí)
低于描述符特權(quán)級(jí),并且當(dāng)前特權(quán)級(jí)保持不變,那么代碼段只能執(zhí)行。所謂當(dāng)前特權(quán)級(jí)
CPL
(Current Privilege Level)
,就是當(dāng)前正在執(zhí)行的任務(wù)的特權(quán)級(jí)。第1 位為可讀位R


存取權(quán)字節(jié)的第0 位A 位是訪問位,用于請(qǐng)求分段不分頁的系統(tǒng)中,每當(dāng)該段被訪問時(shí),
將A 置1。對(duì)于分頁系統(tǒng),則A 被忽略未用。


3、系統(tǒng)段描述符

系統(tǒng)段描述符的第5 個(gè)字節(jié)的第4 位為0,說明它是系統(tǒng)段描述符,類型占
4 位,沒有A 位。第6 個(gè)字節(jié)的第6 位為0,說明系統(tǒng)段的長度是字節(jié)粒度,所以,一個(gè)系統(tǒng)
段的最大長度為1M 字節(jié)。

系統(tǒng)段的類型為16 種,如圖2.15 所示。
在這16 種類型中,保留類型和有關(guān)286 的類型不予考慮。
門也是一種描述符,有調(diào)用門、任務(wù)門、中斷門和陷阱門4 種門描述符




4、選擇符、描述符表和描述符表寄存器


描述符表(即段表)定義了386 系統(tǒng)的所有段的情況。所有的描述符表本身都占據(jù)一個(gè)
字節(jié)為8 的倍數(shù)的存儲(chǔ)器空間,空間大小在8 個(gè)字節(jié)(至少含一個(gè)描述符)到64K 字節(jié)(至
多含8K=8192)個(gè)描述符之間。


1.全局描述符表(GDT)

全局描述符表GDT(Global Descriptor Table),除了任務(wù)門,中斷門和陷阱門描述符
外,包含著系統(tǒng)中所有任務(wù)都共用的那些段的描述符。它的第一個(gè)8 字節(jié)位置沒有使用。


2.中斷描述符表(IDT)

中斷描述符表IDT(Interrupt Descriptor Table),包含256 個(gè)門描述符。IDT 中只
能包含任務(wù)門、中斷門和陷阱門描述符,雖然IDT 表最長也可以為64K 字節(jié),但只能存取2K
字節(jié)以內(nèi)的描述符,即256 個(gè)描述符,這個(gè)數(shù)字是為了和8086 保持兼容。


3.局部描述符表(LDT)

局部描述符表LDT(Local Descriptor Table),包含了與一個(gè)給定任務(wù)有關(guān)的描述符,
每個(gè)任務(wù)各自有一個(gè)的LDT。有了LDT,就可以使給定任務(wù)的代碼、數(shù)據(jù)與別的任務(wù)相隔離。
每一個(gè)任務(wù)的局部描述符表LDT 本身也用一個(gè)描述符來表示,稱為LDT 描述符,它包含

了有關(guān)局部描述符表的信息,被放在全局描述符表GDT 中,使用LDTR進(jìn)行索引。


在實(shí)模式下,段寄存器存儲(chǔ)的是真實(shí)的段基址,在保護(hù)模式下,16 位的段寄存器無法放
下32 位的段基址,因此,它們被稱為選擇符,即段寄存器的作用是用來選擇描述符。選擇符
的結(jié)構(gòu)如圖2.16 所示。


可以看出,選擇符有3 個(gè)域:第15~3 位這13 位是索引域,表示的數(shù)據(jù)為0~8129,用于
指向全局描述符表中相應(yīng)的描述符。第2 位為選擇域,如果TI=1,就從局部描述符表中選擇
相應(yīng)的描述符,如果TI=0,就從全局描述符表中選擇描述符。第1、0 位是特權(quán)級(jí),表示選
擇符的特權(quán)級(jí),被稱為請(qǐng)求者特權(quán)級(jí)
RPL(Requestor Privilege Level
)。只有請(qǐng)求者特權(quán)
級(jí)RPL 高于(數(shù)字低于)或等于相應(yīng)的描述符特權(quán)級(jí)DPL,描述符才能被存取,這就可以實(shí)
現(xiàn)一定程度的保護(hù)。


下面講一下在沒有分頁操作時(shí),尋址一個(gè)存儲(chǔ)器操作數(shù)的步驟。


(1)在段選擇符中裝入16 位數(shù),同時(shí)給出32 位地址偏移量(比如在ESI、EDI 中等)。


(2)先根據(jù)相應(yīng)描述符表寄存器中的段地址(
確定描述符表的地址
)和
段界限
(確定描述符表的大小)
,根據(jù)段選擇符的TI決定從哪種描述符表中取,再根據(jù)段選擇符的索引找到相應(yīng)段描述符的位置
,比較RPL與DPL,若該段無問題,就取出相應(yīng)的段
描述符放入段描述符高速緩沖寄存器中。


(3)將段描述符中的32 位段基地址和放在ESI、EDI 等中的32 位有效地址相加,就形成
了32 位物理地址。



5、linux中的段機(jī)制


從2.2 版開始,Linux 讓所有的進(jìn)程(或叫任務(wù))都使用相同的邏輯地址空間,因此就
沒有必要使用局部描述符表LDT。


Linux 在啟動(dòng)的過程中設(shè)置了段寄存器的值和全局描述符表GDT 的內(nèi)容,段寄存器的定義在
include/asm-i386/segment.h 中:


C++ Code

1

2

3

4

5

#define__KERNEL_CS0x10
//內(nèi)核代碼段,index=2,TI=0,RPL=0

#define__KERNEL_DS0x18
//內(nèi)核數(shù)據(jù)段,index=3,TI=0,RPL=0

#define__USER_CS0x23
//用戶代碼段,index=4,TI=0,RPL=3

#define__USER_DS0x2B
//用戶數(shù)據(jù)段,index=5,TI=0,RPL=3


從定義看出,沒有定義堆棧段,實(shí)際上,Linux 內(nèi)核不區(qū)分?jǐn)?shù)據(jù)段和堆棧段,這也體現(xiàn)
了Linux 內(nèi)核盡量減少段的使用。因?yàn)闆]有使用LDT,因此,TI=0,并把這4 個(gè)段描述符都放在GDT
中, index 就是某個(gè)段描述符在GDT 表中的下標(biāo)。內(nèi)核代碼段和數(shù)據(jù)段具有最高特權(quán),因此其RPL

為0,而用戶代碼段和數(shù)據(jù)段具有最低特權(quán),因此其RPL 為3。


全局描述符表的定義在arch/i386/kernel/head.S 中:


C++ Code

1

2

3

4

5

6

7

8

9

10

ENTRY(gdt_table)

.quad0x0000000000000000
/*NULLdescriptor*/

.quad0x0000000000000000
/*notused*/

.quad0x00cf9a000000ffff
/*0x10kernel4GBcodeat0x00000000*/

.quad0x00cf92000000ffff
/*0x18kernel4GBdataat0x00000000*/

.quad0x00cffa000000ffff
/*0x23user4GBcodeat0x00000000*/

.quad0x00cff2000000ffff
/*0x2buser4GBdataat0x00000000*/

.quad0x0000000000000000
/*notused*/

.quad0x0000000000000000
/*notused*/


從代碼可以看出,GDT 放在數(shù)組變量gdt_table 中。按Intel 規(guī)定,GDT 中的第一項(xiàng)為
空,這是為了防止加電后段寄存器未經(jīng)初始化就進(jìn)入保護(hù)模式而使用GDT 的。第二項(xiàng)也沒用。
從下標(biāo)2~5 共4 項(xiàng)對(duì)應(yīng)于前面的4 種段描述符值。對(duì)照?qǐng)D2.10,從描述符的數(shù)值可以得出:


• 段的基地址全部為0x00000000;

• 段的上限全部為0xffff;

• 段的粒度G 為1,即段長單位為4KB;

• 段的D 位為1,即對(duì)這4 個(gè)段的訪問都為32 位指令;

• 段的P 位為1,即4 個(gè)段都在內(nèi)存。


由此可以得出,每個(gè)段的邏輯地址空間范圍為0~4GB。
每個(gè)段的基地址為0,因此,邏輯地
址到線性地址映射保持不變,也就是說,
偏移量就是線性地址
,我們以后所提到的邏輯地址
(或虛擬地址)和線性地址指的也就是同一地址。看來,Linux 巧妙地把段機(jī)制給繞過去了,
它只把段分為兩種:用戶態(tài)(RPL
=3)的段和內(nèi)核態(tài)(RPL=0)的段,
而完全利用了分頁機(jī)制。


按Intel 的規(guī)定,每個(gè)進(jìn)程有一個(gè)任務(wù)狀態(tài)段(TSS)和局部描述符表LDT,但Linux 也
沒有完全遵循Intel 的設(shè)計(jì)思路。如前所述,Linux 的進(jìn)程沒有使用LDT,而對(duì)TSS 的使用也
非常有限,每個(gè)CPU 僅使用一個(gè)TSS。
TSS 有它自己 8 字節(jié)的任務(wù)段描述符(Task State Segment Descriptor ,簡(jiǎn)稱
TSSD)。這個(gè)描述符包括指向TSS 起始地址的32 位基地址域,20 位界限域,界限域值不能小
于十進(jìn)制104(由TSS 段的最小長度決定)。TSS 描述符存放在GDT 中,它是GDT 中的一個(gè)表
項(xiàng),由中斷描述符表(IDT)中的任務(wù)門(存放TSS段的選擇符)裝入TR來進(jìn)行索引。



7、頁目錄項(xiàng)、頁表項(xiàng)、頁面項(xiàng)


80386 使用4K 字節(jié)大小的頁。每一頁都有4K 字節(jié)長,并在4K 字節(jié)的邊界上對(duì)齊,即每
一頁的起始地址都能被4K 整除。因此,80386 把4G 字節(jié)的線性地址空間,劃分為1G 個(gè)頁面,
每頁有4K 字節(jié)大小。分頁機(jī)制通過把線性地址空間中的頁,重新定位到物理地址空間來進(jìn)行
管理,因?yàn)槊總€(gè)頁面的整個(gè)4K 字節(jié)作為一個(gè)單位進(jìn)行映射,并且每個(gè)頁面都對(duì)齊4K 字節(jié)的
邊界,因此,線性地址的低12 位經(jīng)過分頁機(jī)制直接地作為物理地址的低12 位使用。


頁目錄表

存儲(chǔ)在一個(gè)4K 字節(jié)的頁面中,
最多可包含1024 個(gè)
頁目錄項(xiàng)
,每個(gè)頁目錄項(xiàng)為4 個(gè)字節(jié),結(jié)
構(gòu)如圖2.22 所示。




第31~12 位是20 位頁表地址,由于頁表地址的低12 位總為0,所以用高20 位指出
32 位頁表地址就可以了。


第0 位是存在位,如果P=1,表示頁表地址指向的該頁在內(nèi)存中,如果P=0,表示不
在內(nèi)存中。



第1 位是讀/寫位,第2 位是用戶/管理員位,這兩位為頁目錄項(xiàng)提供硬件保護(hù)。當(dāng)特
權(quán)級(jí)為3 的進(jìn)程要想訪問頁面時(shí),需要通過頁保護(hù)檢查,而特權(quán)級(jí)為0 的進(jìn)程就可以繞過頁
保護(hù),如圖2.23 所示。



第3 位是PWT(Page Write-Through)位,表示是否采用寫透方式,寫透方式就是既
寫內(nèi)存(RAM)也寫高速緩存,該位為1 表示采用寫透方式。
第4 位是PCD(Page Cache Disable)位,表示是否啟用高速緩存,該位為1 表示啟
用高速緩存。



第5 位是訪問位,當(dāng)對(duì)頁目錄項(xiàng)進(jìn)行訪問時(shí),A 位=1。


第7 位是Page Size 標(biāo)志,只適用于頁目錄項(xiàng)。如果置為1,頁目錄項(xiàng)指的是4MB 的
頁面,即擴(kuò)展分頁。


80386 的每個(gè)頁目錄項(xiàng)指向一個(gè)
頁表

存儲(chǔ)在一個(gè)4K 字節(jié)的頁面中,
頁表最多含有1024 個(gè)
頁面項(xiàng)
,每項(xiàng)4 個(gè)字節(jié),包
含頁面的起始地址和有關(guān)該頁面的信息。頁面的起始地址也是4K 的整數(shù)倍,所以頁面的低
12 位也留作它用,如圖2.24 所示。



第31~12 位是
20 位物理頁面地址
,除第6 位外第0~5 位及9~11 位的用途和頁目錄
項(xiàng)一樣,第6 位是頁面項(xiàng)獨(dú)有的,當(dāng)對(duì)涉及的頁面進(jìn)行寫操作時(shí),D 位被置1。

4GB 的存儲(chǔ)器只有一個(gè)頁目錄,它最多有1024 個(gè)頁目錄項(xiàng),每個(gè)頁目錄項(xiàng)又含有1024
個(gè)頁面項(xiàng),因此,存儲(chǔ)器一共可以分成1024×1024=1M 個(gè)頁面。由于每個(gè)頁面為4K 個(gè)字節(jié),
所以,存儲(chǔ)器的大小正好最多為4GB。


當(dāng)訪問一個(gè)操作單元時(shí),如何由分段結(jié)構(gòu)確定的32 位線性地址通過分頁操作轉(zhuǎn)化成32
位物理地址呢?


第一步,CR3 包含著頁目錄的起始地址,用32 位線性地址的最高10 位A31~A22 作為頁
目錄表的頁目錄項(xiàng)的索引,將它乘以4,與CR3 中的頁目錄表的起始地址相加,形成相應(yīng)頁目錄項(xiàng)的
地址。


第二步,從指定的地址中取出32 位頁目錄項(xiàng),它的低12 位為0,這32 位是頁表的起始
地址。用32 位線性地址中的A21~A12 位作為頁表中的頁表項(xiàng)的索引,將它乘以4,與頁表的起
始地址相加,形成相應(yīng)頁表項(xiàng)的地址。


第三步,從指定地址中取出32位頁表項(xiàng),它的低12位為0,這32位是頁面地址,將A11~A0 作為相對(duì)于頁面地址的偏移量,與32 位頁面地址相加,形成32 位
物理地址。




8、linux 中的分頁機(jī)制


Linux 的分段機(jī)制使得所有的進(jìn)程都使用相同的段寄存器值,這就使得內(nèi)存管理變得
簡(jiǎn)單,也就是說,所有的進(jìn)程都使用同樣的線性地址空間(0~4GB)。
Linux 采用三級(jí)分頁模式而不是兩級(jí)
。如圖2.28 所示為三級(jí)分頁模式,為此,Linux
定義了3 種類型的表。


• 總目錄PGD(Page Global Directory)

• 中間目錄PMD(Page Middle Derectory)

• 頁表PT(Page Table)




總結(jié)

以上是生活随笔為你收集整理的80386的分段机制、分页机制和物理地址的形成的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。