中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開(kāi)APP
userphoto
未登錄

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

開(kāi)通VIP
s3c2440硬件學(xué)習(xí)筆記----內(nèi)存管理單元MMU

s3c2440硬件學(xué)習(xí)筆記----內(nèi)存管理單元MMU

分類(lèi): ARM硬件 358人閱讀 評(píng)論(0) 收藏 舉報(bào)

 本篇基本是韋東山書(shū)上的

一、內(nèi)存管理單元MMU介紹
內(nèi)存管理單元簡(jiǎn)稱(chēng)MMU,它負(fù)責(zé)虛擬地址到物理地址的映射,并提供硬件機(jī)制的內(nèi)存訪(fǎng)問(wèn)權(quán)限檢查MMU使得每個(gè)用戶(hù)進(jìn)程擁有自己獨(dú)立的地址空間,并通過(guò)內(nèi)存訪(fǎng)問(wèn)權(quán)限的檢查保護(hù)每個(gè)進(jìn)程所用的內(nèi)存不被其他進(jìn)程破壞。


重點(diǎn)就在于地址映射:頁(yè)表的結(jié)構(gòu)與建立、映射的過(guò)程。
 
1、S3C2440 MMU地址變換過(guò)程
 
1)地址的分類(lèi)
一個(gè)程序在運(yùn)行之前,沒(méi)有必要全部裝入內(nèi)存,僅需要將那些要運(yùn)行的部分先裝入內(nèi)存,其余部分在用到時(shí)從磁盤(pán)載入,當(dāng)內(nèi)存不足時(shí),再將暫時(shí)不用的部分調(diào)出到磁盤(pán)。
這使得大程序可以在較小的內(nèi)存空間中運(yùn)行,也使得內(nèi)存中可以同時(shí)裝入更多的程序并發(fā)執(zhí)行,這樣的存儲(chǔ)器一般稱(chēng)為虛擬存儲(chǔ)器。
虛擬地址最終需要轉(zhuǎn)換為物理地址才能讀寫(xiě)實(shí)際的數(shù)據(jù),通過(guò)將虛擬地址空間和物理空間劃分為同樣大小的空間(段或頁(yè)),然后兩個(gè)空間建立映射關(guān)系。
由于虛擬地址空間遠(yuǎn)大于物理地址,可能多塊虛擬地址空間映射到同一塊物理地址空間,或者有些虛擬地址空間沒(méi)有映射到具體的物理地址空間上去(使用到時(shí)再映射)。
 
ARM cpu地址轉(zhuǎn)換涉及三種地址:虛擬地址(VA,Virtual Address)、變換后的虛擬地址(MVA,Modified Virtual Address)、物理地址(PA,Physical Address)
沒(méi)有啟動(dòng)MMU時(shí),CPU核心,cache,MMU,外設(shè)等所有部件使用的都是物理地址。
啟動(dòng)MMU后,CPU核心對(duì)外發(fā)出虛擬地址VA;VA被轉(zhuǎn)換為MVA供cache,MMU使用,在這里MVA被轉(zhuǎn)換成PA;最后使用PA讀取實(shí)際設(shè)備
 
①CPU核心看到和用到的只是虛擬地址VA,至于VA如果去對(duì)應(yīng)物理地址PA,CPU核心不理會(huì)
②caches和MMU看不到VA,他們利用MVA轉(zhuǎn)換得到PA
③實(shí)際設(shè)備看不到VA、MVA,讀寫(xiě)它們使用的是物理地址PA
 
MVA是除CPU核心外的其他部分看到的虛擬地址,VA與MVA的變化關(guān)系
如果VA<32M,需要使用進(jìn)程標(biāo)識(shí)號(hào)PID(通過(guò)讀CP15的C13獲得)來(lái)轉(zhuǎn)換為MVA
 
if (VA  < 32M) then
        MVA = VA | (PID << 25)
else
        MVA = VA
 
使用MVA,而不使用VA的目的是,當(dāng)有重疊的VA時(shí),轉(zhuǎn)換為MVA地址并不重疊,減小轉(zhuǎn)換為PA的代價(jià)
比如兩個(gè)進(jìn)程1、2,VA都是0-(32M-1),則MVA分別為0x02000000-0x03ffffff,0x04000000-0x05ffffff。
下文說(shuō)到虛擬地址,如果沒(méi)有特別指出,就是指MVA
 
2)虛擬地址到物理地址的轉(zhuǎn)換過(guò)程
 arm cpu使用頁(yè)表來(lái)進(jìn)行轉(zhuǎn)換,頁(yè)表由一個(gè)個(gè)條目組成,每個(gè)條目存儲(chǔ)一段虛擬地址對(duì)應(yīng)的物理地址及訪(fǎng)問(wèn)權(quán)限,或者下一級(jí)頁(yè)表的地址
 S3C2440最多會(huì)用到兩級(jí)頁(yè)表,以段(Section,1M)的方式進(jìn)行轉(zhuǎn)換時(shí)只用到一級(jí)頁(yè)表,以頁(yè)(Page)的方式進(jìn)行轉(zhuǎn)換時(shí)用到兩級(jí)頁(yè)表。
 頁(yè)的大小有3種:大頁(yè)(64KB),小頁(yè)(4KB),極小頁(yè)(1KB)。條目也稱(chēng)為描述符,有:段描述符、大頁(yè)描述符、小頁(yè)描述符、極小頁(yè)描述符-保存段、大頁(yè)、小頁(yè)、極小頁(yè)的起始物理地址;粗頁(yè)表描述符、細(xì)頁(yè)表描述符,它們保存二級(jí)頁(yè)表的物理地址。
 
