亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

蟲蟲首頁| 資源下載| 資源專輯| 精品軟件
登錄| 注冊

您現(xiàn)在的位置是:首頁 > 技術(shù)閱讀 >  為什么要分頁?如何分頁?分頁后地址如何轉(zhuǎn)化?

為什么要分頁?如何分頁?分頁后地址如何轉(zhuǎn)化?

時間:2024-02-12

喵哥技術(shù)交流群發(fā)現(xiàn)了很多水平很高的朋友,歡迎大家來加喵哥微信,進(jìn)群一起討論計算機(jī)知識!

程序喵大人微信

分頁機(jī)制是內(nèi)存管理系統(tǒng)里很重要的一部分,但是分頁機(jī)制卻是在內(nèi)存管理系統(tǒng)建立之前啟用的。本文圍繞分頁機(jī)制展開,講述分頁機(jī)制的特點,分頁機(jī)制是如何啟用的,以及地址轉(zhuǎn)化的問題。提綱導(dǎo)圖如下:


01

邏輯地址,線性地址,虛擬地址,物理地址傻傻分不清?

在了解分頁機(jī)制之前,得先清楚各類地址的含義。

邏輯地址

IA-32架構(gòu)下,分段是必須的,而分頁并不是必須的不論分頁與否,訪問內(nèi)存都必須采用“段基址:段內(nèi)偏移地址”的策略。


因此訪問內(nèi)存需要16&32共48位的地址信息,這便是邏輯地址,高12位為段選擇子,后面32位為段內(nèi)偏移地址。


線性地址

使用選擇子索引到段描述符取得32位的段基址,與邏輯地址內(nèi)的32位段內(nèi)偏移地址相加后,得到一個32位的地址信息,這便是線性地址。


虛擬地址

如果不啟用分頁機(jī)制,線性地址就是物理地址,而如果啟用分頁機(jī)制的話,線性地址又叫做虛擬地址。


物理地址

物理地址,不用多說,內(nèi)存單元的真正地址。


01

為什么分頁?

分頁的本質(zhì)就是將各種大小不同的內(nèi)存段拆分成大小相同的內(nèi)存塊(通常4KB),以便進(jìn)行內(nèi)存管理的一種機(jī)制。


在純分段情況下會出現(xiàn)許多問題,如應(yīng)用程序過多,或者內(nèi)存碎片過多而無法容納新進(jìn)程;又或者重新加載某內(nèi)存段(之前交換出去的)時,找不到合適的內(nèi)存區(qū)域。


造成這情況的原因:只分段的情況下,線性地址就是物理地址,兩者都是連續(xù)的,不夠靈活,不可能每次都能找到合適的內(nèi)存區(qū)域。而分頁的話,線性地址需要進(jìn)一步轉(zhuǎn)化為物理地址,線性地址是連續(xù)的,但是物理地址可以不連續(xù)。


這意味著可以在物理內(nèi)存上隨便(不是真隨便,有塊大小限制)找塊地,只要線性地址和物理地址建立起映射關(guān)系就好。這樣的話尋找合適的內(nèi)存區(qū)域時就很靈活,解決了上述問題。


03

分頁機(jī)制

頁表(基于32位)

分頁機(jī)制的核心是實現(xiàn)虛擬地址到物理地址的轉(zhuǎn)化,如何轉(zhuǎn)化呢?靠的是頁表將虛擬地址和物理地址建立起映射關(guān)系,有了這映射關(guān)系,便可將虛擬地址轉(zhuǎn)化成實際的物理地址。


總的思想是:將虛擬地址的高20位視作索引號,在頁表中進(jìn)行索引頁表項,得到物理基址,將其與虛擬地址的低12位偏移地址相加后便得到最后的物理地址。


這也是一級頁表下虛擬地址轉(zhuǎn)化為物理地址的方式,然而一級頁表并不適用,一般會使用多級頁表。下面以二級頁表為例講解,先看其表項結(jié)構(gòu):


頁目錄項,頁表項

頁目錄項和頁表項的結(jié)構(gòu)以及屬性位簡介如下:


二級頁表地址轉(zhuǎn)換

二級頁表下虛擬地址到物理地址轉(zhuǎn)化的原理與一級頁表下轉(zhuǎn)化的原理相同,只是多進(jìn)行了一步轉(zhuǎn)化。具體流程先看圖:


第一步:使用段選擇子去GDT中索引段描述符,“取出”段基址,段部件將段基址與偏移地址相加得到線性地址,也即虛擬地址。


第二步:將虛擬地址的高10位作為索引號,索引頁目錄表中的頁目錄項,具體操作:將虛擬地址高10位乘4加上CR3中的頁目錄物理地址,得到所要的頁目錄項的地址,即a+0x4*4。


第三步:將虛擬地址的中10位作為索引號索引二級頁表中的頁表項,具體操作:“取出”頁目錄項中的20位頁表物理地址,即0x1000。再加上虛擬地址中10位乘4,得到物理頁地址,即0x1000+0x234*4。


第四步:虛擬地址的后12位偏移地址和第三步得到的物理頁地址相加得到最后實際的物理地址。如圖中所示:0xfa000+0x567=0xfa567為最后target的物理地址。


以上就是二級頁表下地址轉(zhuǎn)化的過程,三級乃至多級頁表下地址轉(zhuǎn)化的方法都一樣,不過是多重復(fù)了第三步的操作。


