內(nèi)存系列學(xué)習(xí)(一):萬(wàn)字長(zhǎng)文帶你搞定MMU-u0026TLB-u0026TWU(內(nèi)存udimm)
前言
Hi,早?。∽屛铱纯粗苣┻€在偷偷學(xué)習(xí)卷我的人是誰(shuí)?【狗頭】
最近一直在學(xué)習(xí)內(nèi)存管理,也知道MMU是管理內(nèi)存的映射的邏輯IP,還知道里面有個(gè)TLB。
今天剛剛好看到了幾篇前輩的文章,很是不錯(cuò),于是這里來(lái)一起學(xué)習(xí)一下吧。
PART 一:MMU 架構(gòu)篇
MMU(Memory Management Unit,內(nèi)存管理單元)是一種硬件模塊,用于在CPU和內(nèi)存之間實(shí)現(xiàn)虛擬內(nèi)存管理。
其主要功能是將虛擬地址轉(zhuǎn)換為物理地址,同時(shí)提供訪問(wèn)權(quán)限的控制和緩存管理等功能。
放在整個(gè)大系統(tǒng)多核架構(gòu)里面,每個(gè)處理器內(nèi)置了MMU模塊,MMU模塊包含了TLB和TWU兩個(gè)子模塊。
1-宏觀理解
地址空間是一個(gè)抽象的概念,由CPU體系架構(gòu)的地址總線決定,一般等同于CPU的尋址范圍、x位處理器中的x。地址空間一般分為 虛擬地址空間 和 物理地址空間 。
任何時(shí)候,計(jì)算機(jī)上都存在一個(gè)程序能夠訪問(wèn)的地址集合,我們稱之為地址空間。這個(gè)空間的大小由CPU的位數(shù)決定,例如一個(gè)32位的CPU,它的地址范圍是0 ~ 0xFFFFFFFF(4G),而對(duì)于一個(gè)64位的CPU,它的地址范圍為0 ~ 0xFFFFFFFFFFFFFFFF。
這個(gè)空間就是我們的程序能夠產(chǎn)生的地址范圍,我們把這個(gè)地址范圍稱為 虛擬地址空間 ,該空間中的某一個(gè)地址我們稱之為虛擬地址。與虛擬地址空間和虛擬地址相對(duì)應(yīng)的則是物理地址空間和物理地址,大多數(shù)時(shí)候我們的系統(tǒng)所具備的物理地址空間只是虛擬地址空間的一個(gè)子集。
舉一個(gè)例子,對(duì)于一臺(tái)內(nèi)存為 256MB的 32bit x86主機(jī)來(lái)說(shuō),它的虛擬地址空間范圍是 0 ~ 0xFFFFFFFF(4G),而物理地址空間范圍是 0x000000000 ~ 0x0FFFFFFF(256MB)。
為什么需要這樣的轉(zhuǎn)換呢?其實(shí)這個(gè)就是現(xiàn)在多進(jìn)程多線程、以及解決內(nèi)存碎片化的途徑。這里就不展開了。
虛擬地址又被簡(jiǎn)稱為虛地址,物理地址又被稱為實(shí)地址。虛擬地址和物理地址之間的轉(zhuǎn)換,又稱為虛實(shí)地址轉(zhuǎn)化。
而這個(gè)轉(zhuǎn)換的過(guò)程是硬件執(zhí)行的:虛擬地址不是被直接送到內(nèi)存地址總線上,而是送到內(nèi)存管理單元MMU。他由一個(gè)或一組芯片組成,一般存在與協(xié)處理器中,其功能是把虛擬地址映射為物理地址。
2-微觀理解
內(nèi)存管理單元(MMU)的一個(gè)重要功能是使系統(tǒng)能夠運(yùn)行多個(gè)任務(wù),作為獨(dú)立的程序運(yùn)行在他們自己的 私有虛擬內(nèi)存空間。
它們不需要了解系統(tǒng)的物理內(nèi)存圖,即硬件實(shí)際使用的地址,也不需要了解可能在同一時(shí)間執(zhí)行的其他程序。
所以在這種時(shí)候其實(shí)也要注意,你到底是使用的物理內(nèi)存還是虛擬內(nèi)存,使用的同一片內(nèi)存,會(huì)不會(huì)出現(xiàn)踩踏內(nèi)存的現(xiàn)象。
你可以為每個(gè)程序使用相同的虛擬內(nèi)存地址空間。
你也可以使用一個(gè)連續(xù)的虛擬內(nèi)存地圖,即使物理內(nèi)存是碎片化的。
這個(gè)虛擬地址空間與系統(tǒng)中的實(shí)際物理內(nèi)存地圖是分開的。
你可以編寫、編譯和鏈接應(yīng)用程序以在虛擬內(nèi)存空間中運(yùn)行。
如下圖所示的內(nèi)存虛擬和物理視圖的系統(tǒng)實(shí)例,一個(gè)系統(tǒng)中的不同處理器和設(shè)備可能有不同的虛擬和物理地址圖。
操作系統(tǒng)對(duì)MMU進(jìn)行編程,在這兩個(gè)內(nèi)存視圖之間進(jìn)行轉(zhuǎn)換。
要做到這一點(diǎn),虛擬內(nèi)存系統(tǒng)中的硬件必須提供地址轉(zhuǎn)換,即把處理器發(fā)出的虛擬地址轉(zhuǎn)換為主內(nèi)存中的物理地址。
虛擬地址是你、編譯器和鏈接器在內(nèi)存中放置代碼時(shí)使用的地址。
物理地址是由實(shí)際的硬件系統(tǒng)使用的。
MMU使用虛擬地址的最重要的位來(lái)索引映射表中的條目,并確定哪個(gè)塊被訪問(wèn)。
MMU將代碼和數(shù)據(jù)的虛擬地址映射成實(shí)際系統(tǒng)中的物理地址。
這種轉(zhuǎn)換是在硬件中自動(dòng)進(jìn)行的,對(duì)應(yīng)用程序是透明的。
除了地址轉(zhuǎn)換外,MMU還控制內(nèi)存訪問(wèn)權(quán)限、內(nèi)存排序和每個(gè)區(qū)域內(nèi)存的緩存策略。
(安全地址與非安全地址的訪問(wèn)控制權(quán)限,檢查頁(yè)標(biāo)簽)
MMU使任務(wù)或應(yīng)用程序的編寫方式要求它們對(duì)系統(tǒng)的物理內(nèi)存圖或可能同時(shí)運(yùn)行的其他程序一無(wú)所知。這使你可以為每個(gè)程序使用相同的虛擬內(nèi)存地址空間。
它還允許你使用一個(gè)連續(xù)的虛擬內(nèi)存地圖,即使物理內(nèi)存是碎片化的。這個(gè)虛擬地址空間與系統(tǒng)中的實(shí)際物理內(nèi)存地圖是分開的。應(yīng)用程序被編寫、編譯和鏈接以在虛擬內(nèi)存空間中運(yùn)行。
這個(gè)就回到了我之前說(shuō)的這個(gè)MMU本質(zhì)上提供的能力。
1-CPU發(fā)出的虛擬地址
CPU發(fā)出的虛擬地址由兩部分組成:VPN和offset,VPN(virtual page number)是頁(yè)表中的條目number,而offset是指頁(yè)內(nèi)偏移。
最終轉(zhuǎn)換后的物理地址也有兩部分:PFN和offset,PFN( Physical frame number)是物理頁(yè)框number,offset和上面虛擬地址的offset相同,是頁(yè)內(nèi)偏移。
2-MMU包含兩個(gè)模塊
MMU包含兩個(gè)模塊TLB(Translation Lookaside Buffer)和TWU(Table Walk Unit)。
TLB是一個(gè)高速緩存,用于緩存頁(yè)表轉(zhuǎn)換的結(jié)果,從而縮短頁(yè)表查詢的時(shí)間。
TWU是一個(gè)頁(yè)表遍歷模塊,頁(yè)表是由操作系統(tǒng)維護(hù)在物理內(nèi)存中,但是頁(yè)表的遍歷查詢是由TWU完成的,這樣減少對(duì)CPU資源的消耗。
MMU由兩部分組成:TLB(Translation Lookaside Buffer)和table walk unit。TLB 是一種地址轉(zhuǎn)換Cache,這里我們略過(guò)TLB的工作細(xì)節(jié)。
table walk unit在不同的CPU架構(gòu)上有不同的叫法,但其作用是相同的,就是把內(nèi)存頁(yè)表走一走進(jìn)行查表,完成虛擬地址到物理地址的轉(zhuǎn)換。
3-訪問(wèn)權(quán)限控制
TrustZone技術(shù)之所以能提高系統(tǒng)的安全性,是因?yàn)閷?duì)外部資源和內(nèi)存資源的硬件隔離。這些硬件隔離包括中斷隔離、片上RAM和ROM的隔離、片外RAM和ROM的隔離、外圍設(shè)備的硬件隔離、外部RAM和ROM的隔離等。
實(shí)現(xiàn)硬件層面的各種隔離,需要對(duì)整個(gè)系統(tǒng)的硬件和處理器核做出相應(yīng)的擴(kuò)展。這些擴(kuò)展包括:
-
? □ 對(duì)處理器核的虛擬化,也就是將AMR處理器的運(yùn)行狀態(tài)分為安全態(tài)和非安全態(tài)。
? □ 對(duì)總線的擴(kuò)展,增加安全位讀寫信號(hào)線。
? □ 對(duì)內(nèi)存管理單元(Memory Management Unit, MMU)的擴(kuò)展,增加頁(yè)表的安全位。
? □ 對(duì)緩存(cache)的擴(kuò)展,增加安全位。
? □ 對(duì)其他外圍組件進(jìn)行了相應(yīng)的擴(kuò)展,提供安全操作權(quán)限控制和安全操作信號(hào)。
在支持TrustZone的SoC上,會(huì)對(duì)MMU進(jìn)行虛擬化,使得寄存器TTBR0、TTBR1、TTBCR在安全狀態(tài)和非安全狀態(tài)下是相互隔離的,因此兩種狀態(tài)下的虛擬地址轉(zhuǎn)換表是獨(dú)立的。
存放在MMU中的每一條頁(yè)表描述符都會(huì)包含一個(gè)安全狀態(tài)位,用以表示被映射的內(nèi)存是屬于安全內(nèi)存還是非安全內(nèi)存。
虛擬化的MMU共享轉(zhuǎn)換監(jiān)測(cè)緩沖區(qū)(Translation Lookaside Buffer, TLB),同樣TLB中的每一項(xiàng)也會(huì)打上安全狀態(tài)位標(biāo)記,只不過(guò)該標(biāo)記是用來(lái)表示該條轉(zhuǎn)換是正常世界狀態(tài)轉(zhuǎn)化的還是安全世界狀態(tài)轉(zhuǎn)化的。
Cache也同樣進(jìn)行了擴(kuò)展,Cache中的每一項(xiàng)都會(huì)按照安全狀態(tài)和非安全狀態(tài)打上對(duì)應(yīng)的標(biāo)簽,在不同的狀態(tài)下,處理器只能使用對(duì)應(yīng)狀態(tài)下的Cache。
在REE(linux)和TEE(optee)雙系統(tǒng)的環(huán)境下,可同時(shí)開啟兩個(gè)系統(tǒng)的MMU。在secure和non-secure中使用不同的頁(yè)表.secure的頁(yè)表可以映射non-secure的內(nèi)存,而non-secure的頁(yè)表不能去映射secure的內(nèi)存,否則在轉(zhuǎn)換時(shí)會(huì)發(fā)生錯(cuò)誤:
在EL2系統(tǒng)中,MMU地址轉(zhuǎn)換時(shí),會(huì)自動(dòng)使用TTBR2_EL1指向的頁(yè)表。
在EL3系統(tǒng)中,MMU地址轉(zhuǎn)換時(shí),會(huì)自動(dòng)使用TTBR3_EL1指向的頁(yè)表。
4-啟用hypervisor
如果啟用了hypervisor那么虛擬地址轉(zhuǎn)換的過(guò)程將有VA—>PA變成了VA—>IPA—>PA, 也就是要經(jīng)過(guò)兩次轉(zhuǎn)換.在guestos(如linux kernel)中轉(zhuǎn)換的物理地址,其實(shí)不是真實(shí)的物理地址(假物理地址),然后在EL2通過(guò)VTTBR0_EL2基地址的頁(yè)表轉(zhuǎn)換后的物理地址,才是真實(shí)的硬件地址。
IPA : intermediate physical address
5-MMU與C15協(xié)處理器
在ARM嵌入式應(yīng)用系統(tǒng)中, 很多系統(tǒng)控制由ARM CP15協(xié)處理器來(lái)完成的。CP15協(xié)處理器包含編號(hào)0-15的16個(gè)32位的寄存器。例如,ARM處理器使用C15協(xié)處理器的寄存器來(lái)控制cache、TCM(Tightly-Coupled Memory)和存儲(chǔ)器管理。
在這些C15寄存器中和MMU關(guān)系較大的有C2、C7、C17寄存器。
Memory protection and control registers,內(nèi)存保護(hù)和控制寄存器,包含
-
? Translation Table Base Register 0 (TTBR0)、
? Translation Table Base Register 1 (TTBR1)
? Translation Table Base Control Register (TTBCR)。
TTBR0、TTBR1是L1轉(zhuǎn)換頁(yè)表的基地址,
TTCR控制TTBR0和TTBR1的使用。
-
? CP15 C7寄存器 Cache and branch predictor maintenance functions、Data and instruction barrier operations用于高速緩存和寫緩存控制。
? CP15 C13寄存器 Context ID Register (CONTEXTIDR)、Software thread ID registers用于保存進(jìn)程標(biāo)識(shí)符(asid地址空間編號(hào))
6-TLB緩存
1-為什么要有TLB
TLB 是 translation lookaside buffer 的簡(jiǎn)稱。首先,我們知道 MMU 的作用是把虛擬地址轉(zhuǎn)換成物理地址。
虛擬地址和物理地址的映射關(guān)系存儲(chǔ)在頁(yè)表中,而現(xiàn)在頁(yè)表又是分級(jí)的。
64 位系統(tǒng)一般都是 3~5 級(jí)。
常見的配置是 4 級(jí)頁(yè)表,就以 4 級(jí)頁(yè)表為例說(shuō)明。
分別是 PGD、PUD、PMD、PTE 四級(jí)頁(yè)表。
在硬件上會(huì)有一個(gè)叫做頁(yè)表基地址寄存器,它存儲(chǔ) PGD 頁(yè)表的首地址。
MMU 就是根據(jù)頁(yè)表基地址寄存器從 PGD 頁(yè)表一路查到 PTE,最終找到物理地址(PTE頁(yè)表中存儲(chǔ)物理地址)。
這就像在地圖上顯示你的家在哪一樣,我為了找到你家的地址,先確定你是中國(guó),再確定你是某個(gè)省,繼續(xù)往下某個(gè)市,最后找到你家是一樣的原理。一級(jí)一級(jí)找下去。(這個(gè)比喻真的不錯(cuò))
這個(gè)過(guò)程你也看到了,非常繁瑣。如果第一次查到你家的具體位置,我如果記下來(lái)你的姓名和你家的地址。下次查找時(shí),是不是只需要跟我說(shuō)你的姓名是什么,我就直接能夠告訴你地址,而不需要一級(jí)一級(jí)查找。
四級(jí)頁(yè)表查找過(guò)程需要四次內(nèi)存訪問(wèn)。延時(shí)可想而知,非常影響性能。頁(yè)表查找過(guò)程的示例如下圖所示。以后有機(jī)會(huì)詳細(xì)展開,這里了解下即可。
2-TLB 的本質(zhì)是什么
TLB 其實(shí)就是一塊高速緩存。
數(shù)據(jù) cache 緩存地址(虛擬地址或者物理地址)和數(shù)據(jù)。TLB 緩存虛擬地址和其映射的物理地址。TLB 根據(jù)虛擬地址查找 cache,它沒(méi)得選,只能根據(jù)虛擬地址查找。
所以 TLB 是一個(gè)虛擬高速緩存。硬件存在 TLB 后,虛擬地址到物理地址的轉(zhuǎn)換過(guò)程發(fā)生了變化。虛擬地址首先發(fā)往 TLB 確認(rèn)是否命中 cache,如果 cache hit 直接可以得到物理地址。
否則,一級(jí)一級(jí)查找頁(yè)表獲取物理地址。并將虛擬地址和物理地址的映射關(guān)系緩存到 TLB 中。
7-TWU
table walk unit:包含從內(nèi)存中讀取translation tables的邏輯
一個(gè)完整的頁(yè)表翻譯和查找的過(guò)程叫作頁(yè)表查詢(Translation Table Walk),頁(yè)表查詢的過(guò)程由硬件自動(dòng)完成,但是頁(yè)表的維護(hù)需要軟件來(lái)完成。
頁(yè)表查詢是一個(gè)相對(duì)耗時(shí)的過(guò)程,理想的狀態(tài)是TLB里緩存有頁(yè)表轉(zhuǎn)換的相關(guān)信息。當(dāng)TLB未命中時(shí),才會(huì)去查詢頁(yè)表,并且開始讀入頁(yè)表的內(nèi)容。
page table
page table是每個(gè)進(jìn)程獨(dú)有的,是軟件實(shí)現(xiàn)的,是存儲(chǔ)在main memory(比如DDR)中的
Address Translation
因?yàn)樵L問(wèn)內(nèi)存中的頁(yè)表相對(duì)耗時(shí),尤其是在現(xiàn)在普遍使用多級(jí)頁(yè)表的情況下,需要多次的內(nèi)存訪問(wèn),為了加快訪問(wèn)速度,系統(tǒng)設(shè)計(jì)人員為page table設(shè)計(jì)了一個(gè)硬件緩存 – TLB,CPU會(huì)首先在TLB中查找,因?yàn)樵赥LB中找起來(lái)很快。TLB之所以快,一是因?yàn)樗械膃ntries的數(shù)目較少,二是TLB是集成進(jìn)CPU的,它幾乎可以按照CPU的速度運(yùn)行。
如果在TLB中找到了含有該虛擬地址的entry(TLB hit),則可從該entry中直接獲取對(duì)應(yīng)的物理地址,否則就不幸地TLB miss了,就得去查找當(dāng)前進(jìn)程的page table。這個(gè)時(shí)候,組成MMU的另一個(gè)部分table walk unit就被召喚出來(lái)了,這里面的table就是page table。
使用table walk unit硬件單元來(lái)查找page table的方式被稱為hardware TLB miss handling,通常被CISC架構(gòu)的處理器(比如IA-32)所采用。它要在page table中查找不到,出現(xiàn)page fault的時(shí)候才會(huì)交由軟件(操作系統(tǒng))處理。
與之相對(duì)的通常被RISC架構(gòu)的處理器(比如Alpha)采用的software TLB miss handling,TLB miss后CPU就不再參與了,由操作系統(tǒng)通過(guò)軟件的方式來(lái)查找page table。使用硬件的方式更快,而使用軟件的方式靈活性更強(qiáng)。IA-64提供了一種混合模式,可以兼顧兩者的優(yōu)點(diǎn)。
如果在page table中找到了該虛擬地址對(duì)應(yīng)的entry的p(present)位是1,說(shuō)明該虛擬地址對(duì)應(yīng)的物理頁(yè)面當(dāng)前駐留在內(nèi)存中,也就是page table hit。找到了還沒(méi)完,接下來(lái)還有兩件事要做:
-
? 既然是因?yàn)樵赥LB里找不到才找到這兒來(lái)的,自然要更新TLB。
? 進(jìn)行權(quán)限檢測(cè),包括可讀/可寫/可執(zhí)行權(quán)限,user/supervisor模式權(quán)限等。如果沒(méi)有正確的權(quán)限,將觸發(fā)SIGSEGV(Segmantation Fault)。
如果該虛擬地址對(duì)應(yīng)的entry的p位是0,就會(huì)觸發(fā)page fault,可能有這幾種情況:
-
? 這個(gè)虛擬地址被分配后還從來(lái)沒(méi)有被access過(guò)(比如malloc之后還沒(méi)有操作分配到的空間,則不會(huì)真正分配物理內(nèi)存)。觸發(fā)page fault后分配物理內(nèi)存,也就是demand paging,有了確定的demand了之后才分,然后將p位置1。
? 對(duì)應(yīng)的這個(gè)物理頁(yè)面的內(nèi)容被換出到外部的disk/flash了,這個(gè)時(shí)候page table entry里存的是換出頁(yè)面在外部swap area里暫存的位置,可以將其換回物理內(nèi)存,再次建立映射,然后將p位置1。
后面再進(jìn)一步就是看看這個(gè)TLB中具體是怎么找的,在page table中又是怎么”walk”,這部分就是具體的地址是怎么轉(zhuǎn)換的,翻譯的。
虛擬地址轉(zhuǎn)換的具體實(shí)現(xiàn)就在下面的PART 二。
有了這些基礎(chǔ)之后我們來(lái)看看MMU內(nèi)存是怎么分配的。
PART 二:MMU 使用篇
這部分可以了解CPU訪問(wèn)的虛擬地址是怎么轉(zhuǎn)換成物理地址,然后通過(guò)物理地址在cache、主存或者EMMC中獲取相應(yīng)的數(shù)據(jù)。
1-MMU相關(guān)的基本概念
(1)虛擬地址相關(guān)基本概念
-
? 虛擬內(nèi)存(Virtual Memory,VM):為每個(gè)進(jìn)程提供了一致的、連續(xù)的、私有的內(nèi)存空間,簡(jiǎn)化了內(nèi)存管理。將主存看成是一個(gè)存儲(chǔ)在磁盤上的地址空間的高速緩存,當(dāng)運(yùn)行多個(gè)進(jìn)程或者一個(gè)進(jìn)程需要更多的空間時(shí),主存顯然是不夠用的,這時(shí)需要更大、更便宜的磁盤保存一部分?jǐn)?shù)據(jù)。
? 虛擬地址空間(Virtual Address Space,VAS):每個(gè)進(jìn)程獨(dú)有。
? 虛擬頁(yè)(Virtual Page,VP):把虛擬內(nèi)存按照頁(yè)表大小進(jìn)行劃分。
? 虛擬地址(Virtual Address,VA):處理器看到的地址。
? 虛擬頁(yè)號(hào)(Virtual Page Number,VPN):用于定位頁(yè)表的PTE。
(2)物理地址相關(guān)的基本概念
-
? 物理內(nèi)存(Physical Memory,PM):主存上能夠使用的物理空間。
? 物理頁(yè)(Physical Page):把物理內(nèi)存按照頁(yè)表的大小進(jìn)行劃分。
? 物理地址(Physical Address,PA):物理內(nèi)存劃分很多塊,通過(guò)物理內(nèi)存進(jìn)行定位。
? 物理頁(yè)號(hào)(Physical Page Number,PPN):定位物理內(nèi)存中塊的位置。
(3)頁(yè)表相關(guān)的基本概念
-
? 頁(yè)表(Page Table):虛擬地址與物理地址映射表的集合。
? 頁(yè)表?xiàng)l目(Page Table Entry,PTE):虛擬地址與獨(dú)立地址具體對(duì)應(yīng)的記錄。
? 頁(yè)全局目錄(Page Global Directory,PGD):多級(jí)頁(yè)表中的最高一級(jí)。
? 頁(yè)上級(jí)目錄(Page Upper Directory,PUD):多級(jí)頁(yè)表中的次高一級(jí)。
? 頁(yè)中間目錄(Page Middle Directory,PMD):多級(jí)頁(yè)表中的一級(jí)。
2-頁(yè)命中、缺頁(yè)
(1)頁(yè)命中
-
? a) 處理器要對(duì)虛擬地址VA進(jìn)行訪問(wèn)。
? b) MMU的TLB沒(méi)有命中,通過(guò)TWU遍歷主存頁(yè)表中的PTEA(PTE地址)。
? c) 主存向MMU返回PTE。
? d) MMU通過(guò)PTE映射物理地址,并把它傳給高速緩存或主存。
? e) 高速緩存或主存返回物理地址對(duì)應(yīng)的數(shù)據(jù)給處理器。
(2)缺頁(yè)
-
? a) 處理器要對(duì)虛擬地址VA進(jìn)行訪問(wèn)。
? b) MMU的TLB沒(méi)有命中,通過(guò)TWU遍歷主存頁(yè)表中的PTEA(PTE地址)。
? c) 主存向MMU返回PTE。
? d) PTE中有效位是0,MMU觸發(fā)一次異常,CPU相應(yīng)缺頁(yè)異常,運(yùn)行相應(yīng)的處理程序。
? e) 缺頁(yè)異常處理程序選出物理內(nèi)存中的犧牲頁(yè),若這個(gè)頁(yè)面已經(jīng)被修改,將其換出到EMMC。
? f) 缺頁(yè)異常處理程序從EMMC中加載新的頁(yè)面,并更新內(nèi)存中頁(yè)表的PTE。
? g) 缺頁(yè)異常處理程序返回到原來(lái)的進(jìn)程,再次執(zhí)行導(dǎo)致缺頁(yè)的指令。CPU將引起缺頁(yè)異常的虛擬地址重新發(fā)給MMU。由于虛擬頁(yè)面現(xiàn)在緩存在主存中,主存會(huì)將所請(qǐng)求的地址對(duì)應(yīng)的內(nèi)容返回給cache和處理器。
3-多級(jí)頁(yè)表映射過(guò)程
物理頁(yè)面大小一級(jí)地址總線寬度不同,頁(yè)表的級(jí)數(shù)也不同。以AArch64運(yùn)行狀態(tài),4KB大小物理頁(yè)面,48位地址寬度為例,頁(yè)表映射的查詢過(guò)程如圖:
對(duì)于多任務(wù)操作系統(tǒng),每個(gè)用戶進(jìn)程都擁有獨(dú)立的進(jìn)程地址空間,也有相應(yīng)的頁(yè)表負(fù)責(zé)虛擬地址到物理地址之間的轉(zhuǎn)換。MMU查詢的過(guò)程中,用戶進(jìn)程的一級(jí)頁(yè)表的基址存放在TTBR0。操作系統(tǒng)的內(nèi)核空間公用一塊地址空間,MMU查詢的過(guò)程中,內(nèi)核空間的一級(jí)頁(yè)表基址存放在TTBR1。當(dāng)TLB未命中時(shí),處理器查詢頁(yè)表的過(guò)程如下:
-
? 處理器根據(jù)虛擬地址第63位,來(lái)選擇使用TTBR0或者TTBR1。當(dāng)VA[63]為0時(shí),選擇TTBR0,TTBR中存放著L0頁(yè)表的基址。
? 處理器以VA[47:39]作為L(zhǎng)0的索引,在L0頁(yè)表中查找頁(yè)表項(xiàng),L0頁(yè)表有512個(gè)頁(yè)表項(xiàng)。
? L0頁(yè)表的頁(yè)表項(xiàng)中存放著L1頁(yè)表的物理基址。處理器以VA[38:30]作為L(zhǎng)1索引,在L1頁(yè)表中找到相應(yīng)的頁(yè)表項(xiàng),L1頁(yè)表中有512個(gè)頁(yè)表項(xiàng)。
? L1頁(yè)表的頁(yè)表項(xiàng)中存放著L2頁(yè)表的物理基址。處理器以VA[29:21]作為L(zhǎng)2索引,在L2頁(yè)表中找到相應(yīng)的頁(yè)表項(xiàng),L2頁(yè)表中有512個(gè)頁(yè)表項(xiàng)。
? L2頁(yè)表的頁(yè)表項(xiàng)中存放著L3頁(yè)表的物理基址。處理器以VA[20:12]作為L(zhǎng)1索引,在L3頁(yè)表中找到相應(yīng)的頁(yè)表項(xiàng),L3頁(yè)表中有512個(gè)頁(yè)表項(xiàng)。
? L3頁(yè)表的頁(yè)表項(xiàng)里,存放著4KB頁(yè)面的物理基址,然后加上VA[11:0],這樣就構(gòu)成了物理地址,至此處理器完成了一次虛擬地址到物理地址的查詢與翻譯的工作。
4-虛擬地址空間布局
當(dāng)然虛擬地址空間劃分不只是如此。因?yàn)槟壳皯?yīng)用程序沒(méi)有那么大的內(nèi)存需求,所以ARM64處理器不支持完全的64位虛擬地址,實(shí)際支持情況如下。
(1)-虛擬地址位寬
虛擬地址的最大寬度是48位 內(nèi)核虛擬地址在64位地址空間的頂部,高16位是全1,范圍是[0xFFFF 0000 0000 0000,0xFFFF FFFF FFFF FFFF];
用戶虛擬地址在64位地址空間的底部,高16位是全0,范圍是[0x00000000 0000 0000,0×0000 FFFF FFFF FFFF];
高16位是全1或全0的地址稱為規(guī)范的地址,兩者之間是不規(guī)范的地址,不允許使用。
如果處理器實(shí)現(xiàn)了ARMv8.2標(biāo)準(zhǔn)的大虛擬地址(Large Virtual Address,LVA)支持,并且頁(yè)長(zhǎng)度是64KB,那么虛擬地址的最大寬度是52位。這個(gè)也就是大頁(yè)表,可以提升內(nèi)存與訪問(wèn)速度。
可以為虛擬地址配置比最大寬度小的寬度,并且可以為內(nèi)核虛擬地址和用戶虛擬地址配置不同的寬度。
轉(zhuǎn)換控制寄存器(Translation Control Register)TCR_EL1的字段T0SZ定義了必須是全0的最高位的數(shù)量,字段T1SZ定義了必須是全1的最高位的數(shù)量,用戶虛擬地址的寬度是(64-TCR_EL1.T0SZ),內(nèi)核虛擬地址的寬度是(64-TCR_EL1.T1SZ)。(全是0是代表的用戶,全是1代表的是內(nèi)核。)
(2)編譯ARM64架構(gòu)的Linux內(nèi)核時(shí),可以選擇虛擬地址寬度
-
? (1)如果選擇頁(yè)長(zhǎng)度4KB,默認(rèn)的虛擬地址寬度是39位。
? (2)如果選擇頁(yè)長(zhǎng)度16KB,默認(rèn)的虛擬地址寬度是47位。
? (3)如果選擇頁(yè)長(zhǎng)度64KB,默認(rèn)的虛擬地址寬度是42位。
? (4)可以選擇48位虛擬地址。
在ARM64架構(gòu)的Linux內(nèi)核中,內(nèi)核虛擬地址和用戶虛擬地址的寬度相同。
-
? 所有進(jìn)程共享內(nèi)核虛擬地址空間,
? 每個(gè)進(jìn)程有獨(dú)立的用戶虛擬地址空間,
? 同一個(gè)線程組的用戶線程共享用戶虛擬地址空間,內(nèi)核線程沒(méi)有用戶虛擬地址空間。
小結(jié)
1-幾個(gè)問(wèn)題
(1)為什么沒(méi)有MMU就無(wú)法運(yùn)行Linux系統(tǒng)?
這是因?yàn)?Linux 內(nèi)核將虛擬地址空間分為多個(gè)頁(yè)面,并將這些頁(yè)面映射到物理地址空間上,以實(shí)現(xiàn)內(nèi)存隔離、保護(hù)和虛擬內(nèi)存等功能。
沒(méi)有 MMU,就無(wú)法實(shí)現(xiàn)這種映射,從而無(wú)法運(yùn)行 Linux 系統(tǒng)。
(2)為什么有些較為簡(jiǎn)單的SOC可能沒(méi)有MMU,但仍然可以運(yùn)行一些嵌入式操作系統(tǒng)或者裸機(jī)程序?
RTOS可以運(yùn)行在沒(méi)有MMU的系統(tǒng)上,因?yàn)镽TOS通常不需要進(jìn)行內(nèi)存保護(hù)和虛擬地址映射等高級(jí)特性。
相反,RTOS的設(shè)計(jì)側(cè)重于實(shí)時(shí)性和低延遲,因此通常只需要簡(jiǎn)單的內(nèi)存管理和任務(wù)調(diào)度即可。
這使得RTOS可以運(yùn)行在許多嵌入式系統(tǒng)上,包括一些沒(méi)有MMU的系統(tǒng)。
內(nèi)存真的是一個(gè)非常非常有意思且豐富的東西,不是我這一篇能講完的,這肯定還是差的蠻多的,文章有很多的內(nèi)容來(lái)自于前輩的文章和博客。如果看完有一點(diǎn)點(diǎn)的收獲,那肯定就是值了的。
后續(xù)希望能出一個(gè)結(jié)合源碼與硬件的長(zhǎng)文,把內(nèi)存和大家一起學(xué)習(xí)透徹。
記得點(diǎn)贊、關(guān)注、轉(zhuǎn)發(fā)、在看是我最大的鼓勵(lì)?。?!
周末愉快!??!
參考文章
感謝一下前輩們的卓越文章與書籍。
-
? https://www.jianshu.com/p/ef1e93e9d65b
? https://zhuanlan.zhihu.com/p/570452487
? https://zhuanlan.zhihu.com/p/487386274
? https://zhuanlan.zhihu.com/p/596039345
? https://www.jianshu.com/p/e4bc4a8e2553
? http://www.taodudu.cc/news/show-523335.html?action=onClick
? https://mp.weixin.qq.com/s?__biz=Mzg3ODU3Nzk3MQ==&mid=2247502406&idx=1&sn=0287f11c54654968abe656280ffac0c5&scene=21#wechat_redirect
? https://zhuanlan.zhihu.com/p/65348145
? https://zhuanlan.zhihu.com/p/436719684?utm_source=zhihu&utm_id=0
? 《嵌入式系統(tǒng)開發(fā)指南》
? 《深度探索嵌入式系統(tǒng)開發(fā)》
? 《計(jì)算機(jī)架構(gòu)與體系》