下圖為S3C2440的地址轉(zhuǎn)換圖

 


 
TTB base代表一級(jí)頁(yè)表的地址,將它寫(xiě)入?yún)f(xié)處理器CP15的寄存器C2(稱(chēng)為頁(yè)表基址寄存器)即可,一級(jí)頁(yè)表的地址是16K對(duì)齊,使用[31:14]存儲(chǔ)頁(yè)表基址,[13:0]為0
 一級(jí)頁(yè)表使用4096個(gè)描述符來(lái)表示4GB空間,每個(gè)描述符對(duì)應(yīng)1MB的虛擬地址,存儲(chǔ)它對(duì)應(yīng)的1MB物理空間的起始地址,或者存儲(chǔ)下一級(jí)頁(yè)表的地址。使用MVA[31:20]來(lái)索引一級(jí)頁(yè)表(20-31一共12位,2^12=4096,所以是4096個(gè)描述符),得到一個(gè)描述符,每個(gè)描述符占4個(gè)字節(jié)。
一級(jí)頁(yè)表描述符格式如下:
 

一級(jí)頁(yè)表描述符
 
最低兩位:
 0b00:無(wú)效
 
 0b01:粗頁(yè)表(Coarse page table)
        [31:10]為粗頁(yè)表基址,此描述符低10位填充0后就是一個(gè)二級(jí)頁(yè)表的物理地址,二級(jí)頁(yè)表含256個(gè)條目(使用[9:2],2^8=256個(gè)),稱(chēng)為粗頁(yè)表(Coarse page table)。其中每個(gè)條目表示4KB大小的物理地址空間,一個(gè)粗頁(yè)表表示1MB物理地址
 
0b10:段(Section)
        [31:20]為段基址,、此描述符低20位填充0后就是一塊1MB物理地址空間的起始地址。MVA[19:0],用來(lái)在這1MB空間中尋址。描述符的位[31:20]和MVA[19:0]構(gòu)成了這個(gè)虛擬地址MVA對(duì)應(yīng)的物理地址
 
以段的方式進(jìn)行映射時(shí),虛擬地址MVA到物理地址PA的轉(zhuǎn)換過(guò)程如下:
①頁(yè)表基址寄存器位[31:14]和MVA[31:20]組成一個(gè)低兩位為0的32位地址,MMU利用這個(gè)地址找到段描述符
②取出段描述符的位[31:20](段基址),它和MVA[19:0]組成一個(gè)32位的物理地址(這就是MVA對(duì)應(yīng)的PA)


段地址轉(zhuǎn)換過(guò)程

 

0b11:細(xì)頁(yè)表(Fine page table)

        [31:12]為細(xì)頁(yè)表基址(Fine page table base address),此描述符的低12位填充0后,就是一個(gè)二級(jí)頁(yè)表的物理地址。此二級(jí)頁(yè)表含1024個(gè)條目(使用[11:2],10位),其中每個(gè)條目表示大小1kb的物理地址空間,一個(gè)細(xì)頁(yè)表表示1MB物理地址空間

 

以大頁(yè)(64KB),小頁(yè)(4KB)或極小頁(yè)(1KB)進(jìn)行地址映射時(shí),需要用到二級(jí)頁(yè)表,二級(jí)頁(yè)表有粗頁(yè)表、細(xì)頁(yè)表兩種,二級(jí)頁(yè)表描述符格式如下:

 

 

二級(jí)頁(yè)表描述符


最低兩位:
0b00:無(wú)效
 
0b01:大頁(yè)描述符
        位[31:16]為大頁(yè)基址,此描述符的低16位填充0后就是一塊64KB物理地址空間的起始地址粗頁(yè)表中的每個(gè)條目只能表示4KB物理空間,如果大頁(yè)描述符保存在粗頁(yè)表中,則連續(xù)16個(gè)條目都保存同一個(gè)大頁(yè)描述符。類(lèi)似的,細(xì)頁(yè)表中每個(gè)條目只能表示1KB的物理空間,如果大頁(yè)描述符保存在細(xì)頁(yè)表中,則連續(xù)64個(gè)條目都保存同一個(gè)大頁(yè)描述符。
下面以保存在粗頁(yè)表中的大頁(yè)描述符為例,說(shuō)明地址轉(zhuǎn)化那過(guò)程
①頁(yè)表基址寄存器[31:14]和MVA[31:20]組成一個(gè)低兩位為0的32位地址,MMU利用這個(gè)地址找到粗頁(yè)表描述符
②取出粗頁(yè)表描述符的[31:10](即粗頁(yè)表基址),它和MVA[19:12]組成一個(gè)低兩位為0的32位物理地址,通過(guò)這個(gè)地址找到大頁(yè)描述符
③取出大頁(yè)描述符的[31:16](即大頁(yè)基址),它和MVA[15:0]組成一個(gè)32位的物理地址,即MVA對(duì)應(yīng)的PA
步驟②和③中,用于在粗頁(yè)表中索引的MVA[19:12]、用于在大頁(yè)內(nèi)尋址的MVA[15:0]有重合的位[15:12],當(dāng)位[15:12]從0b0000變化到0b1111時(shí),步驟②得到的大頁(yè)描述符相同,所以粗頁(yè)表中有連續(xù)16個(gè)條目保存同一個(gè)大頁(yè)描述符


大頁(yè)的地址轉(zhuǎn)換過(guò)程(大頁(yè)描述符保存在粗頁(yè)表中)

 

0b10:小頁(yè)描述符

[31:12]為小頁(yè)基址(Small page base address),此描述符的低12位填充0后就是一塊4kb([11:0],一共12位,2^12=4096)物理地址空間的起始地址。粗頁(yè)表中每個(gè)條目表示4kb的物理空間,如果小頁(yè)描述符保存在粗頁(yè)表中,則只需要用一個(gè)條目來(lái)保存一個(gè)小頁(yè)描述符。類(lèi)似的,細(xì)頁(yè)表中每個(gè)條目只能表示1kb的物理空間,如果小頁(yè)保存在細(xì)頁(yè)表中,則連續(xù)4個(gè)條目都保存同一個(gè)小頁(yè)描述符。

下面以保存在粗頁(yè)表中的小頁(yè)描述符為例,說(shuō)明地址轉(zhuǎn)換過(guò)程:

①頁(yè)表基址[31:14]和MVA[31:20]組成一個(gè)低兩位為0的32位地址,MMU利用這個(gè)地址找到粗頁(yè)表描述符

②取出粗頁(yè)表描述符[31:10](即粗頁(yè)表基址),它和MVA[19:12]組成一個(gè)低兩位為0的32位物理地址,用這個(gè)地址找到小頁(yè)描述符

③取出小頁(yè)描述符的位[31:12](即小頁(yè)基址),它和MVA[11:0]組成一個(gè)32位物理地址(即MVA對(duì)應(yīng)的PA)

小頁(yè)描述符保存在細(xì)頁(yè)表中,地址轉(zhuǎn)換過(guò)程和上面類(lèi)似。

 

小頁(yè)的地址轉(zhuǎn)換過(guò)程(小頁(yè)描述符保存在粗頁(yè)表中)

 

0b11:極小頁(yè)描述符

        [31:10]為極小頁(yè)基址(Tiny page base address),此描述符的低10位填充0后就是一塊1KB物理地址空間的起始地址。極小頁(yè)描述符只能保存在細(xì)頁(yè)表中,用一個(gè)條目來(lái)保存一耳光極小頁(yè)描述符

下面是極小頁(yè)的地址轉(zhuǎn)換過(guò)程:

①頁(yè)表基址寄存器[31:14]和MVA[31:20]組成一個(gè)低兩位為0的32位地址,MMU通過(guò)這個(gè)地址找到細(xì)頁(yè)表描述符

②取出細(xì)頁(yè)表描述符[31:12](即細(xì)頁(yè)表基址),它和MVA[19:10]組成一個(gè)低兩位為0的32位物理地址,通過(guò)這個(gè)地址即可找到極小頁(yè)描述符

③取出極小頁(yè)描述符[31:10](即極小頁(yè)基址),它和MVA[9:0]組成一個(gè)32位的物理地址(即MVA對(duì)應(yīng)的PA)

 

 

極小頁(yè)的地址轉(zhuǎn)換過(guò)程(極小頁(yè)描述符保存在粗頁(yè)表中)

 

從段、大頁(yè)、小頁(yè)、極小頁(yè)的地址轉(zhuǎn)換過(guò)程可知

①以段進(jìn)行映射時(shí),通過(guò)MVA[31:20]結(jié)合頁(yè)表得到一段(1MB)的起始物理地址,MVA[19:0]用來(lái)在段中尋址

②以大頁(yè)進(jìn)行映射時(shí),通過(guò)MVA[31:16]結(jié)合頁(yè)表得到一個(gè)大頁(yè)(64KB)的起始物理地址,MVA[15:0]用來(lái)在小頁(yè)中尋址

③以小頁(yè)進(jìn)行映射時(shí),通過(guò)MVA[31:12]結(jié)合頁(yè)表得到一個(gè)小頁(yè)(4KB)的起始物理地址,MVA[11:0]用來(lái)在小頁(yè)中尋址

④以極小頁(yè)進(jìn)行映射時(shí),通過(guò)MVA[31:10]結(jié)合頁(yè)表得到一個(gè)極小頁(yè)(1KB)的起始物理地址,MVA[9:0]用來(lái)在極小頁(yè)中尋址

 

2、內(nèi)存的訪(fǎng)問(wèn)權(quán)限檢查

它決定一塊內(nèi)存是否允許讀、是否允許寫(xiě)。這由CP15寄存器C3(域訪(fǎng)問(wèn)控制)、描述符的域(Domain)、CP15寄存器C1的R/S/A位、描述符的AP位共同決定。

“域”決定是否對(duì)某塊內(nèi)存進(jìn)行權(quán)限檢查,“AP”決定如何對(duì)某塊內(nèi)容進(jìn)行權(quán)限檢查。

S3C2440有16個(gè)域,CP15寄存器C3中每?jī)晌粚?duì)應(yīng)一個(gè)域(一共32位),用來(lái)表示這個(gè)域是否進(jìn)行權(quán)限檢查

每?jī)晌粩?shù)據(jù)的含義

00:無(wú)訪(fǎng)問(wèn)權(quán)限(任何訪(fǎng)問(wèn)都將導(dǎo)致“Domain fault”異常)

01:客戶(hù)模式(使用段描述符、頁(yè)描述符進(jìn)行權(quán)限檢查)

10:保留(保留,目前相當(dāng)于“無(wú)訪(fǎng)問(wèn)權(quán)限”)

11:管理模式(不進(jìn)行權(quán)限檢查,允許任何訪(fǎng)問(wèn))

Domain占用4位,用來(lái)表示內(nèi)存屬于0-15,哪一個(gè)域

例如:

①段描述符中的“Domain”為0b0010,表示1MB內(nèi)存屬于域2,如果域訪(fǎng)問(wèn)控制寄存器的[5:4]等于0b00,則訪(fǎng)問(wèn)這1MB空間都會(huì)產(chǎn)生“Domain fault”異常,如果等于0b01,則使用描述符中的“Ap”位進(jìn)行權(quán)限檢查

②粗頁(yè)表中的“Domain”為0b1010,表示1MB內(nèi)存屬于域10,如果域訪(fǎng)問(wèn)控制寄存器的[21:20]等于0b01,則使用二級(jí)頁(yè)表中的大頁(yè)/小頁(yè)描述符中的"ap3"、"ap2"、"ap1"、"ap0"位進(jìn)行權(quán)限檢查,如果等于0b11,則允許任何訪(fǎng)問(wèn),不進(jìn)行權(quán)限檢查。

如下圖:

 


一級(jí)頁(yè)表描述符


二級(jí)頁(yè)表描述符
 
