加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

圖文詳解 Linux 分頁(yè)機(jī)制!

2023/05/30
2339
閱讀需 9 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

分頁(yè)機(jī)制是 80x86 內(nèi)存管理機(jī)制的第二種機(jī)制,分段機(jī)制用于把虛擬地址轉(zhuǎn)換為線性地址,而分頁(yè)機(jī)制用于把線性地址轉(zhuǎn)換為物理地址。分頁(yè)機(jī)制可以用于任何一種分段機(jī)制,也可以理解為先有分段機(jī)制才有分頁(yè)機(jī)制,這是由于歷史原因,分段機(jī)制要比分頁(yè)機(jī)制更輕,先出現(xiàn)的分段后出現(xiàn)的分頁(yè)。

處理器的分頁(yè)機(jī)制用于把線性地址劃分成一個(gè)個(gè)的頁(yè)面,這些劃分成頁(yè)面的線性地址會(huì)被映射到物理空間的頁(yè)面上。

我們知道分段的保護(hù)措施有兩種,一種是利用任務(wù)之間的保護(hù);一種是利用內(nèi)存段和寄存器之間的保護(hù)。

分頁(yè)機(jī)制有幾種頁(yè)面級(jí)的保護(hù)措施,分段機(jī)制和保護(hù)措施可以和分頁(yè)機(jī)制的保護(hù)措施一起使用,也可以使用分頁(yè)機(jī)制的保護(hù)措施替換分段機(jī)制的保護(hù)。

比如分頁(yè)機(jī)制可以在頁(yè)面的基礎(chǔ)上加強(qiáng)讀/寫(xiě)保護(hù)。另外,在頁(yè)面單元上,分頁(yè)機(jī)制還提供了用戶和超級(jí)用戶兩級(jí)保護(hù)。

分頁(yè)機(jī)制可以通過(guò) CR0 控制寄存器的 PG 這個(gè)標(biāo)志位來(lái)判斷是否開(kāi)啟分頁(yè)機(jī)制;如果 PG = 1 ,則表示啟用分頁(yè)操作,處理器會(huì)使用本節(jié)描述的機(jī)制將線性地址轉(zhuǎn)換為物理地址。如果 PG = 0,則表示禁用分頁(yè)機(jī)制,此時(shí)分段產(chǎn)生的線性地址會(huì)被直接用作物理地址。

分段機(jī)制和分頁(yè)機(jī)制還有一個(gè)區(qū)別就是:分段機(jī)制可以在任意可變長(zhǎng)度的內(nèi)存上進(jìn)行操作,而分頁(yè)機(jī)制只能對(duì)固定大小的頁(yè)面(內(nèi)存塊)進(jìn)行操作。分頁(yè)機(jī)制把線性和物理地址空間都劃分成頁(yè)面。線性地址空間中的頁(yè)面都可以映射在物理地址空間內(nèi),如下圖所示。

80x86 使用 4K (2 ^ 12) 字節(jié)固定大小的頁(yè)面,每個(gè)頁(yè)面均是 4KB,并且對(duì)齊于 4KB 地址邊界處。這表示分頁(yè)機(jī)制會(huì)把 4GB 劃分成為以 4KB 為基礎(chǔ)的頁(yè)面,共劃分 1M(1048576) 個(gè),線性地址的低 12 bit 位可以直接作為頁(yè)內(nèi)偏移量,也可直接作為物理地址的低 12 位。

現(xiàn)在我們知道線性地址空間會(huì)經(jīng)過(guò)分頁(yè)機(jī)制映射到物理內(nèi)存空間上,這是一個(gè)正常能夠映射到的情況,如果映射不到怎么辦?也就是說(shuō)包含線性地址空間的頁(yè)面不在物理內(nèi)存中怎么辦?此時(shí)處理器就會(huì)產(chǎn)生一個(gè)頁(yè)錯(cuò)誤異常。頁(yè)錯(cuò)誤異常的處理程序會(huì)讓操作系統(tǒng)從磁盤(pán)中把相應(yīng)的頁(yè)面加載到物理內(nèi)存中。當(dāng)頁(yè)面加載到物理內(nèi)存中后,會(huì)從異常處理程序中返回,使得處于異常指令的位置繼續(xù)向下執(zhí)行指令。