注:分頁機(jī)制的作用是將虛擬地址轉(zhuǎn)化為物理地址,但在實際轉(zhuǎn)化的過程中相當(dāng)于在關(guān)閉分頁機(jī)制條件下進(jìn)行的。即地址轉(zhuǎn)化的過程中涉及的地址(CR3中頁目錄地址,頁目錄項地址,頁表項地址)都是實際的物理地址,不會被分頁機(jī)制繼續(xù)轉(zhuǎn)化,否則的話會無限遞歸下去。


為什么一級頁表不適用?

1個4B大小的頁表項指向4K的頁面,映射整個4G空間的話需要4G / 4K = 1M 個頁表項,因此整個頁表大小為4M。


一個進(jìn)程便需要4M大小的頁表,如果說有很多進(jìn)程則會花費許多內(nèi)存來儲存頁表。再者這還只是32位的系統(tǒng),內(nèi)存空間只有232B = 4GB,若是64位系統(tǒng),則需要 264 / 212 = 252個頁表項 ,那簡直不可想象。


多級頁表為什么比一級頁表省空間?

首先頁表就是一個整體,一級頁表下4M(32位)的頁表就是一個整體,需要全部創(chuàng)建,所以每個進(jìn)程都要有4M的頁表,這樣的話頁表所占用的空間的確很多。


多級頁表只會為進(jìn)程實際使用的那部分虛擬內(nèi)存建立頁表,只用一級頁表需要建立所有的頁表項,而多級頁表只建立了需要的頁表,如此當(dāng)然更省空間。

那為什么多級頁表下就只需要建立需要的那部分頁表呢?


多級頁表相當(dāng)于對一級頁表再次進(jìn)行分頁,將一張大頁表拆成了多張小頁表,以后想用幾張便做幾張,這樣就很靈活而且省空間。


操作系統(tǒng)虛擬內(nèi)存管理系統(tǒng)對物理頁的分配也是這么實現(xiàn)的,只有某個虛擬地址需要一張新頁表來映射時,才會為它分配物理頁,這就做到了需要才建立的原則,因而比一級頁表更省空間。


04

如何建立分頁機(jī)制?(大致思路,與實際操作系統(tǒng)可能有出入)

分頁機(jī)制是計算機(jī)啟動時進(jìn)行的,可以算是操作系統(tǒng)加載器的工作,建立起用分頁機(jī)制大致要做以下幾件事情:


1、建立初始頁表,計算機(jī)啟動時是在 1M 的實模式下工作,頁表的建立相對來說較簡單。而建立頁表就是建立映射關(guān)系,建立映射關(guān)系就是添加頁表項。操作系統(tǒng)內(nèi)核的虛擬地址在0xc0000000以上,而最開始我們工作的地址是在物理內(nèi)存的低端1M,所以這里的映射關(guān)系為將物理內(nèi)存的低端1M映射到虛擬地址空間的0xc0000000以上。


2、GDT,內(nèi)核棧等等都應(yīng)放在內(nèi)核中,需要修改其地址值,還有一些描述符中的段基址也需要修改,因為原來記錄的地址是實際的物理地址,啟用分頁后應(yīng)采用虛擬地址。


3、把頁目錄地址賦給CR3寄存器。


4、將CR0寄存器的PE位置1,開啟分頁機(jī)制。


5、地址轉(zhuǎn)換的第一步就是去GDT中找段基址,現(xiàn)GDT發(fā)生了變化,需要使用 lgdt 指令重新加載GDT。


至此便啟用了分頁機(jī)制,隨后系統(tǒng)運行中出現(xiàn)的地址都是虛擬地址,需要經(jīng)過上述圖中所示的轉(zhuǎn)化來獲得實際的物理地址。


05

分頁的缺點?如何解決?

分頁雖然很靈活,但是需要做多次計算,多次訪問內(nèi)存。每一個虛擬地址都要重復(fù)上述操作的話,處理器的負(fù)擔(dān)過重,時間也花費過多。


如何解決呢?利用局部性原理為地址轉(zhuǎn)換建立了一個高速緩存,TLB,俗稱快表。有了TLB,處理器在尋址之前會先利用虛擬地址的高20位在TLB中查找相應(yīng)條目,如果命中,則返回虛擬地址所映射的物理頁地址,否則便去查詢頁表,找到相應(yīng)物理頁地址后再更新TLB。


C++學(xué)習(xí)資料免費獲取方法:關(guān)注程序喵大人,后臺回復(fù)“程序喵”即可免費獲取40萬字C++進(jìn)階獨家學(xué)習(xí)資料。





往期推薦


1、少寫點
if-else吧,它的效率有多低你知道嗎?
2、年度原創(chuàng)好文匯總
3、全網(wǎng)首發(fā)!!C++20新特性全在這一張圖里了
4
他來了,他來了,C+
+17新特性精華都在這了
5、一文讓你搞懂設(shè)計模式
6、C++11新特性,所有知識點都在這了!


主站蜘蛛池模板: 彝良县| 伊宁市| 阿拉尔市| 成都市| 岑巩县| 治多县| 佛山市| 宜昌市| 张北县| 贞丰县| 成武县| 连江县| 府谷县| 苗栗市| 正定县| 延吉市| 汾西县| 颍上县| 敦化市| 阿瓦提县| 孟连| 如皋市| 敦煌市| 天气| 会东县| 项城市| 深州市| 连州市| 黔东| 泸州市| 高州市| 无为县| 浠水县| 黄山市| 工布江达县| 黎平县| 太保市| 大宁县| 秦安县| 阜阳市| 普兰店市|