AP、ap3、ap2、ap1、ap0結(jié)合CP15寄存器C1的R/S位,決定如何進(jìn)行訪(fǎng)問(wèn)檢查。
段描述符中AP控制整個(gè)段(1MB)訪(fǎng)問(wèn)權(quán)限;大頁(yè)描述符每個(gè)apx(0-3)控制一個(gè)大頁(yè)(64KB)中1/4內(nèi)存的訪(fǎng)問(wèn)權(quán)限,即ap3對(duì)應(yīng)大頁(yè)高端的16KB,ap0對(duì)應(yīng)大頁(yè)低端的16KB;小頁(yè)描述符與大頁(yè)描述符類(lèi)似,每個(gè)apx(0-3)控制一個(gè)小頁(yè)(4KB)的1/4內(nèi)存的訪(fǎng)問(wèn)權(quán)限;極小頁(yè)中的ap控制整個(gè)極小頁(yè)(1KB)的訪(fǎng)問(wèn)權(quán)限。
下表為AP、S、R的對(duì)照表
AP S R 特權(quán)模式 用戶(hù)模式 說(shuō)明
00 0 0 無(wú)訪(fǎng)問(wèn)權(quán)限 無(wú)訪(fǎng)問(wèn)權(quán)限 任何訪(fǎng)問(wèn)將產(chǎn)生“Permission fault”異常
00 1 0 只讀 無(wú)訪(fǎng)問(wèn)權(quán)限 在超級(jí)權(quán)限下可以進(jìn)行讀操作
00 0 1 只讀 只讀 任何寫(xiě)操作將產(chǎn)生”P(pán)ermission fault“異常
00 1 1 保留 - -
01 x x 讀/寫(xiě) 無(wú)訪(fǎng)問(wèn)權(quán)限 只允許在超級(jí)模式下訪(fǎng)問(wèn)
10 x x 讀/寫(xiě) 只讀 在用戶(hù)模式下進(jìn)行寫(xiě)操作將產(chǎn)生"Permission fault"異常
11 x x 讀/寫(xiě) 讀/寫(xiě) 在所有模式下允許任何訪(fǎng)問(wèn)
xx 1 1 保留 - -


 
 3、TLB的作用

從MVA到PA的轉(zhuǎn)換需要訪(fǎng)問(wèn)多次內(nèi)存,大大降低了CPU的性能,有沒(méi)有辦法改進(jìn)呢?

程序執(zhí)行過(guò)程中,用到的指令和數(shù)據(jù)的地址往往集中在一個(gè)很小的范圍內(nèi),其中的地址、數(shù)據(jù)經(jīng)常使用,這是程序訪(fǎng)問(wèn)的局部性。

由此,通過(guò)使用一個(gè)高速、容量相對(duì)較小的存儲(chǔ)器來(lái)存儲(chǔ)近期用到的頁(yè)表?xiàng)l目(段、大頁(yè)、小頁(yè)、極小頁(yè)描述符),避免每次地址轉(zhuǎn)換都到主存中查找,這樣就大幅提高性能。這個(gè)存儲(chǔ)器用來(lái)幫助快速地進(jìn)行地址轉(zhuǎn)換,成為轉(zhuǎn)譯查找緩存(Translation Lookaside Buffers, TLB)

當(dāng)CPU發(fā)出一個(gè)虛擬地址時(shí),MMU首先訪(fǎng)問(wèn)TLB。如果TLB中含有能轉(zhuǎn)換這個(gè)虛擬地址的描述符,則直接利用此描述符進(jìn)行地址轉(zhuǎn)換和權(quán)限檢查,否則MMU訪(fǎng)問(wèn)頁(yè)表找到描述符后再進(jìn)行地址轉(zhuǎn)換和權(quán)限檢查,并將這個(gè)描述符填入TLB中,下次再使用這個(gè)虛擬地址時(shí)就直接使用TLB用的描述符。

使用TLB需要保證TLB中的內(nèi)容與頁(yè)表一致,在啟動(dòng)MMU之前,頁(yè)表中的內(nèi)容發(fā)生變化后,尤其要注意。一般的做法是在啟動(dòng)MMU之前使整個(gè)TLB無(wú)效,改變頁(yè)表時(shí),使所涉及的虛擬地址對(duì)應(yīng)的TLB中條目無(wú)效。

 

4、Cache的作用

同樣基于程序訪(fǎng)問(wèn)的局部性,在主存和CPU通用寄存器之間設(shè)置一個(gè)高速的、容量相對(duì)較小的存儲(chǔ)器,把正在執(zhí)行的指令地址附近的一部分指令或數(shù)據(jù)從主存調(diào)入這個(gè)存儲(chǔ)器,供CPU在一段時(shí)間內(nèi)使用,對(duì)提高程序的運(yùn)行速度有很大作用。這個(gè)cache一般稱(chēng)為高速緩存。

①寫(xiě)穿式(Write Through)

任一CPU發(fā)出寫(xiě)信號(hào)送到Cache的同時(shí),也寫(xiě)入主存,保證主存的數(shù)據(jù)同步更新。優(yōu)點(diǎn)是操作簡(jiǎn)單,但由于主存速度慢,降低了系統(tǒng)的寫(xiě)速度并占用了總線(xiàn)的時(shí)間。

②回寫(xiě)式(Write Back)

數(shù)據(jù)一般只寫(xiě)到Cache,這樣可能出現(xiàn)Cache中的數(shù)據(jù)得到更新而主存中的數(shù)據(jù)不變(數(shù)據(jù)陳舊)的情況。此時(shí)可在Cache中設(shè)一個(gè)標(biāo)志地址及數(shù)據(jù)陳舊的信息,只有當(dāng)Cache中的數(shù)據(jù)被換出或強(qiáng)制進(jìn)行”清空“操作時(shí),才將原更新的數(shù)據(jù)寫(xiě)入主存響應(yīng)的單元中,保證了Cache和主存中數(shù)據(jù)一致。

 

Cache有以下兩個(gè)操作:

①”清空“(clean):把Cache或Write buffer中已經(jīng)臟的(修改過(guò),但未寫(xiě)入主存)數(shù)據(jù)寫(xiě)入主存

②”使無(wú)效“(Invalidate):使之不能再使用,并不將臟的數(shù)據(jù)寫(xiě)入主存。

 