頁(yè)錯(cuò)誤異常是分頁(yè)機(jī)制實(shí)現(xiàn)換入換出過(guò)程中出現(xiàn)頻次非常高的一種異常機(jī)制,它就好像 bug 一樣如影隨形,而且頻繁的頁(yè)面換入換出操作會(huì)很耗費(fèi)處理器資源,所以為了減少頻繁換入換出的操作,采用了一種局部性原理的方式:把經(jīng)常訪問(wèn)的頁(yè)目錄和相關(guān)頁(yè) "保存" 起來(lái),這里采用了一種硬件實(shí)現(xiàn),即轉(zhuǎn)換查找緩沖區(qū)(Translation Lookaside Buffer)。有了 TLB,處理器會(huì)先從 TLB 中查找相關(guān)頁(yè),TLB 中不存在的頁(yè)才會(huì)從內(nèi)存中進(jìn)行讀取,此時(shí)的 TLB 相當(dāng)于是內(nèi)存的一個(gè)副本。

頁(yè)表結(jié)構(gòu)

頁(yè)表中每個(gè)頁(yè)表項(xiàng)的大小為 32 位,其中 20 位來(lái)存放物理基地址,剩余的 12 位存放可用于存放頁(yè)面是否存在等屬性信息。如果線性地址索引的頁(yè)表項(xiàng)被標(biāo)注為存在,則表示該項(xiàng)有效,我們可以從中取得物理地址;如果線性地址索引的頁(yè)表項(xiàng)不存在,那么訪問(wèn)物理頁(yè)面就會(huì)產(chǎn)生異常。

下面是一個(gè)線性地址到物理地址的變換過(guò)程圖。

可以看到,80x86 使用了兩級(jí)頁(yè),這是為了減少頁(yè)的數(shù)量所設(shè)計(jì)的,因?yàn)殡m然每個(gè)頁(yè)字節(jié)是 4K,共有 2 ^ 20 (1MB)個(gè)頁(yè),總共占據(jù) 4MB 大小,但實(shí)際上應(yīng)用程序一次用不到這么多頁(yè),會(huì)造成資源浪費(fèi),所以采用了一種分層的設(shè)計(jì)方式。

第一級(jí)稱為頁(yè)目錄(page directory),它被存放在 1 個(gè) 4K 頁(yè)面中,因?yàn)橐还灿?2 ^ 10 次方(1 MB)個(gè)頁(yè)目錄,每個(gè)目錄是 4 字節(jié),所以是在一個(gè) 4K 頁(yè)面中。線性地址的最高十位(22 - 31 位)用作一級(jí)表(頁(yè)目錄)中的索引來(lái)訪問(wèn)二級(jí)表。

