在創(chuàng)建多任務嵌入式系統(tǒng)時,最好有一個簡單的方式來編寫、裝載及運行各自獨立的任務。目前大多數(shù)的嵌入式系統(tǒng)不再使用自己定制的控制系統(tǒng),而使用操作系統(tǒng)來簡化這個過程。較高級的操作系統(tǒng)采用基于硬件的存儲管理單元MMU來實現(xiàn)上述操作。
MMU提供的一個關(guān)鍵服務是使各個任務作為各自獨立的程序在其自己的私有存儲空間中運行。在帶MMU的操作系統(tǒng)控制下,運行的任務無須知道其他與之無關(guān)的任務的存儲需求情況,這就簡化了各個任務的設(shè)計。
MMU提供了一些資源以允許使用虛擬存儲器(將系統(tǒng)物理存儲器重新編址,可將其看成一個獨立于系統(tǒng)物理存儲器的存儲空間)。MMU作為轉(zhuǎn)換器,將程序和數(shù)據(jù)的虛擬地址(編譯時的連接地址)轉(zhuǎn)換成實際的物理地址,即在物理主存中的地址。這個轉(zhuǎn)換過程允許運行的多個程序使用相同的虛擬地址,而各自存儲在物理存儲器的不同位置。
這樣存儲器就有兩種類型的地址:虛擬地址和物理地址。虛擬地址由編譯器和連接器在定位程序時分配;物理地址用來訪問實際的主存硬件模塊(物理上程序存在的區(qū)域)。
15.5.1MMU概述內(nèi)存管理單位MMU對處理器內(nèi)存提供了很好的管理。這種管理主要是通過一個叫作傳輸表的數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)的。這個傳輸表存在于內(nèi)存中,它有多個稱為Entry的入口,每個入口定義了存儲空間的一個頁,頁的大小從1KB到1MB,同時定義了這些頁的屬性。
ARM系統(tǒng)中,MMU主要完成以下工作:
①虛擬存儲空間到物理存儲空間的映射,它能夠?qū)崿F(xiàn)從虛擬地址到物理地址的轉(zhuǎn)換;
②存儲器訪問權(quán)限的控制;
③設(shè)置虛擬存儲空間的緩存特性。
MMU通過它的協(xié)處理器寄存器來確定傳輸表在內(nèi)存中的位置,并通過這些寄存器來向ARM處理器提供內(nèi)存訪問錯誤信息。
從虛擬地址到物理地址的變換過程是查詢傳輸表的過程,由于傳輸表放在內(nèi)存中,這個查詢過程通常代價很大。這個訪問時間通常是1~2個內(nèi)存周期。為了減少平均內(nèi)存訪問時間,ARM結(jié)構(gòu)體系中采用一個容量更小(通常為8~16個字)、訪問速度和CPU中通用寄存器相當?shù)拇鎯ζ骷泶娣女斍霸L問需要的地址變換條目,它是一個小容量的Cache。這個小容量的頁表Cache稱為TLB(TranslationLookasideBuffer)。
注意
如果系統(tǒng)中使用數(shù)據(jù)和指令統(tǒng)一存儲系統(tǒng),那么TLB也將是統(tǒng)一的。如果系統(tǒng)是數(shù)據(jù)和指令分開的存儲系統(tǒng),那么TLB也將分為數(shù)據(jù)TLB和指令TLB。
MMU可以將整個存儲空間分為最多16個域(domain)。每個域?qū)欢ǖ膬?nèi)存區(qū)域,該內(nèi)存區(qū)域具有相同的訪問控制屬性。MMU中寄存器c3用于控制與域有關(guān)的屬性配置。
表15.20列出了與MMU有關(guān)的協(xié)處理器寄存器及其作用。
表15.20 與MMU有關(guān)的協(xié)處理器寄存器
協(xié)處理器寄存器
作用
c1中某些位
配置MMU中的一些操作
c2
保存內(nèi)存中頁表基地址
c3
設(shè)置域訪問權(quán)限
c4
保留
c5
內(nèi)存訪問失效狀態(tài)標準
c6
內(nèi)存訪問失效時失效地址
c8
控制與清除TLB內(nèi)容相關(guān)的操作
c10
控制與鎖定TLB內(nèi)容相關(guān)的操作
15.5.2MMU與MPU在ARM體系結(jié)構(gòu)中,MMU將MPU的功能大大地增加,使系統(tǒng)內(nèi)存管理更加靈活、方便。在MPU中引入了“域”的概念來管理內(nèi)存,而且域是在專用寄存器中設(shè)置的。而MMU將域設(shè)置從寄存器移到了內(nèi)存單位,這樣使域的設(shè)置更加靈活,但同時也增加了系統(tǒng)訪問時間。
另外,除了提供內(nèi)存保護功能外,MMU還增加了虛擬地址到物理地址的映射。在只有MPU的系統(tǒng)中,每個任務被編譯和運行在彼此不同的、固定的主存地址空間,每個任務只能在一個進程空間中運行,任何兩個任務都不能在主存中有重疊地址。為了運行一個任務,一個保護區(qū)域被設(shè)置在固定地址的程序上,以允許任務訪問由該區(qū)域定義的一段存儲空間。保護區(qū)域的放置使得該任務得以運行,而其他任務空間被保護。
而使用MMU中虛擬地址到物理地址的映射功能,即使任務被編譯、連接、運行在主存中有重疊地址的區(qū)域中,它們?nèi)匀豢梢赃\行。MMU中對虛存的支持可使構(gòu)建后的嵌入式系統(tǒng)具有多個虛擬存儲映射和單個物理存儲器映射。每個任務擁有自己的虛擬存儲器映射,以編譯和連接組成此任務的代碼和數(shù)據(jù)。內(nèi)核層管理各個任務在物理存儲器中的放置,使得它們在物理存儲器中擁有彼此不同的地址,這個地址與其設(shè)計時的虛擬運行地址不一樣。
15.5.3內(nèi)存訪問過程當處理器產(chǎn)生一個內(nèi)存訪問請求時,將傳輸一個虛擬地址給MMU,MMU首先遍歷TLB(如果使用分離的存儲系統(tǒng),它將分別遍歷數(shù)據(jù)TLB和指令TLB)。如果TLB中不保護虛擬地址入口(Entry),那么它將轉(zhuǎn)入保存在內(nèi)存中的傳輸主表,來獲得所有訪問地址的物理地址和訪問權(quán)限。一旦訪問成功,它將新的虛擬地址入口(Entry)信息保存在TLB中,以備下次查詢使用。
當?shù)玫搅说刂纷儞Q入口(Entry)后,將進行以下操作:
①根據(jù)入口(Entry)中的C(cachable)控制位和B(Bufferable)控制位決定是否緩存該內(nèi)存訪問結(jié)果。
②根據(jù)訪問權(quán)限控制位和域訪問控制位確定該內(nèi)存訪問是否被允許。如果該內(nèi)存訪問不被允許,CP15向ARM處理器報告存儲訪問中止。
③對應不允許緩存的存儲訪問,直接得到物理地址訪問內(nèi)存。對于允許緩存的存儲訪問,如果在Cache命中,則忽略物理地址;如果Cache沒有命中,則使用物理地址訪問內(nèi)存,并把該數(shù)據(jù)塊讀到Cache中。
圖15.23為帶Cache的MMU存儲訪問示意圖。
圖15.23帶Cache的MMU存儲訪問示意圖
15.5.4MMU的使能與禁止MMU的使能/禁止可以通過CP15寄存器的c1的bit[0]來控制。
·bit[0]=0,MMU禁止。
·bit[0]=1,MMU使能。
下面的例子顯示了典型的MMU使能過程。
【例15.4】典型的MMU使能過程。
MRCp15,0,r0,c1,0,0
ORRr0,#01
MCRp15,0,r0,c1,0,0
當MMU被禁止時,存儲訪問執(zhí)行下列過程。
①當禁止MMU時,存儲系統(tǒng)是否支持Cache和寫緩存,根據(jù)不同芯片設(shè)計不同而有所不同(ARM公司將設(shè)計權(quán)交給芯片廠商)。
·如果芯片規(guī)定當禁止MMU時禁止Cache和寫緩存,則存儲訪問不考慮C、B控制位。
·如果芯片規(guī)定禁止MMU時使能Cache和寫緩存,則數(shù)據(jù)訪問被視為無Cache(uncachable)和寫緩存(unbufferable)的,即C=0、B=0。讀取指令時,如果系統(tǒng)是統(tǒng)一的TLB,則C=0;如果使用分開的TLB,則C=1。
②存儲訪問不受權(quán)限控制,MMU也不會產(chǎn)生存儲訪問中止信號。
③所有物理地址和虛擬地址相等,即使用平板存儲模式。
使能/禁止MMU時需要注意以下幾個問題。
·在使能MMU之前,正確的傳輸表要在內(nèi)存中事先建立,CP15的相關(guān)寄存器必須完成初始化操作。
·如果使用的不是平板存儲模式(物理地址和對應虛擬地址相等),在禁止/使能MMU時,虛擬地址和物理地址的對應關(guān)系發(fā)生變化,這時應該清除(Flush)Cache中的當前地址變換入口(Entry)。
·如果完成禁止/使能MMU的代碼的物理地址和虛擬地址不同,則禁止/使能MMU將帶來很大麻煩,因此建議完成使能/禁止MMU的代碼的物理地址和虛擬地址相同。
15.5.5虛擬地址到物理地址的轉(zhuǎn)換(1)地址重定位
為了使任務有各自的虛擬存儲器映射,MMU硬件采用地址重定位,在地址訪問主存之前,轉(zhuǎn)換有處理器輸出的虛擬地址。當處理器產(chǎn)生一個虛擬地址時,MMU取出這個虛擬地址的高位,遍歷傳輸表,從而形成一個物理地址。
虛擬存儲空間到物理存儲空間的映射是以內(nèi)存塊為單位進行的。也就是說,虛擬存儲空間中一塊連續(xù)的存儲空間被映射到物理存儲空間中同樣大小的一塊連續(xù)存儲空間。
虛擬存儲空間到物理存儲空間地址重映射過程如圖15.24所示。
圖15.24虛擬存儲空間到物理存儲空間地址重映射過程
ARM支持的存儲塊的大小有以下幾種。
·段(Sections):大小為1M的存儲塊。
·大頁(Largepages):大小為64KB。
·小頁(Smallpages):大小為4KB。
·極小頁(TinyPages):大小為1KB。
段和大頁只需通過一次映射就可以將虛擬地址轉(zhuǎn)換成物理地址,也可以根據(jù)需要增加一級映射,采用兩級映射的方式再將大頁分成16KB的子頁,小頁分成1KB的子頁。極小頁不能再分,只能以1KB大小的整頁為單位。
ARM在內(nèi)存中存在兩級頁表以實現(xiàn)上述地址映射過程。
·一級頁表:一級頁表包括兩種類型的頁表項,即保持指向二級頁表起始地址的頁表項和保存用于轉(zhuǎn)換段(Section)地址的頁表項。一級頁表也稱為段頁表(sectionpagetable)。
·二級頁表:二級頁表包含以大頁和小頁為單位的地址變換頁表項。
一級頁表將4G地址空間劃分為多個1MB的段(Section),因此一級頁表包含4096個頁表項。一級頁表是一個混合表,可以作為二級頁表的目錄表,也可以作為用于轉(zhuǎn)換1MB段(也可視為1MB的虛擬頁)的普通頁表。當一級頁表作為頁目錄時,其頁表項包含的是代表1MB虛擬空間的二級頁表指針。二級頁表分為粗頁表(Coarse)和細頁表(Fine)。當一級頁表用于轉(zhuǎn)換一個1MB的段時,其頁表項包含的是物理存儲器中對應1MB頁幀(pageframe)的首地址。
注意
目錄頁表項和1MB的段頁表項可以共存于一級頁表中。
一個粗二級頁表(Coarse)包含256個頁表項,占有1KB的主存空間,每個頁表項將一個4KB的虛擬存儲塊轉(zhuǎn)換成一個4KB的物理存儲塊。粗二級頁表支持4KB和64KB的頁,頁表項包含的是4KB或64KB的頁幀地址。如果轉(zhuǎn)換的是一個64KB的頁,則對于每個64KB的頁,同一個頁表項必須在頁表中重復16次。
一個細二級頁表(Fine)有1024個頁表項,占有4KB的主存空間,每個頁表項轉(zhuǎn)換一個1KB的存儲塊。細頁表支持1KB、4KB、64KB虛存頁,每個頁表項包含1KB、4KB或64KB的物理頁幀首地址。如果轉(zhuǎn)換的是4KB的頁,則同一個頁表項必須在頁表中連續(xù)重復4次;如果轉(zhuǎn)換的是64KB的頁,則同一個頁表項需要在頁表中連續(xù)重復64次。
一級頁表和二級頁表的特征如表15.21所示。
表15.21 一級頁表和二級頁表特征
類型
頁表占用的存儲空間
(單位:KB)
支持的頁大小
(單位:KB)
頁表項數(shù)目
一級頁表
16
1024
4096
粗二級頁表
1
1,4,64
1024
細二級頁表
4
1,4,64
256
(2)傳輸表基地址
當處理器發(fā)出地址請求信號,而其要求的虛擬地址沒有包含在TLB中時,MMU將會初始化一個產(chǎn)生過程。傳輸過程需要的地址轉(zhuǎn)換表——傳輸表的基地址存放在協(xié)處理器寄存器c2中,MMU通過此基地址找到傳輸表,準備一次地址傳輸過程。
(3)基于一級頁表的地址變換過程
基于一級頁表的地址變換過程是指從虛擬地址到物理地址的轉(zhuǎn)換只需要一級頁表就能完成的地址轉(zhuǎn)換。一級頁表地址轉(zhuǎn)換過程如圖15.25所示。
圖15.25一級頁表地址轉(zhuǎn)換過程
圖15.25中,CP15寄存器c2中存放的是內(nèi)存中一級頁表的基地址。因為一級頁表大小為16KB,也就是說,一級頁表是16KB地址對齊的,所以c2中bits[13∶0]=0,bits[31∶14]為內(nèi)存中頁表基地址。
CP15的寄存器c2的bits[31∶14]和虛擬地址的bits[31∶20]結(jié)合作為一個31位數(shù)的高30位值,忽略32位值的最后兩位,可以使用該值從頁表中查到一個4字節(jié)的地址頁表項。
一級頁表支持以下4種類型的頁表項。
·1MB段轉(zhuǎn)換項;
·指向細二級頁表的目錄項;
·指向粗二級頁表的目錄項;
·產(chǎn)生中止異常的錯誤項。
系統(tǒng)通過頁表項的低兩位bits[1:0]來確定頁表項的類型。頁表項的格式要求二級頁表的地址必須與其頁大小的倍數(shù)對齊。一級頁表的各種頁表項的格式如圖15.26所示。
圖15.26一級頁表項
如果bits[1:0]=0b10時,該頁表項為段描述符(SectionDescriptor),段描述符定義了對應的1MB的虛擬存儲空間的地址映射關(guān)系。
如果bits[1:0]=0b01時,該頁表項包含了粗二級頁表的物理地址。該粗二級頁表定義了對應的1MB虛擬存儲空間的地址映射關(guān)系。它可以實現(xiàn)以大頁和小頁為單位的地址映射。
如果bits[1:0]=0b11時,該頁表項包含了細二級頁表的物理地址。該細二級頁表定義了對應的1MB虛擬存儲空間的地址映射關(guān)系。它可以實現(xiàn)以大頁、小頁和極小頁為單位的地址映射。
如果bits[1:0]=0b00時,說明此頁表項是一個錯誤頁表項。它將產(chǎn)生一個存儲頁錯誤。錯誤條件會導致預取指令中止或數(shù)據(jù)中止,這取決于具體的存儲器訪問類型。
(4)段描述符及其地址變換過程
如果一級頁表頁表項的bits[1∶0]=0b10,說明此頁表項指向一個1MB的存儲段。頁表項的高12位代替虛擬地址的高12位來產(chǎn)生物理地址。該頁表項還包含域?qū)傩浴ahche屬性、緩沖器屬性和訪問權(quán)限屬性。具體定義如表15.22所示。
表15.22 段頁表項中各字段含義
字段
含義
bits[1:0]
段頁表項標識
bits[3:2]
定義段的Cache和寫緩存屬性
bit[4]
生產(chǎn)商定義
bits[8:5]
本段所在的域
bit[9]
當前未被使用,設(shè)置成0
bits[11:10]
訪問權(quán)限控制AP位,見表15.23
bits[19:12]
當前未被使用,設(shè)置成0
bits[31:20]
該段對應的物理空間基地址的高12位
表15.23 訪問權(quán)限控制位的編碼及其含義
訪問權(quán)限控制AP
S
R
特權(quán)模式
用戶模式
0b00
0
0
不可訪問
不可訪問
0b00
1
0
只讀
不可訪問
0b00
0
1
只讀
只讀
0b00
1
1
不可預知
不可預知
0b01
X
X
讀/寫
無訪問
0b10
X
X
讀/寫
只讀
0b11
X
X
讀/寫
讀/寫
表中S和R位是CP15寄存器c1中的控制位,它們分別對應系統(tǒng)(S)和ROM(R)位。這兩位用來在不同模式加速系統(tǒng)中訪問大的存儲塊。
設(shè)置S位使得所有頁具有不可訪問權(quán)限,從而允許特權(quán)模式任務對頁有讀訪問權(quán)限。因此通過改變CP15寄存器c1中的一位,所有標識為不可訪問的空間一下子變?yōu)榭捎?,而不需要改變每個頁表項的AP位,節(jié)省了開銷。
改變R位使得所有頁具有不可訪問權(quán)限,因而特權(quán)模式任務和用戶模式任務對頁都有讀訪問權(quán)限。同樣,這一位可以加速對大塊存儲塊的訪問,而不需要修改許多頁表項的值。
注意
地址轉(zhuǎn)換過程中,在物理地址產(chǎn)生之前,將會按表2.22的編碼對訪問地址的權(quán)限進行檢測。
基于段的地址變換過程如圖15.27所示。
圖15.27基于段的地址變換過程
(5)粗二級頁表描述符及其地址變換過程
如果一級頁表項的bits[1∶0]=0b01,說明此頁表項包含一個粗二級頁表首地址指針,同時還包含一級頁表項代表的1MB虛存段的域信息。粗頁表必須與1KB的倍數(shù)地址對齊。頁表項具體定義見表15.24。
表15.24 粗二級頁表項中各字段含義
字段
含義
bits[1:0]
粗二級頁表描述符標識
bits[4:2]
生產(chǎn)商定義
bits[8:5]
域標識符
bit[9]
當前未被使用,設(shè)置成0
bits[31:10]
粗二級頁表基地址,該地址1KB對齊
基于粗二級頁表的地址變換過程如圖15.28所示。
(6)細二級頁表描述符及其地址變換過程
如果一級頁表項的bits[1:0]=0b11,說明此頁表項包含一個細二級頁表首地址指針,同時還包含一級頁表項代表的1MB虛存段的域信息。細頁表必須與4KB的倍數(shù)地址對齊。頁表項具體定義如表15.25所示。
圖15.28基于粗二級頁表的地址變換過程
表15.25 細二級頁表項中各字段含義
字段
含義
bits[1:0]
細二級頁表描述符標識
bits[4:2]
生產(chǎn)商定義
bits[8:5]
域標識符
bits[11:9]
當前未被使用,設(shè)置成0
bits[31:12]
細二級頁表基地址,該地址4KB對齊
基于細二級頁表的地址變換過程如圖15.29所示。
(7)基于二級頁表的地址變換過程
二級頁表有4種可能的頁表項:
·定義64KB頁幀屬性的大(Large)頁表項;
·定義4KB頁幀屬性的?。⊿mall)頁表項;
·定義1KB頁幀屬性的微(tiny)頁表項;
·訪問中止異常的錯誤項。
系統(tǒng)通過頁表項的最低位[1:0]來確定頁表項的類型。二級頁表的頁表項格式如圖15.30所示。
當bits[1:0]=0b01時,該頁表項為大頁表項,它包含了一個64KB物理存儲塊的基地址。如果頁表是細二級頁表,那么大頁表項將在表中重復64次;如果頁表是粗二級頁表,那么大頁表項將在表中重復16次。
圖15.29基于細二級頁表的地址變換過程
圖15.30二級頁表的頁表項格式
當bits[1:0]=0b10時,該頁表項為小頁表項,它保存一個4KB物理存儲塊的基地址。如果頁表是細二級頁表,那么小頁表項將在表中重復4次;如果頁表是粗二級頁表,那么大頁表項只需在表中出現(xiàn)1次。
當bits[1:0]=0b11時,該頁表項為微頁表項,它保存一個1KB物理存儲塊的基地址。如果頁表是細二級頁表,那么微頁表項只需在表中重復1次;微頁表項不會出現(xiàn)在粗二級頁表中,如果出現(xiàn),那么訪問結(jié)果不可預知。
當bits[1:0]=0b00時,該頁表項產(chǎn)生存儲頁訪問錯誤。錯誤條件會導致預取指中止或數(shù)據(jù)中止,這取決于具體的存儲器訪問類型。
(8)大頁表描述符及其地址變換過程
如果二級頁表項bits[1:0]=0b01,說明該頁表項為大頁表項,它不僅包含了一個64KB物理存儲塊基地址,同時還含有4組權(quán)限位域以及頁的Cache和寫緩存屬性。每一組訪問權(quán)限域代表虛存頁的1/4,這些頁表項可以看成是16KB子頁,以更好的控制64KB頁的訪問權(quán)限。
具體定義如表15.26所示。
表15.26 大頁表項中各字段含義
字段
含義
bits[1:0]
大頁表項類型標識符
bits[3:2]
Cache和寫緩存屬性
bits[11:4]
訪問權(quán)限控制位,具體編碼見表15.27。
一個大頁分為4個子頁
AP0子頁0的訪問權(quán)限
AP1子頁1的訪問權(quán)限
AP2子頁2的訪問權(quán)限
AP3子頁3的訪問權(quán)限
bits[15:12]
當前未使用,應為0
bits[31:16]
該大頁對應的物理頁幀的基地址的高16位
圖15.31說明了基于大頁表的地址變換過程。
圖15.31基于大頁表的地址變換過程
(9)小頁表描述符及其地址變換過程
如果二級頁表項bits[1∶0]=0b10,說明該頁表項為小頁表項,它不僅包含了一個4KB物理存儲塊基地址,同時還含有4組權(quán)限位域以及頁的Cache和寫緩存屬性。每一組訪問權(quán)限域代表虛存頁的1/4,這些頁表項可以看成是1KB子頁,以更好的控制4KB頁的訪問權(quán)限。
頁表項的具體定義如表15.27所示。
表15.27 小頁表項中各字段含義
字段
含義
bits[1:0]
小頁表項類型標識符
bits[3:2]
Cache和寫緩存屬性
bits[11:4]
訪問權(quán)限控制位,具體編碼見表15.22。
一個小頁分為4個子頁
AP0子頁0的訪問權(quán)限
AP1子頁1的訪問權(quán)限
AP2子頁2的訪問權(quán)限
AP3子頁3的訪問權(quán)限
bits[15:12]
當前未使用,應為0
bits[31:16]
該小頁對應的物理頁幀的基地址的高20位
圖15.32說明了基于小頁表的地址變換過程。
圖15.32基于小頁表的地址變換過程
(10)微頁表描述符及其地址變換過程
如果二級頁表項bits[1∶0]=0b11,該二級頁表項是微頁表項,它提供了一個1KB物理存儲塊的基地址,同時含有一個訪問權(quán)限位域以及頁的Cache和寫緩存屬性。微頁表項的具體含義如表15.28所示。
表15.28 微頁表項中各字段含義
字段
含義
bits[1:0]
微頁表項類型標識符
bits[3:2]
Cache和寫緩存屬性
bits[5:4]
訪問權(quán)限控制位,具體編碼見表15.29
bits[9:6]
當前未使用,應為0
bits[31:10]
該微頁對應的物理頁幀的基地址的高22位
圖15.33說明了基于微頁表的地址變換過程。
圖15.33基于微頁表的地址變換過程
注意
ARMv6體系結(jié)構(gòu)不包含微頁,如果打算創(chuàng)建一個很容易移植到以后體系結(jié)構(gòu)的系統(tǒng),則建議在該系統(tǒng)中避免使用1KB微頁。
15.5.6域(domain)和存儲器訪問權(quán)限域指的是一些段、大頁或者小頁的集合。編程的中,設(shè)計者最多可以使用16個域,每個域的訪問控制特征由CP15中的c3中的兩位控制。
CP15中的寄存器c3的格式如圖15.34。
圖15.34CP15寄存器c3編碼格式
其中,每兩個位控制一個域的訪問控制特性,其編碼及對應的含義如表15.29所示。
表15.29 域訪問控制字段編碼及含義
控制位編碼
訪問類型
含義
0b00
無訪問權(quán)限
這時訪問該域?qū)a(chǎn)生訪問失效
0b01
客戶類型(client)
根據(jù)頁表中地址變換頁表項的域訪問權(quán)限控制位決定是否允許特定的存儲訪問
0b10
保留
使用該值會產(chǎn)生不可預知的結(jié)果
0b11
管理者權(quán)限(Manager)
不考慮頁表中頁表項內(nèi)的訪問控制權(quán)限位,所以這種情況下不產(chǎn)生訪問失效
綜上所述,有兩種不同的控制來管理一個任務的存儲器訪問權(quán)限。
·管理者(manager)用于主控(primarycontrol),不考慮每個段、大頁和小頁的訪問權(quán)限。
·客戶(client)使用頁表中的訪問權(quán)限用于次控(secondarycontrol)。
當多個段或者頁從屬于一個域時,這些段或者頁的訪問權(quán)限可以很容易的由域來統(tǒng)一控制。存儲器采用這種管理策略將不同的存儲單元“打包”。
注意
即使不使用MMU提供的虛擬存儲功能,仍然可以把這些內(nèi)核用作簡單的存儲保護單元。首先將虛擬存儲空間直接映射到物理存儲空間,然后為每個任務分配一個不同的域,最后使用這些域來保護睡眠任務(通過將它們的域訪問設(shè)置成不可訪問)。
15.5.7與TLB相關(guān)的操作(1)清除TLB
如果操作系統(tǒng)改變了頁表中的數(shù)據(jù),那么緩存在TLB中的轉(zhuǎn)換數(shù)據(jù)可能就不再有效了。存儲器核有一些CP15命令用于清除TLB,從而使TLB中的數(shù)據(jù)作廢。表15.30是一些可用的命令:清除所有TLB數(shù)據(jù),清除指令TLB,清除數(shù)據(jù)TLB,也可以一次只清除一行TLB數(shù)據(jù)。
表15.30 清除TLB的CP15命令
命令
MCR指令
Rd的值
支持的內(nèi)核
使所有TLB無效
MCRp15,0,Rd,c8,c7,0
0
ARM720T、ARM920T、ARM922T、ARM926EJ-S、ARM1022E、ARM1026EJ-S、StrongARM、Xscale
按行使TLB無效
MCRp15,0,Rd,c8,c7,1
要使之無效的虛擬地址
ARM720T
使指令TLB無效
MCRp15,0,Rd,c8,c5,0
要使之無效的虛擬地址
ARM920T、ARM922T、ARM926EJ-S、ARM1022E、ARM1026EJ-S、StrongARM、Xscale
按行使指令TLB無效
MCRp15,0,Rd,c8,c5,1
要使之無效的虛擬地址
ARM920T、ARM922T、ARM926EJ-S、ARM1022E、ARM1026EJ-S、StrongARM、Xscale
使數(shù)據(jù)TLB無效
MCRp15,0,Rd,c8,c6,0
要使之無效的虛擬地址
ARM920T、ARM922T、ARM926EJ-S、ARM1022E、ARM1026EJ-S、StrongARM、Xscale
按行使數(shù)據(jù)TLB無效
MCRp15,0,Rd,c8,c6,1
要使之無效的虛擬地址
ARM920T、ARM922T、ARM926EJ-S、ARM1022E、ARM1026EJ-S、StrongARM、Xscale
下面的例子顯示了一個使TLB無效的過程。
【例】一個使TLB無效的過程。
MOVr1,0;
MCRp15,0,r1,c8,c7,0
(2)鎖定TLB
由于對TLB表的查詢經(jīng)常會使系統(tǒng)訪問內(nèi)存(要查詢的段、頁不在TLB中),這就使得系統(tǒng)的平均訪問時間大大增加。對于實時系統(tǒng),就需要將一些關(guān)鍵的頁表項鎖定在訪問速度相對較快的TLB中。
ARM920T、ARM922T、ARM926EJ-S、ARM1022E和ARM1026EJ-S內(nèi)核版本支持TLB轉(zhuǎn)換數(shù)據(jù)的鎖定。如果TLB中的某一行是鎖定的,則當TLB清除命令發(fā)出時,它仍然保留在TLB中。
與TLB鎖定相關(guān)的操作可以通過對CP15寄存器r10編程來實現(xiàn)。
各種ARM核的可用鎖定命令如表15.31所示。
表15.31 訪問TLB鎖定寄存器的命令
命令
MCR指令
Rd的值
支持的內(nèi)核
讀數(shù)據(jù)TLB鎖定寄存器
MRCp15,0,Rd,c10,c0,0
TLB鎖定
ARM920T、ARM922T、ARM926EJ-S、ARM1022E、ARM1026EJ-S、StrongARM、Xscale
寫數(shù)據(jù)TLB鎖定寄存器
MCRp15,0,Rd,c10,c7,1
TLB鎖定
ARM920T、ARM922T、ARM926EJ-S、ARM1022E、ARM1026EJ-S、StrongARM、Xscale
讀指令TLB鎖定寄存器
MRCp15,0,Rd,c8,c5,0
TLB鎖定
ARM920T、ARM922T、ARM926EJ-S、ARM1022E、ARM1026EJ-S、StrongARM、Xscale
寫指令TLB鎖定寄存器
MCRp15,0,Rd,c8,c5,1
TLB鎖定
ARM920T、ARM922T、ARM926EJ-S、ARM1022E、ARM1026EJ-S、StrongARM、Xscale
其中Rd的格式如圖15.35所示。
圖15.35Rd格式詳解
其中,
·W=log2N,N為TLB中入口(entry)的個數(shù)。對ARM920T、ARM922T、ARM926EJ-S、ARM1022E版本的內(nèi)核來講,W=6;而對于ARM1026EJ-S內(nèi)核版本,W=3。
·victm位域:確定下次被換出的TLB入口(entry)。
·base位域:從第0個入口(entry)到base−1入口的TLB值,被鎖定。
鎖定TLB中N條地址入口的操作序列如下。
①確保在整個鎖定過程中不會發(fā)生異常中斷,可以通過禁止中斷等方法實現(xiàn)。
②如果鎖定的是指令TLB或指令/數(shù)據(jù)統(tǒng)一的TLB,將base=N、victim=N、P=0寫入寄存器c10。
③使整個將要鎖定的TLB無效。
④如果要鎖定指令TLB,確保與鎖定過程有關(guān)的指令地址變換地址入口已經(jīng)加載到指令TLB中。
注意
在此過程中,TLB的一個地址變換入口可以涵蓋所有與鎖定TLB相關(guān)的指令。這通常是由使整個TLB無效后的第一條指令實現(xiàn)的。
如果要鎖定的是數(shù)據(jù)TLB,確保與鎖定過程有關(guān)的數(shù)據(jù)地址變換地址入口已經(jīng)加載到數(shù)據(jù)TLB中。
注意
在此過程中避免使用內(nèi)嵌語法(inlineliteral)。所有鎖定TLB用到的數(shù)據(jù)可以被TLB中一個地址變換條目所覆蓋。
如果系統(tǒng)使用統(tǒng)一的數(shù)據(jù)TLB和指令TLB,上述兩條都要保證。
⑤對于I=0到N,重復執(zhí)行下列操作:
·將base=I、victim=I、P=1寫入寄存器c10中;
·將每一條想要鎖定到TLB的變換地址入口讀取到TLB中。對于數(shù)據(jù)TLB和數(shù)據(jù)/指令統(tǒng)一的TLB可以使用LDR指令讀取一個涉及該變換地址入口的數(shù)據(jù),將該地址變換入口讀取到TLB中。對于指令TLB,通過操作寄存器c7,將相應的變換地址讀取到指令TLB中。
⑥將base=N、victim=N、P=0寫入寄存器c10中。
要解除TLB中被鎖定的變換地址入口,可以使用下面的操作序列。
①通過操作寄存器c8,使TLB中各被鎖定的變換地址入口無效。
②將base=0、victim=0、P=0寫入寄存器c10中。
15.5.8存儲訪問失效ARM中有兩種存儲訪問失效(Fault)可以導致處理器停止執(zhí)行。
·MMU失效(MMUFault):由MMU檢測到失效(Fault)并通知處理器。
·外部存儲器訪問中止(ExternalAbort):由外部存儲器向存儲器報告無效的存儲器訪問請求。
上述兩種情況統(tǒng)稱為存儲訪問中止(Abort)。如果存儲訪問中止發(fā)生在數(shù)據(jù)訪問周期,CPU將產(chǎn)生數(shù)據(jù)訪問中止異常中斷(DataAbort);如果存儲訪問發(fā)生在指令預取周期,當該指令執(zhí)行時,CPU產(chǎn)生指令預取異常中斷(PrefetchAbort)。
注意
預取指令時發(fā)生錯誤,只有當該指令執(zhí)行時,CPU才會產(chǎn)生指令預取異常中斷。
(1)MMU失效
MMU可以產(chǎn)生4種類型的訪問失效,分別是:
·地址對齊失效(AlignmentFault);
·地址變換失效(TranslationFault);
·域控制失效(DomainFault);
·訪問權(quán)限控制失效(PermissionFault)。
存儲系統(tǒng)可以中止3種類型的存儲訪問:
·Cache行預取(linefetch);
·無Cache和寫緩存的存儲器訪問(uncachedorunbufferedaccesses);
·傳輸表訪問(translationtableaccesses)。
MMU失效優(yōu)先于外部存儲器訪問中止請求。當存儲訪問失效發(fā)生時,系統(tǒng)控制協(xié)處理器中有兩個寄存器分別負責保存發(fā)生中止的失效狀態(tài)和地址。
注意
如果一條指令在預取階段發(fā)生錯誤,它仍將進入指令流水線,直到該條指令被執(zhí)行時,預取異常才發(fā)生。但當預取錯誤指令在進入執(zhí)行階段前,指令發(fā)生跳轉(zhuǎn),那么該預取異常不會發(fā)生,協(xié)處理器錯誤寄存器的狀態(tài)也不會被更新。
(2)MMU中與存儲訪問失效相關(guān)的寄存器
MMU中與存儲訪問失效相關(guān)的寄存器有兩個:
·失效狀態(tài)寄存器(FSR,F(xiàn)aultStatusRegister);
·失效地址寄存器(FAR,F(xiàn)aultAddressRegister)。
失效狀態(tài)寄存器是協(xié)處理器寄存器c5。失效地址寄存器為協(xié)處理器寄存器c6。
當存儲訪問失效發(fā)生時,失效狀態(tài)寄存器中的字段被更新以反映所發(fā)生的存儲訪問失效的相關(guān)的信息,包括存儲訪問所屬的域以及存儲訪問的類型。同時存儲訪問失效的虛擬地址被保存到地址寄存器c6中。
在數(shù)據(jù)訪問周期發(fā)生存儲訪問失效更新了失效狀態(tài)寄存器后,如果系統(tǒng)尚未進入存儲異常模式,這時發(fā)生了指令預取引起的存儲失效,則該指令預取引起的訪問失效將不會更新失效狀態(tài)寄存器的值。這樣就保證了數(shù)據(jù)訪問周期發(fā)生的存儲訪問失效狀態(tài)信息不會被指令預取周期發(fā)生的存儲訪問失效破壞。
引起存儲訪問失效的存儲訪問類型如表15.32所示。
表中,對齊失效的編碼可以為0b0001或0b0011。
表15.32 存儲訪問失效的存儲訪問類型
優(yōu)先級
引起存儲訪問失效的原因
失效狀態(tài)字段
域字段
失效地址寄存器c6
最高
極端異常(TerminalException)
0b0010
無效
生產(chǎn)商定義
中斷向量訪問異常(VectorException)
0b0000
無效
有效
地址對齊(Alignment)
0b00x1
無效
有效
擴展地址變換失效(頁表訪問失效)
一級頁表
0b1100
有效
有效
二級頁表
0b1110
無效
有效
地址變換失效
段失效
0b0101
無效
有效
頁失效
0b0111
有效
有效
域控制失效
段失效
0b1001
有效
有效
頁失效
0b1011
有效
有效
訪問權(quán)限控制失效
段失效
0b1101
有效
有效
頁失效
0b1111
有效
有效
基于Cache的外部存儲訪問系統(tǒng)異常
段失效
0b0100
有效
有效
頁失效
0b0110
有效
有效
最低
非Cache預取時外部存儲訪問異常
段失效
0b1000
有效
有效
頁失效
0b1010
有效
有效
在域控制字段(bits[3:0])中存在無效值,是因為無效發(fā)生在域訪問之前。
當不同的存儲訪問類型同時引起存儲訪問失效時,按照優(yōu)先級由高到低的次序,先保存優(yōu)先級高的存儲訪問失效相關(guān)信息,在表中各存儲訪問優(yōu)先級由上到下依次遞減。
圖15.36顯示了判斷存儲訪問失效的全過程。
下面分別介紹各種類型的存儲訪問失效方式。
①極端異常(terminalexception)
極端異常指的是發(fā)生了不可恢復的存儲訪問失效。具體屬于哪種情況,有生產(chǎn)商定義。
②中斷向量訪問異常(vectorexception)
在數(shù)據(jù)訪問周期,如果訪問異常中斷向量表(地址0x0到0x1f)時發(fā)生存儲訪問失效,這種存儲訪問失效稱為中斷向量訪問異常。當MMU被禁止時是否產(chǎn)生中斷向量訪問異常由生產(chǎn)商決定。
③地址對齊失效
在數(shù)據(jù)訪問周期,如果訪問字單元地址時地址bits[1:0]位不是0b00,或者訪問半字單元時地址bits[0]位不是0b0,則產(chǎn)生的存儲訪問失效稱為地址對齊失效。在指令預取周期不會產(chǎn)生地址對齊失效。在數(shù)據(jù)訪問周期,如果訪問字節(jié)單位,不會產(chǎn)生地址訪問失效。
④地址變換失效
有兩種類型的地址變換失效。一種是基于段的地址變換失效,它指當一級頁表描述符的位bits[1:0]=0b00時,表示該一級描述符頁表項無效,這時產(chǎn)生基于段的地址變換失效。第二種是基于頁的地址變換失效。當二級描述符的位bits[1:0]=0b00時,表示該二級描述符頁表項無效,這時產(chǎn)生基于頁的地址變換失效。
圖15.36判斷存儲訪問失效的全過程。
⑤域控制位失效
域控制位失效包括兩種類型。一種基于段的存儲訪問域控制失效。在一級描述符中包含4位的域標識符。該標識符指定了本段所屬的域,在MMU讀取一級描述符時,它檢查域訪問控制寄存器c3中對應于該域的控制位,如果相應的兩位控制位為0b00,說明該域不允許存儲訪問,這時,就產(chǎn)生了基于段的存儲訪問域控制失效。第二種是基于頁的存儲訪問中域控制位失效。在一級描述符中包含4位的域標識符。該標識符指定了本頁所屬的域,在MMU讀取一級描述符時,它檢查域訪問控制寄存器c3中對應于該域的控制位,如果相應的兩位控制位為0b00,說明該域不允許存儲訪問,這時就產(chǎn)生了基于頁的存儲訪問域控制失效。
⑥訪問權(quán)限失效
訪問權(quán)限失效的檢查是在域控制位失效檢查時進行的。這時如果域訪問控制器中對應于該域的控制位為0b01,則要進行相應的權(quán)限檢查。訪問權(quán)限失效有兩種類型。一種基于段的存儲訪問權(quán)限控制失效,對于基于段的存儲訪問,在一級描述符中包含一個兩位的訪問權(quán)限控制位AP。如果字段AP標識了不允許進行相關(guān)存儲訪問時,產(chǎn)出基于段的存儲訪問權(quán)限控制失效。第二種是基于頁的存儲訪問控制失效。對于基于頁的存儲訪問,在二級描述符中定義的可能為大頁、小頁或者微頁。當二級描述符中定義的為微頁時,該二級描述符中包含一個對應于該微頁的訪問控制字段AP,如果字段AP標識了不允許進行相關(guān)的存儲訪問,這時產(chǎn)生基于子頁的存儲訪問權(quán)限控制失效。同樣,當二級頁表描述符中定義的為小頁或大頁時,操作過程同微頁。
(3)外部存儲訪問失效
除處理器內(nèi)部MMU向CPU報告錯誤外,ARM體系結(jié)構(gòu)還定義了一個外部訪問中斷引腳。該引腳可以用于外部存儲器向CPU訪問失效異常。但是,并不是所有失效異常都可以通過這種方式報告,所以該引腳在連線時要非常注意。下面列舉了存儲訪問操作,可以通過這種機制中止和重啟動。
·讀操作(reads)。
·非緩存的寫操作(unbufferedwrites)。
·一級描述符預取(first-leveldescriptorfetch)。
·二級描述符預?。╯econd-leveldescriptorfetch)。
·非緩存的信號量操作(semaphoresinuncachable/unbufferablememoryareas)。
在Cache預取時,可以在任意字時終止存儲訪問過程。如果存儲訪問發(fā)生在存儲器想要獲取的數(shù)據(jù)中,這時該存儲訪問將立即被中止。如果產(chǎn)生中止的數(shù)據(jù)是在Cache預取時,從存儲器順序讀出的,那么直到這些數(shù)據(jù)被存儲器訪問時,該存儲訪問才會被中止。
帶緩存的寫操作不能通過這種方式向CPU報告異常。因此,在系統(tǒng)中標記為可外部中止的存儲區(qū)域不要進行可緩存的寫操作。
15.5.9快速上下文切換擴展(FCSE,F(xiàn)astContextSwitchExtension)(1)快速上下文切換擴展原理
快速上下文切換擴展(FCSE,F(xiàn)astContextSwitchExtension)是MMU中的一個附加硬件,用于提高ARM嵌入式系統(tǒng)的系統(tǒng)性能。FCSE使得多個獨立任務可以運行在一個固定的重疊存儲空間中,而在上下文切換時,不需要清理(clean)或清除(flush)Cache和TLB。FCSE主要特征就是不需要清除Cache和TLB。
通常情況下,如果兩個進程占有的虛擬地址空間有重疊,系統(tǒng)在兩個進程之間進行切換時,必須進行虛擬地址到物理地址的重映射。而虛擬地址到物理地址重映射涉及到重建MMU中頁表,而且Cache及TLB中的內(nèi)容都必須使無效。這樣操作將帶來巨大的系統(tǒng)開銷,一方面重建MMU和使無效Cache及TLB的內(nèi)容需要很大的開銷,另一方面重建Cache和TLB內(nèi)容也需要很大的開銷。
快速上下文切換擴展的引入避免了這種開銷。它位于CPU和MMU之間,如果兩個進程使用了同樣的虛擬地址空間,則對CPU而言,兩個進程的空間地址是一樣的。快速上下文切換擴展對各進程的虛擬地址進行變換,這樣系統(tǒng)中CPU之外的部分看到的是經(jīng)過快速上下文切換擴展變換的虛擬地址??焖偕舷挛那袚Q擴展將各進程的虛擬空間變換成不同的虛擬空間。這樣在進行進程間切換時就不需要進行虛擬地址到物理地址的重映射。
快速上下文切換擴展將CPU發(fā)出的每個虛擬地址按照上述的規(guī)則進行變換,然后發(fā)送到系統(tǒng)中的其他部分。變換過程如圖15.37所示。
圖15.37快速上下文切換擴展變換過程
使用快速上下文切換擴展,虛擬存儲管理增加了一次地址轉(zhuǎn)換??焖偕舷挛那袚Q擴展在虛擬地址到達Cache和TLB前,使用一個特殊的、包含進程ID值的重定位寄存器來修改虛地址。把第一次變換前的地址稱為虛地址VA(VirtualAddress),把第一次變換后的地址稱為修改后虛擬地址MVA(ModifiedvirtualAddress)。
這樣,任務間的切換就不用涉及到改變頁表,只需簡單地將新任務的進程ID寫到位于CP15地FCSE進程ID寄存器。正是因為任務切換不需要改變頁表,因而切換后Cache和TLB中的值依然保持有效,不需要清除。
ARM系統(tǒng)中,4GB的虛擬空間被分為128個進程空間快,每個進程空間塊大小為32MB。每個進程空間塊中可以包含一個進程,該進程可以使用虛擬地址空間0x00000000~0x01ffffff,這個地址范圍也就是CPU看到的進程的虛擬空間。系統(tǒng)128個進程空間塊的編號為0~127,編號為1的進程空間塊中的進程實際使用虛擬地址空間為1×0x02000000~1×0x02000000+0x01ffffff。這個地址空間是系統(tǒng)中除CPU之外的其他部分看到的該進程所占有的虛擬地址空間。
由地址VA到MVA的變換算法如下所示。
MVA=VA+(ox02000000×進程ID)
保存在CP15寄存器c13寄存器中的值包含進程ID,c13中從bit[31]~bit[25]共7位標識進程ID,因此可以有128個進程。寄存器格式如圖15.38。
圖15.38快速上下文切換寄存器c13
訪問寄存器c13的指令格式如下所示:
MCRp15,0,<Rd>,<c13>,c0,0
MRCp15,0,<Rd>,<c13>,c0,0
其中,在讀操作時,結(jié)果中位[31:25]返回PID,其他位的數(shù)值是不可預知的。寫操作將設(shè)置PID的值。
當PID=0時,MVA=VA,相當于禁止了FCSE。系統(tǒng)復位后PID為0。
當正在運行的進程訪問別的進程時,被訪問的進程標識不能為0。這時,CPU發(fā)生的地址VA的高7位不是全0。
完整的VA到MVA的變換算法如下所示。
If(VA[31:25]==0b0000000)then
MVA=VA|(PID<<25=
Else
MVA=VA
(2)一個快速上下文切換的例子
圖15.39顯示了一個從任務1切換到任務2之前和之后的存儲器布局。
任務1正在運行
任務2正在運行
圖15.39快速上下文切換擴展例子
從圖中可以看出,任務1和任務2都運行在0x00000000~0x01ffffff的地址空間。從任務1切換到任務2域控制要做相應的改變。通過在CPU和MMU之間加FCSE使系統(tǒng)的虛擬地址空間映射沒有改變,所以不需要清除(Flush)或清理(Clean)Cache或TLB。
使用FCSE時執(zhí)行一次上下文切換需要的步驟:
①保存執(zhí)行任務的上下文,并將執(zhí)行任務設(shè)置為睡眠態(tài);
②將喚醒任務的進程ID寫到CP15的寄存器c13中;
③通過寫CP15的寄存器c3,將當前任務的域設(shè)置為不可訪問,而喚醒任務的域設(shè)置為客戶訪問;
④恢復喚醒任務的上下文;
⑤繼續(xù)執(zhí)行被恢復的任務。
下面是關(guān)于FCSE的一些提示。
①任務在大小上有固定的最大32MB的限制。
②存儲管理必須使用有固定起始地址(32MB的倍數(shù))的固定32MB分區(qū)。
③除非想為每個任務管理一個異常向量表,否則使用CP15寄存器c1的V位將異常向量表放置在虛擬地址0xffff0000。
④必須定義和使用一個活躍的域控制系統(tǒng)。
⑤如果使用域來保護各個任務,則除非修改一級頁表中域的相應位,并在上下文切換時清除TLB,否則最多只能有16個并發(fā)任務。