S2C2440內(nèi)置了指令Cache(ICaches)、數(shù)據(jù)Cache(DCaches)、寫(xiě)緩存(Write buffer),需要用到描述符中的C位(Ctt)和B位(Btt)

1)指令Cache(ICaches)

系統(tǒng)剛上電或復(fù)位時(shí),ICaches中的內(nèi)容是無(wú)效的,并且ICaches功能關(guān)閉。往Icr位(CP15協(xié)處理器中寄存器1的第12位)寫(xiě)1可以啟動(dòng)ICaches,寫(xiě)0停止ICaches

ICaches一般在MMU開(kāi)啟后使用,此時(shí)描述符的C位用來(lái)表示一段內(nèi)存是否可以被Cache。若Ctt=1,允許Cache,否則不允許。如果MMU沒(méi)有開(kāi)啟,ICaches也可以被使用,此時(shí)CPU讀取指令時(shí)所涉及的內(nèi)存都被當(dāng)做允許Cache

ICaches關(guān)閉時(shí),CPU每次取指都要讀取主存,性能低,所以通常盡早啟動(dòng)ICaches

ICaches開(kāi)啟后,CPU每次取指時(shí)都會(huì)先在ICaches中查看是否能找到所用指令,而不管Ctt是0還是1。如果找到成為Cache命中,找不到稱(chēng)為Cache丟失,ICaches被開(kāi)啟后,CPU的取指有如下三種情況:

①Cache命中且Ctt為1時(shí),從ICaches中取指,返回CPU

②Cache丟失且Ctt為1時(shí),CPU從主存中取指,并且把指令緩存到Cache中

③Ctt為0時(shí),CPU從主存中取指

2)數(shù)據(jù)Cache(DCaches)

與ICaches相似,系統(tǒng)剛上電或復(fù)位時(shí),DCaches中的內(nèi)容無(wú)效,并且DCaches功能關(guān)閉,Write buffer中的內(nèi)容也是被廢棄不用的。往Ccr位(CP15協(xié)處理器 中寄存器1的第二位)寫(xiě)1啟動(dòng)DCaches,寫(xiě)0停止DCaches。Write buffer和DCaches緊密結(jié)合,額米有專(zhuān)門(mén)的控制來(lái)開(kāi)啟和停止它

與ICaches不同,DCaches功能必須在MMU開(kāi)啟之后才能被使用。

DCaches被關(guān)閉時(shí),CPU每次都去內(nèi)存取數(shù)據(jù)。

DCaches被開(kāi)啟后,CPU每次讀寫(xiě)數(shù)據(jù)時(shí)都會(huì)先在DCaches中查看是否能找到所要的數(shù)據(jù),不管Ctt是0還是1,找到了成為Cache命中,找不到成為Cache丟失。

通過(guò)下表可知DCaches和Write buffer在Ccr,Ctt,Btt各種取值下,如何工作,Ctt and Ccr 意為 Ctt與Ccr進(jìn)行邏輯與后的值

 

Ctt and Ccr Btt DCaches、Write buffer 和主存的訪(fǎng)問(wèn)方式
0 0 Non-cached,non-buffered(NCNB)

讀寫(xiě)數(shù)據(jù)時(shí)都是直接操作主存,并且可以被外設(shè)中止;

寫(xiě)數(shù)據(jù)時(shí)不使用Write buffer,CPU會(huì)等待寫(xiě)操作完成;

不會(huì)出現(xiàn)Cache命中
 
0 1 Non-Cached buffered(NCB)

讀數(shù)據(jù)時(shí)都是直接操作主存;

不會(huì)出現(xiàn)Cache命中;

寫(xiě)數(shù)據(jù)時(shí),數(shù)據(jù)線(xiàn)存入Write buffer,并在隨后寫(xiě)入主存;

數(shù)據(jù)存入Write buffer后,CPU立即繼續(xù)執(zhí)行;

讀數(shù)據(jù)時(shí),可以被外設(shè)中止;

寫(xiě)數(shù)據(jù)時(shí),無(wú)法被外設(shè)中止
 
1 0 Cached,write-through(寫(xiě)通)mode

讀數(shù)據(jù)時(shí),如果Cache命中則從Cache中返回?cái)?shù)據(jù),不讀取主存;

讀數(shù)據(jù)時(shí),如果Cache丟失則從讀主存中返回?cái)?shù)據(jù),并導(dǎo)致“l(fā)inefill”的動(dòng)作;

寫(xiě)數(shù)據(jù)時(shí),數(shù)據(jù)先存入Write buffer,并在隨后寫(xiě)入主存;

數(shù)據(jù)存入Write buffer后,CPU立即繼續(xù)執(zhí)行;

寫(xiě)數(shù)據(jù)時(shí),如果Cache命中則新數(shù)據(jù)也寫(xiě)入Cache中;

寫(xiě)數(shù)據(jù)時(shí),無(wú)法被外設(shè)中止
 
1 1 Cached,write-back(寫(xiě)回) mode

讀數(shù)據(jù)時(shí),如果Cache命中則從Cache中返回?cái)?shù)據(jù),不讀取主存;

讀數(shù)據(jù)時(shí),如果Cache丟失則從讀主存中返回?cái)?shù)據(jù),并導(dǎo)致“l(fā)inefile”的動(dòng)作;

寫(xiě)數(shù)據(jù)時(shí),如果Cache丟失則將數(shù)據(jù)先存入Write buffer,存儲(chǔ)完畢后CPu立即繼續(xù)執(zhí)行,這些數(shù)據(jù)在隨后寫(xiě)入主存;

寫(xiě)數(shù)據(jù)時(shí),如果Cache命中則在Cache中更新數(shù)據(jù),并設(shè)置這些數(shù)據(jù)為”臟的“,但是不會(huì)寫(xiě)入主存;

無(wú)論Cache命中與否,寫(xiě)數(shù)據(jù)都無(wú)法被外設(shè)中止
 

 使用Cache時(shí)需要保證Cache、Write buffer的內(nèi)容和主存內(nèi)容一致,保證下面兩個(gè)原則:

①清空DCaches,使主存數(shù)據(jù)得到更新

②使無(wú)效ICaches,使CPU取指時(shí)重新讀取主存

在實(shí)際編寫(xiě)程序時(shí),要注意如下幾點(diǎn):

①開(kāi)啟MMU前,十五小ICaches,DCaches和Write buffer

②關(guān)閉MMU前,清空ICaches、DCaches,即將”臟“數(shù)據(jù)寫(xiě)到主存上

③如果代碼有變,使無(wú)效ICaches,這樣CPU取指時(shí)會(huì)從新讀取主存

④使用DMA操作可以被Cache的內(nèi)存時(shí),將內(nèi)存的數(shù)據(jù)發(fā)送出去時(shí),要清空Cache;將內(nèi)存的數(shù)據(jù)讀入時(shí),要使無(wú)效Cache

⑤改變頁(yè)表中地址映射關(guān)系時(shí)也要慎重考慮

⑥開(kāi)啟ICaches或DCaches時(shí),要考慮ICaches或DCaches中的內(nèi)容是否與主存保持一致

⑦對(duì)于I/O地址空間,不使用Cache和Write buffer

 

5、S3C2440 MMU、TLB、Cache的控制指令

S3C2440除了ARM920T的CPU核心外,還有若干個(gè)協(xié)處理器,用來(lái)幫助主CPu完成一些特殊功能。對(duì)MMU、TLB、Cache等的操作涉及到協(xié)處理器。

<MCR|MRC>{條件} 協(xié)處理器編碼,協(xié)處理器操作碼1,目的寄存器,源寄存器1,源寄存器2,協(xié)處理器操作碼2

<MCR|MRC> {cond} p#,<expression1>,Rd,cn,cm{,<expression2>}

MRC        //從協(xié)處理器獲得數(shù)據(jù),傳給ARM920T CPU核心寄存器

MCR        //數(shù)據(jù)從ARM920T CPU核心寄存器傳給協(xié)處理器

{cond}        //執(zhí)行條件,省略時(shí)表示無(wú)條件執(zhí)行

p#        //協(xié)處理器序號(hào)

<expression1>        //一個(gè)常數(shù)

Rd        //ARM920T CPU核心的寄存器

cn和cm        //協(xié)處理器中的寄存器

<expression2>        //一個(gè)常數(shù)

其中,<expression1>、cn、cm、<expression2>僅供協(xié)處理器使用,它們的作用如何取決于具體的協(xié)處理器

 

二、MMU使用實(shí)例:地址映射

這個(gè)實(shí)例將開(kāi)啟MMU,并將虛擬地址0xA0000000-0xA0100000映射到物理地址0x56000000-0x56100000(GPBCON物理地址為0x56000010,GPBDAT物理地址為0x56000014),來(lái)驅(qū)動(dòng)LED。

將虛擬地址0xB0000000-0xB3FFFFFF映射到物理地址0x30000000-0x33FFFFFF,在連接程序時(shí),將一部分代碼的運(yùn)行地址指定為0xB0004000.

這個(gè)程序只使用一級(jí)頁(yè)表,以段的方式進(jìn)行地址映射,32位CPU虛擬地址空間達(dá)到4G,一級(jí)頁(yè)表使用4096個(gè)描述符來(lái)表示4G空間(每個(gè)描述符對(duì)應(yīng)1MB),每個(gè)描述符占4字節(jié),所以一級(jí)頁(yè)表占16KB。這個(gè)程序使用SDRAM的開(kāi)始16KB存放一級(jí)頁(yè)表,所以剩下的內(nèi)存開(kāi)始地址就為0x30004000,這個(gè)地址最終會(huì)對(duì)應(yīng)虛擬地址0xB0004000(所以代碼運(yùn)行地址為0xB0004000)

程序分為兩部分:第一部分的運(yùn)行地址為0,它用來(lái)初始化SDRAM,復(fù)制第二部分的代碼到SDRAM中(存放在0x30004000)、設(shè)置頁(yè)表、啟動(dòng)MMU,最后跳到SDRAM中(地址0xB0004000),第二部分運(yùn)行地址設(shè)為0xB0004000,用來(lái)驅(qū)動(dòng)LED

先看連接文件mmu.lds

 

SECTIONS {

  firtst    0x00000000 : { head.o init.o }

  second    0xB0004000 : AT(2048) { leds.o }

}

程序分兩個(gè)段:first和second。first由head.o和init.o組成,加載和運(yùn)行地址都是0,second由leds.o組成,加載地址為2048,重定位地址為0xB0004000。

 

 

@*************************************************************************

@ File:head.S

@ 功能:設(shè)置SDRAM,將第二部分代碼復(fù)制到SDRAM,設(shè)置頁(yè)表,啟動(dòng)MMU,

@       然后跳到SDRAM繼續(xù)執(zhí)行

@*************************************************************************      

.text

.global _start

_start:

    ldr sp, =4096                       @ 設(shè)置棧指針,以下都是C函數(shù),調(diào)用前需要設(shè)好棧

    bl  disable_watch_dog               @ 關(guān)閉WATCHDOG,否則CPU會(huì)不斷重啟

    bl  memsetup                        @ 設(shè)置存儲(chǔ)控制器以使用SDRAM

    bl  copy_2th_to_sdram               @ 將第二部分代碼復(fù)制到SDRAM

    bl  create_page_table               @ 設(shè)置頁(yè)表

    bl  mmu_init                        @ 啟動(dòng)MMU,啟動(dòng)以后下面代碼都用虛擬地址

    ldr sp, =0xB4000000                 @ 重設(shè)棧指針,指向SDRAM頂端(使用虛擬地址)

    ldr pc, =0xB0004000                 @ 跳到SDRAM中繼續(xù)執(zhí)行第二部分代碼

halt_loop:

    b   halt_loop

 

 