第二級(jí)稱為頁(yè)表(page table,它和頁(yè)目錄一樣,也是占據(jù)一個(gè)頁(yè)面,最多含有 1K 個(gè) 4 字節(jié)的頁(yè)表。頁(yè)表項(xiàng)會(huì)存儲(chǔ) 20 位的物理地址,線性地址中的 12 - 21 位作為頁(yè)表的索引,用于獲取含有 20 位物理地址的頁(yè)表項(xiàng)。頁(yè)表項(xiàng)的 20 位物理基地址和線性地址中的低 12 位一起合成最終的 32 位物理地址。

頁(yè)表項(xiàng)結(jié)構(gòu)

現(xiàn)在我們知道線性地址的低 12 位和頁(yè)表存儲(chǔ)的 20 位可以合成物理地址,頁(yè)表項(xiàng)除了能夠存儲(chǔ)地址外,還有一些其他的屬性,下面是頁(yè)表項(xiàng)的結(jié)構(gòu)圖。

這里需要特別注意的是,頁(yè)目錄的結(jié)構(gòu)和頁(yè)表的結(jié)構(gòu)是一樣的,只不過(guò)他倆描述的主體不一樣,一個(gè)描述的是頁(yè)目錄,一個(gè)描述的是頁(yè)表。

    P -- 位 0 是存在(Present)標(biāo)志,用于指明表項(xiàng)對(duì)地址轉(zhuǎn)換是否有效。P = 1 表示有效,P = 0 表示無(wú)效,在頁(yè)的轉(zhuǎn)換過(guò)程中,如果說(shuō)涉及的頁(yè)目錄或頁(yè)表的表項(xiàng)無(wú)效,也就是頁(yè)面沒(méi)有再物理地址中,就會(huì)產(chǎn)生一個(gè)異常。如果 P = 0 ,那么除了表項(xiàng)無(wú)效外,其余的 bit 位可以自由使用。R/W -- 位 1 是讀/寫(xiě)(Read/Write)標(biāo)志,當(dāng) R/W = 1 時(shí),表示該頁(yè)可以被讀、寫(xiě)和執(zhí)行;當(dāng) R/W = 0 時(shí),表示該頁(yè)只讀或可執(zhí)行;當(dāng)處理器運(yùn)行在超級(jí)用戶權(quán)限下(0、1、2)時(shí),此位不會(huì)發(fā)生作用。U/S -- 位 2 是用戶/超級(jí)用戶(User/Supervisor)標(biāo)識(shí),如果此位為 0 ,表示任意特權(quán)級(jí)下面的應(yīng)用程序都可以訪問(wèn),如果此位為 1 ,那么頁(yè)面只能允許在特權(quán)級(jí)為 0、1、2 也就是超級(jí)用戶特權(quán)級(jí)下才能訪問(wèn)。A -- 位 5 是已訪問(wèn)(Accessed)標(biāo)志,此位僅用于統(tǒng)計(jì)頁(yè)面的訪問(wèn)情況,如果頁(yè)面已經(jīng)訪問(wèn)過(guò),就會(huì)置 1,但是操作系統(tǒng)會(huì)通過(guò)定期復(fù)位來(lái)重置此標(biāo)識(shí)位。D -- 位 6 是頁(yè)面已修改(Dirty)標(biāo)志,也就是我們常說(shuō)的"臟位",當(dāng)處理器對(duì)頁(yè)面執(zhí)行寫(xiě)操作時(shí),就會(huì)設(shè)置對(duì)應(yīng)頁(yè)面的 D 標(biāo)志。AVL -- 保留字段,這個(gè)字段專門(mén)提供給程序使用。

根據(jù)上面字段的描述,可以看到頁(yè)目錄和頁(yè)表項(xiàng)中的 P 位為分頁(yè)技術(shù)的虛擬存儲(chǔ)提供了必要的標(biāo)識(shí),若線性地址空間中的頁(yè)面存在于物理內(nèi)存中,那么對(duì)應(yīng)的表項(xiàng) P = 1,并且該表項(xiàng)中含有相應(yīng)的物理地址。頁(yè)面不在物理內(nèi)存中的表項(xiàng) P = 0 。如果程序訪問(wèn)物理內(nèi)存中不存在的頁(yè)面,處理器就會(huì)產(chǎn)生一個(gè)缺頁(yè)異常。此時(shí)操作系統(tǒng)就會(huì)利用這個(gè)異常把缺少的頁(yè)面從磁盤(pán)調(diào)入內(nèi)存,把相應(yīng)的物理地址放在表項(xiàng)中,返回程序繼續(xù)執(zhí)行引起異常的指令并且設(shè)置 P = 1。

A 和 D 這兩個(gè)標(biāo)志位是實(shí)現(xiàn)虛擬存儲(chǔ)的基礎(chǔ),這兩個(gè)標(biāo)志位可以定期檢測(cè)指定的頁(yè)面是否訪問(wèn)過(guò)并且是否可以讀寫(xiě),從而判斷哪些頁(yè)面可以移出到磁盤(pán)。比如一個(gè)頁(yè)面從磁盤(pán)讀入內(nèi)存后,它的 D 標(biāo)志位為 0 ,那么當(dāng)頁(yè)被移除磁盤(pán)時(shí),它的 D 位還是 0 的話,就可以判斷這個(gè)頁(yè)面無(wú)需調(diào)入磁盤(pán)。D = 1 表示頁(yè)面已經(jīng)被修改過(guò),就需要將其寫(xiě)回到磁盤(pán)上。

 

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

cxuan 寫(xiě)的文章還不錯(cuò)。會(huì)分享計(jì)算機(jī)底層、計(jì)算機(jī)網(wǎng)絡(luò)、操作系統(tǒng),Java基礎(chǔ)、框架、源碼等文章。