/*

 * init.c: 進(jìn)行一些初始化,在Steppingstone中運(yùn)行

 * 它和head.S同屬第一部分程序,此時(shí)MMU未開(kāi)啟,使用物理地址

 */

/* WATCHDOG寄存器 */

#define WTCON           (*(volatile unsigned long *)0x53000000)

/* 存儲(chǔ)控制器的寄存器起始地址 */

#define MEM_CTL_BASE    0x48000000

 

 

 

/*

 * 關(guān)閉WATCHDOG,否則CPU會(huì)不斷重啟

 */

void disable_watch_dog(void)

{

    WTCON = 0;  // 關(guān)閉WATCHDOG很簡(jiǎn)單,往這個(gè)寄存器寫(xiě)0即可

}

 


/*

 * 設(shè)置存儲(chǔ)控制器以使用SDRAM

 */

void memsetup(void)

{

    /* SDRAM 13個(gè)寄存器的值 */

    unsigned long  const    mem_cfg_val[]={ 0x22011110,     //BWSCON

                                            0x00000700,     //BANKCON0

                                            0x00000700,     //BANKCON1

                                            0x00000700,     //BANKCON2

                                            0x00000700,     //BANKCON3 

                                            0x00000700,     //BANKCON4

                                            0x00000700,     //BANKCON5

                                            0x00018005,     //BANKCON6

                                            0x00018005,     //BANKCON7

                                            0x008C07A3,     //REFRESH

                                            0x000000B1,     //BANKSIZE

                                            0x00000030,     //MRSRB6

                                            0x00000030,     //MRSRB7

                                    };

    int     i = 0;

    volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;

    for(; i < 13; i++)

        p[i] = mem_cfg_val[i];        //循環(huán)復(fù)制13個(gè)寄存器到內(nèi)存控制器基址

}

 


/*

 * 將第二部分代碼復(fù)制到SDRAM

 */

void copy_2th_to_sdram(void)

{

    unsigned int *pdwSrc  = (unsigned int *)2048;        //第二段代碼加載地址2048

    unsigned int *pdwDest = (unsigned int *)0x30004000;        //0x30004000前放頁(yè)表

   

    while (pdwSrc < (unsigned int *)4096) //4kb最大4096

    {

        *pdwDest = *pdwSrc;

        pdwDest++;

        pdwSrc++;

    }

}

 


/*

 * 設(shè)置頁(yè)表

 */

void create_page_table(void)

{

 


/*

 * 用于段描述符的一些宏定義

 *[31:20]段基址,[11:10]AP,[8:5]Domain,[3]C,[2]B,[1:0]0b10為段描述符

 */

#define MMU_FULL_ACCESS     (3 << 10)   /* 訪(fǎng)問(wèn)權(quán)限AP */

#define MMU_DOMAIN          (0 << 5)    /* 屬于哪個(gè)域 Domain*/

#define MMU_SPECIAL         (1 << 4)    /* 必須是1 */

#define MMU_CACHEABLE       (1 << 3)    /* cacheable C位*/

#define MMU_BUFFERABLE      (1 << 2)    /* bufferable B位*/

#define MMU_SECTION         (2)         /* 表示這是段描述符 */

#define MMU_SECDESC         (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | \

                             MMU_SECTION)

#define MMU_SECDESC_WB      (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | \

                             MMU_CACHEABLE | MMU_BUFFERABLE | MMU_SECTION)

#define MMU_SECTION_SIZE    0x00100000        /*每個(gè)段描述符對(duì)應(yīng)1MB大小空間*/

 


    unsigned long virtuladdr, physicaladdr;

    unsigned long *mmu_tlb_base = (unsigned long *)0x30000000;        /*SDRAM開(kāi)始地址存放頁(yè)表*/

   

    /*

     * Steppingstone的起始物理地址為0,第一部分程序的起始運(yùn)行地址也是0,

     * 為了在開(kāi)啟MMU后仍能運(yùn)行第一部分的程序,

     * 將0~1M的虛擬地址映射到同樣的物理地址

     */

    virtuladdr = 0;

    physicaladdr = 0;

     //虛擬地址[31:20]用于索引一級(jí)頁(yè)表,找到它對(duì)應(yīng)的描述符,對(duì)應(yīng)于(virtualaddr>>20)

     //段描述符中[31:20]保存段的物理地址,對(duì)應(yīng)(physicaladdr & 0xFFF00000)

    *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | \

                                            MMU_SECDESC_WB;

 


    /*

     * 0x56000000是GPIO寄存器的起始物理地址,

     * GPBCON和GPBDAT這兩個(gè)寄存器的物理地址0x56000010、0x56000014,

     * 為了在第二部分程序中能以地址0xA0000010、0xA0000014來(lái)操作GPBCON、GPBDAT,

     * 把從0xA0000000開(kāi)始的1M虛擬地址空間映射到從0x56000000開(kāi)始的1M物理地址空間

     */

    virtuladdr = 0xA0000000;

    physicaladdr = 0x56000000;

    *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | \

                                            MMU_SECDESC;

 


    /*

     * SDRAM的物理地址范圍是0x30000000~0x33FFFFFF,

     * 將虛擬地址0xB0000000~0xB3FFFFFF映射到物理地址0x30000000~0x33FFFFFF上,

     * 總共64M,涉及64個(gè)段描述符

     */

    virtuladdr = 0xB0000000;

    physicaladdr = 0x30000000;

    while (virtuladdr < 0xB4000000)

    {

        *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | \

                                                MMU_SECDESC_WB;

        virtuladdr += 0x100000;        //右移20位就是1

        physicaladdr += 0x100000;        //右移20位就是1

    }

}

 


/*

 * 啟動(dòng)MMU

 */

void mmu_init(void)

{

    unsigned long ttb = 0x30000000;

 


__asm__(

    "mov    r0, #0\n"

    "mcr    p15, 0, r0, c7, c7, 0\n"    /* 使無(wú)效ICaches和DCaches */

   

    "mcr    p15, 0, r0, c7, c10, 4\n"   /* drain write buffer on v4 */

    "mcr    p15, 0, r0, c8, c7, 0\n"    /* 使無(wú)效指令、數(shù)據(jù)TLB */

   

    "mov    r4, %0\n"                   /* r4 = 頁(yè)表基址 */

    "mcr    p15, 0, r4, c2, c0, 0\n"    /* 設(shè)置頁(yè)表基址寄存器 */

   

    "mvn    r0, #0\n"                  

    "mcr    p15, 0, r0, c3, c0, 0\n"    /* 域訪(fǎng)問(wèn)控制寄存器設(shè)為0xFFFFFFFF, 不進(jìn)行權(quán)限檢查*/   

    /*

     * 對(duì)于控制寄存器,先讀出其值,在這基礎(chǔ)上修改感興趣的位,

     * 然后再寫(xiě)入

     */

    "mrc    p15, 0, r0, c1, c0, 0\n"    /* 讀出控制寄存器的值 */

   

    /* 控制寄存器的低16位含義為:.RVI ..RS B... .CAM

     * R : 表示換出Cache中的條目時(shí)使用的算法,

     *     0 = Random replacement;1 = Round robin replacement

     * V : 表示異常向量表所在的位置,

     *     0 = Low addresses = 0x00000000;1 = High addresses = 0xFFFF0000

     * I : 0 = 關(guān)閉ICaches;1 = 開(kāi)啟ICaches

     * R、S : 用來(lái)與頁(yè)表中的描述符一起確定內(nèi)存的訪(fǎng)問(wèn)權(quán)限

     * B : 0 = CPU為小字節(jié)序;1 = CPU為大字節(jié)序

     * C : 0 = 關(guān)閉DCaches;1 = 開(kāi)啟DCaches

     * A : 0 = 數(shù)據(jù)訪(fǎng)問(wèn)時(shí)不進(jìn)行地址對(duì)齊檢查;1 = 數(shù)據(jù)訪(fǎng)問(wèn)時(shí)進(jìn)行地址對(duì)齊檢查

     * M : 0 = 關(guān)閉MMU;1 = 開(kāi)啟MMU

     */

   

    /* 

     * 先清除不需要的位,往下若需要?jiǎng)t重新設(shè)置它們   

     */

                                        /* .RVI ..RS B... .CAM */

    "bic    r0, r0, #0x3000\n"          /* ..11 .... .... .... 清除V、I位 */

    "bic    r0, r0, #0x0300\n"          /* .... ..11 .... .... 清除R、S位 */

    "bic    r0, r0, #0x0087\n"          /* .... .... 1... .111 清除B/C/A/M */

 


    /*

     * 設(shè)置需要的位

     */

    "orr    r0, r0, #0x0002\n"          /* .... .... .... ..1. 開(kāi)啟對(duì)齊檢查 */

    "orr    r0, r0, #0x0004\n"          /* .... .... .... .1.. 開(kāi)啟DCaches */

    "orr    r0, r0, #0x1000\n"          /* ...1 .... .... .... 開(kāi)啟ICaches */

    "orr    r0, r0, #0x0001\n"          /* .... .... .... ...1 使能MMU */

   

    "mcr    p15, 0, r0, c1, c0, 0\n"    /* 將修改的值寫(xiě)入控制寄存器 */

    : /* 無(wú)輸出 */

    : "r" (ttb) );

}

 
 
/*
 * leds.c: 循環(huán)點(diǎn)亮4個(gè)LED
 * 屬于第二部分程序,此時(shí)MMU已開(kāi)啟,使用虛擬地址
 */
 
#define GPBCON      (*(volatile unsigned long *)0xA0000010)     // 物理地址0x56000010
#define GPBDAT      (*(volatile unsigned long *)0xA0000014)     // 物理地址0x56000014
 
#define GPB5_out    (1<<(5*2))
#define GPB6_out    (1<<(6*2))
#define GPB7_out    (1<<(7*2))
#define GPB8_out    (1<<(8*2))
 
/*
 * wait函數(shù)加上“static inline”是有原因的,
 * 這樣可以使得編譯leds.c時(shí),wait嵌入main中,編譯結(jié)果中只有main一個(gè)函數(shù)。
 * 于是在連接時(shí),main函數(shù)的地址就是由連接文件指定的運(yùn)行時(shí)裝載地址。
 * 而連接文件mmu.lds中,指定了leds.o的運(yùn)行時(shí)裝載地址為0xB4004000,
 * 這樣,head.S中的“l(fā)dr pc, =0xB4004000”就是跳去執(zhí)行main函數(shù)。
 */
static inline void wait(unsigned long dly)
{
    for(; dly > 0; dly--);
}
 
int main(void)
{
    unsigned long i = 0;
   
    // 將LED1-4對(duì)應(yīng)的GPB5/6/7/8四個(gè)引腳設(shè)為輸出
    GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out;      
 
    while(1){
        wait(30000);
        GPBDAT = (~(i<<5));     // 根據(jù)i的值,點(diǎn)亮LED1-4
        if(++i == 16)
            i = 0;
    }
 
    return 0;
}
 

最后是Makefile


objs := head.o init.o leds.o


mmu.bin : $(objs)

arm-linux-ld -Tmmu.lds -o mmu_elf $^

arm-linux-objcopy -O binary -S mmu_elf $@

arm-linux-objdump -D -m arm mmu_elf > mmu.dis

%.o:%.c

arm-linux-gcc -Wall -O2 -c -o $@ $<


%.o:%.S

arm-linux-gcc -Wall -O2 -c -o $@ $<


clean:

rm -f mmu.bin mmu_elf mmu.dis *.o

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
S3C2440的內(nèi)存管理單元MMU--大小頁(yè)地址轉(zhuǎn)換
內(nèi)存管理單元MMU概述
ARM920T虛擬地址原理分析及實(shí)現(xiàn)
嵌入式系統(tǒng)原理與接口技術(shù)
虛擬內(nèi)存 & I/O & 零拷貝
piaoxiang
更多類(lèi)似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服