嵌入式系統中,存儲系統差別很大,可包含多種類型的存儲器件,如 FLASH , SRAM , SDRAM , ROM 等,這些不同類型的存儲器件速度和寬度等各不相同;在訪問存儲單元時,可能採取平板式的地址映射機制對其操作,或需要使用虛擬地址對其進行讀寫;系統中,需引入存儲保護機制,增強系統的安全性。爲適應如此複雜的存儲體系要求, ARM 處理器中引入了存儲管理單元來管理存儲系統。
一 內存管理單元( MMU )概述
在 ARM 存儲系統中,使用 MMU 實現虛擬地址到實際物理地址的映射。爲何要實現這種映射?首先就要從一個嵌入式系統的基本構成和運行方式着手。系統上電時,處理器的程序指針從 0x0 (或者是由 0Xffff_0000 處高端啓動)處啓動,順序執行程序,在程序指針( PC )啓動地址,屬於非易失性存儲器空間範圍,如 ROM 、 FLASH 等。然而與上百兆的嵌入式處理器相比, FLASH 、 ROM 等存儲器響應速度慢,已成爲提高系統性能的一個瓶頸。而 SDRAM 具有很高的響應速度,爲何不使用 SDRAM 來執行程序呢?爲了提高系統整體速度,可以這樣設想,利用 FLASH 、 ROM 對系統進行配置,把真正的應用程序下載到 SDRAM 中運行,這樣就可以提高系統的性能。然而這種想法又遇到了另外一個問題,當 ARM 處理器響應異常事件時,程序指針將要跳轉到一個確定的位置,假設發生了 IRQ 中斷, PC 將指向 0x18( 如果爲高端啓動,則相應指向 0vxffff_0018 處 ) ,而此時 0x18 處仍爲非易失性存儲器所佔據的位置,則程序的執行還是有一部分要在 FLASH 或者 ROM 中來執行的。那麼我們可不可以使程序完全都 SDRAM 中運行那?答案是肯定的,這就引入了 MMU ,利用 MMU ,可把 SDRAM 的地址完全映射到 0x0 起始的一片連續地址空間,而把原來佔據這片空間的 FLASH 或者 ROM 映射到其它不相沖突的存儲空間位置。例如, FLASH 的地址從 0x0000_0000 - 0x00ff_ffff, 而 SDRAM 的地址範圍是 0x3000_0000 - 0x31ff_ffff ,則可把 SDRAM 地址映射爲 0x0000_0000 - 0x1fff_ffff 而 FLASH 的地址可以映射到 0x9000_0000 - 0x90ff_ffff (此處地址空間爲空閒,未被佔用)。映射完成後,如果處理器發生異常,假設依然爲 IRQ 中斷, PC 指針指向 0x18 處的地址,而這個時候 PC 實際上是從位於物理地址的 0x3000_0018 處讀取指令。通過 MMU 的映射,則可實現程序完全運行在 SDRAM 之中。
在實際的應用中,可能會把兩片不連續的物理地址空間分配給 SDRAM 。而在操作系統中,習慣於把 SDRAM 的空間連續起來,方便內存管理,且應用程序申請大塊的內存時,操作系統內核也可方便地分配。通過 MMU 可實現不連續的物理地址空間映射爲連續的虛擬地址空間。
操作系統內核或者一些比較關鍵的代碼,一般是不希望被用戶應用程序所訪問的。通過 MMU 可以控制地址空間的訪問權限,從而保護這些代碼不被破壞。
二 MMU 地址映射的實現
MMU 的實現過程,實際上就是一個查表映射的過程。建立頁表( translate table )是實現 MMU 功能不可缺少的一步。頁表是位於系統的內存中,頁表的每一項對應於一個虛擬地址到物理地址的映射。每一項的長度即是一個字的長度(在 ARM 中,一個字的長度被定義爲 4 字節)。頁表項除完成虛擬地址到物理地址的映射功能之外,還定義了訪問權限和緩衝特性等。
1 、映射存儲塊的分類
MMU 支持基於節或頁的存儲器訪問, MMU 可以用下面四種大小進行映射:
節 ( Section ) 構成 1MB 的存儲器塊
支持 3 中不同的頁尺寸:
微頁 ( Tiny page ) 構成 1KB 的存儲器塊
小頁 ( Small page ) 構成 4KB 的存儲器塊
大頁 ( Large page ) 構成 64KB 的存儲器塊
其中對於節映射使用一級轉換表就可以了,而對於微頁、小頁、大頁則需要使用兩級轉換表。
存在主存儲器內的轉換表有兩個級別:
2 、第一級轉換表
(注:本文中的頁表與轉換表同義)
存儲節轉換表和指向第二級表的指針。
注: 上圖中粗糙頁表欄中的最後一項應爲‘01 ’
第一級表的每個入口是一個描述它所關聯的 1MB 虛擬地址是如何映射的描述符。見表 3-1 ,根據 bits[1:0] 的組合,有四種可能:
· 如果 bits[1:0]==0b00 ,所關聯的地址沒有被映射,試圖訪問他們將產生一個轉換錯( fault )。因爲他們被硬件忽略,所以軟件可以利用這樣的描述符的 bits[31:2] 做自己的用途。推薦爲描述符繼續保持正確的訪問權限。
· 如果 bits[1:0]==0b10 ,這個入口是它所關聯地址的節描述符。見節描述符和轉換節參考中的細節。
· 如果 bits[0]==1 ,這個入口給出粗糙第二級表( bit[1]==0 ),或精細第二級表( bit[1]==1 )。
每一種類型的表描述了它所關聯的 1MB 存儲區域的映射。粗糙第二級表較小,每個表 1KB ,每個精細第二級表 4KB 。然而粗糙第二級表只能映射大頁和小頁,精細第二級表可以映射大頁、小頁和微頁。
節描述符和轉換節參考
l 如果第一級描述符是節描述符,那麼各個字段有如下的意義:
Bits[1:0] 描述符類型標識( 0b10 表示節描述符)
Bits[3:2] 高速緩存和緩衝位
Bits[4] 由具體實現定義
Bits[8:5] 這個描述符控制的節的 16 種域之一
Bits[9] 現在沒有使用,應該爲零
Bits[11:10] 訪問控制,見表 3-3
Bits[19:12] 現在沒有使用,應該爲零
Bits[31:20] 節基址,形成物理地址的高 12 位
l 如果第一級描述符是粗糙頁表描述符,那麼各個字段有如下的意義:
Bits[1:0] 描述符類型標識( 0b01 表示粗糙頁表描述符)
Bits[4:2] 由具體實現定義
Bits[8:5] 這個描述符控制的頁的 16 種域之一
Bits[9] 現在沒有使用,應該爲零
Bits[31:10] 頁表基地址是一個指向第二極粗糙頁表的指針,
l 如果第一級描述符是精細頁表描述符,那麼各個字段有如下的意義:
Bits[1:0] 描述符類型標識( 0b11 表示精細頁表描述符)
Bits[4:2] 由具體實現定義
Bits[8:5] 這個描述符控制的頁的 16 種域之一
Bits[11:9] 現在沒有使用,應該爲零
Bits[31:10] 頁表基地址是一個指向第二級精細頁表的指針,它給出第二級表
訪問的基地址。而第二級精細頁表必須在 4KB 邊界對齊。
3 、第二級轉換表
存儲大頁和小頁的轉換表。一種類型的第二級表存儲微頁轉換表。
每個粗糙第二級表對映着以4KB 爲單位的虛擬地址範圍市怎麼映射的,每個精細第二級表對映着以1KB 爲單位的虛擬地址範圍市怎麼映射的。那些入口是頁描述符,他們能夠分別描述大於4KB 或1KB 的頁。在這種情況下,這個描述符必須被重複足夠次,以保證這個頁始終使用相同的描述符,不論訪問這個頁中的哪個虛擬地址。對於一個第二級描述符,有四種可能,由描述符的bits[1:0] 選擇。見表3-2 :
· ? 如果bits[1:0]==0b00 ,說關聯的虛擬地址沒有被映射,任何對這些虛擬地
址的訪問將會導致轉換錯(fault) 。軟件可以利用這樣的描述符的bits[31:2] 做自己的用途,因爲他們被硬件忽略。推薦爲描述符繼續保持正確的訪問權限。
· ? 如果bits[1:0]==0b01 ,這個入口是大頁描述符,描述64KB 的虛擬地址。
見轉換大頁參考。一個大頁描述符在精細第二級表中必須被重複64 次,在粗
糙第二級表中必須被重複16 次以保證所有的虛擬地址都被描述。
· ? 如果bits[1:0]== 0b10 ,這個入口是小頁描述符,描述4KB 的虛擬地址。
見轉換小頁參考。一個小頁描述符在精細第二級表中必須被重複4 次,以保
證所有的虛擬地址都被描述。在粗糙第二級表中只有一個實例。
· ? 如果bits[1:0]== 0b11 ,這個入口是微頁描述符,描述1KB 的虛擬地址。
見轉換微頁參考。在精細第二級表中只需要一個微頁描述符的實例。微頁描
述符不能在粗糙第二級表中出現,如果出現了,結果不可預測。
大頁描述符字段
大頁描述符的字段有如下意義:
bits[1:0] 表示描述符的類型
bits[3:2] 高速緩促和緩衝位
bits[11:4] 訪問權限位。這些爲控制對頁的訪問。關於這些位的解釋見表3-3 。
大頁被分成4 各子頁。
AP0 編碼對第一個子頁的訪問權限。
AP1 編碼對第二個子頁的訪問權限。
AP2 編碼對第三個子頁的訪問權限。
AP3 編碼對第四個子頁的訪問權限。
bits[15:12] 現在沒有使用,應該爲零。
bits[31:16] 用來形成物理地址的對應位。
?
小頁描述符字段
小頁描述符的字段有如下意義:
bits[1:0] 表示描述符的類型
bits[3:2] 高速緩促和緩衝位
bits[11:4] 訪問權限位。這些爲控制對頁的訪問。關於這些位的解釋見表3-3 。
小頁被分成4 各子頁。
AP0 編碼對第一個子頁的訪問權限。
AP1 編碼對第二個子頁的訪問權限。
AP2 編碼對第三個子頁的訪問權限。
AP3 編碼對第四個子頁的訪問權限。
bits[31:12] 用來形成物理地址的對應位。
微頁描述符字段
微頁描述符的字段有如下意義:
bits[1:0] 表示描述符的類型
bits[3:2] 高速緩促和緩衝位
bits[5:4] 訪問權限位。這些爲控制對頁的訪問。關於這些位的解釋見表3-3 關於微頁的解釋。
bits[9:6] 現在沒有使用,應該爲零。
bits[31:10] 用來形成物理地址的對應位。
MMU 把 CPU 產生的虛擬地址轉換成物理地址去訪問外部存儲器,同時繼承並檢查訪問權限。地址轉換有四條路徑。路徑的選取由這個地址是被標記成節映射訪問還是頁映射訪問確定。頁映射訪問可以是大、小和微頁的訪問。
MMU 的映射分爲兩種,一級頁表的變換和二級頁表變換。兩者的不同之處就是所實現的變換地址空間大小不同。一級頁表變換支持 1M 大小的存儲空間的映射,而二級可以支持 64KB 、 4KB 和 1KB 大小地址空間的映射。
要實現從虛擬地址到物理地址的映射,必然會遇到一個問題,如何找到這個頁表。對於表的查找,要知道這個表的基地址和偏移地址,在具有 MMU 功能的處理器中,集成了一個被稱爲 CP15 的協處理器,該協處理器的 C2 寄存器中用於保存頁表的基地址,
下面以一級頁表變換爲例說明 MMU 實現地址變換的過程。
4 、節訪問的轉換過程
節和大頁是支持允許只用一個 TLB 入口去映射大的存儲器區間。小頁和大頁有附加的訪問控制:小頁分成 1KB 的子頁,和大頁分成 16KB 的子頁。微頁沒有子頁,對微頁的訪問控制是對整個頁。
然而,轉換過程總是由下面所描述的那樣由第一級表的獲取開始。節映射的訪問只需要讀取第一級表,頁映射的訪問還需要讀取第二級表。
1 轉換表基址
當片上( on-chip )的 TLB 中不包含被要求的虛擬地址的入口時,轉換過程被啓動。轉換表基址寄存器( CP15 的寄存器 2 )保存着第一級轉換表基址的物理地址。只有 bits[31:14] 有效, bits[13:0] 應該是零( SBZ )。所以第一級表必須在 16KB 的邊界。
2 取第一級表
轉換表基址寄存器的 bits[31:14] 與虛擬地址的 bits[31:20] 和兩個 0 位連接形成 32 爲物理地址,如圖 3-2 。這個地址選擇了一個四字節的轉換表入口,它是第一級描述符或是指向第二級頁表的指針。
當處理器訪問一個虛擬地址時,該虛擬地址的 [31 : 20] 作爲偏移地址與頁基地址結合(基地址必須是 64KB 對齊的,因此基地址的 [13 : 0] 位都爲 0 ),得到一個 32 位的頁表項地址(因爲頁表項爲 4 字節對齊, [1 : 0] 兩位爲 0 )。通過這個頁表項地址可以檢索到該頁表項。頁表項的格式見前面第一級轉換表。
查找到頁表項後,根據頁表項的訪問特性(緩衝以及是否允許訪問等)協處理器決定是否允許訪問。如不允許訪問,則協處理器向 CPU 報告出錯信息;反之,由頁表項的 [31 : 20] 位與虛擬地址的 [19 : 0] 一起組成實際的物理地址,實現從虛擬地址到物理地址的映射。如下圖所示:
5 、粗糙二級表中的小頁轉換
如果從第一級讀取到的是二級粗糙頁表描述符,那麼會象下圖3-7 所示執行第二級描述符讀取。
6 、精細二級表中的微頁轉換
如果從第一級讀取到的是二級精細頁表描述符,那麼會象圖3-5 所示執行第
二級描述符讀取。
7 、存儲器訪問的順序
查找整個轉換表的過程叫轉換表遍歷。它由硬件制動進行,並需要大量的執行時間(至少一個存儲器訪問,通常是兩個)。爲了減少存儲器訪問的平均消耗,轉換表遍歷結果被高速緩存在一個或多個叫作Translation Lookaside Buffers(TLBs) 的結構中。通常在ARM 的實現中每個內存接口有一個TLB 。
因此,當 ARM 要訪問存儲器時, MMU 先查找 TLB 中的虛擬地址表,如果 ARM 的結構支持分開的地址 TLB 和指令 TLB ,那麼它用:
· 取指令使用指令 TLB
· 其它的所有訪問類別用數據 TLB
如果 TLB 中沒有虛擬地址的入口,則轉換表遍歷硬件從存在主存儲器中的轉換表中獲取轉換和訪問權限,一旦取到,這些信息將被放在 TLB 中,它會放在一個沒有使用的入口處或覆蓋一個已有的入口。
一旦爲存儲器訪問的 TLB 的入口被拿到 , 這些信息將被用於:
1. C (高速緩存)和 B (緩衝)位被用來控制高速緩存和寫緩衝,並決定是否高速緩存。(如果系統中沒有高速緩存和寫緩衝,則對應的位將被忽略)
2. 訪問權限和域位用來控制訪問是否被允許。如果不允許,則 MMU 將向 ARM 處理器發送一個存儲器異常;否則訪問將被允許進行。
3. 對沒有高速緩存的系統(包括在沒有高速緩存系統中的所有存儲器訪問),物理地址將被用作主存儲器訪問的地址。對有高速緩存的系統,在高速緩存沒有選中的情況下,物理地址將被用行取 (line fetch) 的地址。如果選中了高速緩存,則物理地址將被忽略。圖 3-1 說明了這種高速緩存系統
三、協處理器 CP15
MMU 由系統控制寄存器的2 、3 、4 、5 、6 、8 、10 號寄存器和1 號寄存器的一些位控制。
5.1 對協處理器寄存器的操作
ARM 寄存器到協處理器的數據傳誦指令和反向傳送指令分別爲MCR MRC
l MCR
MCR 指令將ARM 處理器的寄存器中的數據傳送到協處理器的寄存器中。若協處理器不能成功執行該操作,將產生未定義指令異常中斷。指令格式如下:
MCR{cond} coproc ,opcode1 ,Rd ,CRn ,CRm{ ,opcode2}
其中 coproc 指令操作的協處理器的名稱,標準名爲pn ,n 爲0~15 ,這裏爲p15
opcode1 協處理器的特定操作碼
Rd 做源的ARM 處理器寄存器
CRn 存放第一個操作數的協處理器寄存器
CRm 存放第二個操作數的協處理器寄存器
opcode2 可選的協處理器操作碼
指令舉例如下:
MCR p6,2,R7,c1,c2
MCR p7,0,R1,c3,c2,1
l MRC
MRC 指令將協處理器的寄存器中的數據傳送到ARM 理器的寄存器中。若協處理器不能成功執行該操作,將產生未定義指令異常中斷。指令格式如下:
MRC{cond} coproc ,opcode1 ,Rd ,CRn ,CRm{ ,opcode2}
其中 coproc 指令操作的協處理器的名稱,標準名爲pn ,n 爲0~15 ,這裏爲p15
opcode1 協處理器的特定操作碼
Rd 做目標的ARM 處理器寄存器
CRn 存放第一個操作數的協處理器寄存器
CRm 存放第二個操作數的協處理器寄存器
opcode2 可選的協處理器操作碼
指令舉例如下:
MRC p6,2,R7,c1,c2
MCR p7,0,R1,c3,c2,1
CP15 寄存器 0 , ID 代碼及緩存類型
訪問:只讀
CP 寄存器 0 包含詳細的硬件信息。讀訪問內容由 opcode_2 域值確定。對寄存器 0 寫入結果無法預計。
將 opcode_2 域置 0 後讀寄存器 0 訪問 ID 代碼寄存器 。
將 opcode_2 域置 1 後讀寄存器 0 訪問緩存類型寄存器。緩存類型寄存器包含緩存大小與架構信息。
CP15 寄存器 1 ,控制
訪問:讀 / 寫
CP15 寄存器 1 或或稱爲控制寄存器包含 ARM920T 控制位
各個控制位的作用:
• M[0]: MMU 使能
0 = MMU 禁用
1 = MMU 使能
• A[1]: 隊列故障使能
0 = 故障校驗禁用
1 = 故障校驗使能
• C[2]: DCache 使能
0 = DCache 禁用
1 = DCache 使能
• B[7]: Endianness
0 = 小 endian 模式
1 = 大 endian 模式
• S[8]: 系統保護
修改 MMU 保護系統
詳見 ARM920T 技術參考手冊 Rev. DDI0151C 。
• R[9]: ROM 保護
修改 MMU 保護系統
詳見 ARM920T 技術參考手冊 Rev. DDI0151C 。
• I[12]: ICache 控制
0 = ICache 禁用
1 = ICache 使能
• V[13]: 異常寄存器基地址
0 = 低地址,爲 0x00000000
1 = 高地址,爲 0xFFFF0000
• RR[14]: Round Robin 置換
0 = 隨機置換
1 = Round robin 置換
CP15 寄存器 2, TTB
訪問:讀 / 寫
CP15 寄存器 2 ,或轉換表基 (TTB) 寄存器,定義轉換表第一級,用於存放頁表基址
讀 CP15 寄存器 2 時,在 bits[31:14] 返回當前活動的第一級轉換表的物理地址, bits[13:0] 不確定。讀 CP15 寄存器 2 時, CRm 和操作數 2 被忽略,並應該是 0 。
寫 CP15 寄存器 2 時,在 bits[31:14] 更新當前活動的第一級轉換表的物理地址, bits[13:0] 應該寫 0 或先前讀回的值。寫 CP15 寄存器 2 時, CRm 和操作數 2 被忽略,並應該是 0 。
CP15 寄存器 3 ,域訪問控制寄存器
訪問:讀 / 寫
CP 15 寄存器 3 ,或域訪問控制寄存器,定義允許域訪問。
使用 16 域進行 MMU 訪問優先級控制。
寄存器 3 中的每兩位對應一個域。
域是節、大頁和小頁的集合。 ARM 結構支持 16 個域。對域的訪問由域訪問控制寄存器的兩個位字段控制。因爲每個字段對訪問對應的域的使能非常迅速,所以整個存儲器區間能很快地交換進出虛擬存儲器。這裏支持 2 種域訪問方式:
客戶域的用戶(執行程序,訪問數據),被形成這個域的節或頁來監督訪問權限。
管理者控制域的行爲(域中的當前節和頁,對域的訪問),不被形成這個域的節或頁來監督訪問權限。
一個程序可以是一些域的客戶,也是另外一些域的管理者,同時沒有對其它域的訪問權限。這允許對程序訪問不同存儲器資源的非常靈活的存儲器保護。表 3-4 說明了域訪問控制寄存器的位編碼方式。
(域的作用即對於每一個存儲塊如節、大頁和小頁,設置能否訪問這些存儲塊,或者訪問這些存儲塊時是否需要進行在轉換表中所設置的權限的檢查)
CP15寄存器4,保留
對該寄存器的訪問( 讀或寫) 結果無法預見。
CP15寄存器5,故障狀態寄存器
訪問:讀/ 寫
讀CP 15 寄存器5,或故障狀態寄存器(FSR),返回最後數據故障源,表示當數據中止出現時嘗試訪問的域與類型。
此外,將引起數據中止的虛擬地址寫入故障地址寄存器(CP15 寄存器6)。
寫CP 15 寄存器5,或故障狀態寄存器(FSR),設置數據寫入時FSR 值。用於調試器恢復FSR中值。
• Status[3:0]: 故障類型
說明故障類型。當數據中止出現時由MMU對狀態域編碼。狀態域譯碼由域名及與數據中止相關的MVA(存於FAR中)確定。
• Domain[7:4]: 域
說明當故障出現時訪問的域(D15 - D0)。
當寫入時,未定義位爲0,讀出時結果無法預見。
CP15寄存器6,故障地址寄存器
訪問:讀/ 寫
CP 15寄存器6,或故障地址寄存器(FAR),包含當最後故障出現時嘗試訪問的MVA 。FAR只會因數據故障而改變,不會因預取故障改變。
對FAR 的寫性能,允許調試器保存一個先前狀態。
CP15寄存器7,緩存工作寄存器
訪問: 只寫
CP15寄存器7,或緩存工作寄存器,用以管理指令緩存(ICache) 與數據緩存(DCache)。
每個緩存工作功能由pcode_2 及使用寫CP15 寄存器7 的MCR 指令的CRm 域選定。
詳細內容參照手冊。
CP15寄存器8, TLB 工作寄存器
訪問: 只讀
CP15寄存器8,或轉換後備緩衝器(TLB)工作寄存器,用於管理指令TLB與數據TLB。
使用opcode_2及寫CP15 寄存器8 的MCR 指令中的CRm域選定TLB 工作 。
TLB:Translation Lookaside Buffer. 根據功能可以譯爲快表,直譯可以翻譯爲旁路轉換緩衝,也可以把它理解成頁表緩衝.裏面存放的是一些頁表文件(虛擬地址到物理地址的轉換表).當處理器要在主內存尋址時,不是直接在內存的物理地址裏查找的,而是通過一組虛擬地址轉換到主內存的物理地址,TLB就是負責將虛擬內存地址翻譯成實際的物理內存地址,而CPU尋址時會優先在TLB中進行尋址.處理器的性能就和尋址的命中率有很大的關係.
二,爲什麼要引入TLB:
映射機制必須使一個程序能斷言某個地址在其自己的進程空間或地址空間內,並且能夠高效的將其轉換爲真實的物理地址以訪問內存.一個方法是使用一個含有整個空間內所有頁的入口(entry)的表(即頁表),每個入口包含這個頁的正確物理地址.這很明顯是個相當大的數據結構,因而不得不存放於主存之中.
由於CPU首先接到的是由程序傳來的虛擬內存地址,所以CPU必須先到物理內存中取頁表,然後對應程序傳來的虛擬頁面號,在表裏找到對應的物理頁面號,最後才能訪問實際的物理內存地址,也就是說整個過程中CPU必須訪問兩次物理內存(實際上訪問的次數更多).因此,爲了減少CPU訪問物理內存的次數,引入TLB.。通常在ARM 的實現中每個內存接口有一個TLB。
· 有一個存儲器接口的系統通常有一個唯一的TLB
· 指令和數據的內存接口分開的系統通常有分開的指令TLB 和數據TLB
當存儲器中的轉換表被改變或選中了不同的轉換表(通過寫CP15 的寄存器2),先前在TLB中的轉換表遍歷結果將不再有效。MMU 結構提供了刷新TLB 的操作。MMU 結構也允許特定的轉換表遍歷結果被鎖定在一個TLB 中,這就保證了對相關的存儲器區域的訪問絕不會導致轉換表遍歷,這也對那些把指令和數據鎖定在高速緩存中的實時代碼有相同的好處。
試圖用MRC 指令讀CP15 寄存器8 的結果不確定。當只有很少量的存儲器被重新映射時,無效的單一入口操作能被用來在一些實現中改善性能。對每個被重新映射的存儲器區域(節、小頁或大頁),無效的單一入口需要在存儲器區域的虛擬地址上執行。性能的改善來源於不用重新裝載與沒有被重新映射的存儲器區域相關的TLB 入口。
---小心------
當存儲器被重新映射時必須使與舊的映射相關的TLB 入口無效。如果不這樣,可能會進入兩個TLB 入口覆蓋虛擬地址範圍的狀態。在最好的情況下訪問這樣的覆蓋虛擬地址範圍會有不可預料的結果;在某些實現中甚至會物理損壞MMU。強烈建議在重新映射存儲器時要加倍小心使TLB 適當地失效。
------------
CP15寄存器9,緩存上鎖寄存器
訪問: 讀/ 寫
CP15寄存器9,或緩存上鎖寄存器,復位時值爲0x0。緩存上鎖寄存器允許軟件控制在ICache或DCache上的緩存線上載入填充。防止在填充時ICache 或 DCache 被驅逐,將其鎖定在緩存中。
由CP15 寄存器9 讀取返回緩存上鎖寄存器值,即所有緩存段的基地址指針。只返回[31:26],其它值不可預見。
對CP15 寄存器9 寫入更新緩存上鎖寄存器,所有緩存段基地址與當前地址指針更新。
CP15寄存器10, TLB 上鎖寄存器
訪問: 讀/ 寫
CP15寄存器10,或 TLB上鎖寄存器復位時值爲0x0。每個TLB均有一個TLSB上鎖寄存器;opcode_2值確定訪問哪個TLB寄存器:
• opcode_2 = 0x0 , D TLB 寄存器
• opcode_2 = 0x1, I TLB寄存器
轉換表遍歷的執行需要一定的時間,特別當訪問慢速的主存儲器時。在實時中斷處理程序中,當TLB 不包含中斷處理程序的轉換和/或要訪問的數據時,中斷延遲迴大量加長。
TLB 鎖定是一些ARM 存儲器系統的特性,它允許把特定的轉換表遍歷的結果裝載到TLB 中。這種方式不會被後來的轉換表遍歷的結果覆蓋。由CP15 寄存器10 設定。設 W=LOG2(TLB 入口數),如果需要的話取整(round-up),則CP15 寄存器10 的格式爲:
如果具體的實現有分開的指令和數據TLB,那麼有2 個不同的寄存器,由訪問寄存器10 的MCR 或MRC 指令中的opcode2 字段選擇:
opcode2 == 0 選擇數據TLB 鎖定寄存器
opcode2 == 1 選擇指令TLB 鎖定寄存器
如果具體的實現只有唯一的TLB,那麼只有1 個寄存器,opcode2 字段應該爲0。訪問寄存器10 的MCR 或MRC 指令中的CRm 總應該爲0。
寫寄存器10 有如下結果:
victim 字段表示下次TLB 失敗(miss)時,轉換表遍歷的結果替代哪個TLB 入口。Base 字段包含TLB 替換的策略,只使用從(base)到(TLB 入口-1)的TLB 入口,victim 應該在這個區間。
轉換表遍歷的結果在寫到TLB 入口時,若P==1 則它被保護起來,不能被寄存器8的使整個TLB 失效操作影響;若P==0 則會被那些操作給失效掉。
---注------
如果TLB 的入口不是2 的N 次方,那麼寫到大於或等於TLB 入口數的TLB 入口的base 或victim 的值將不確定。
-----------
讀寄存器10 將返回它的值。
CP15寄存器11, 12,保留
對這些寄存器的訪問( 讀或寫) 結果不可預見。
CP15寄存器13, FCSE PID寄存器
訪問: 讀/ 寫
CP15寄存器13,或快速前後切換擴展(FCSE)處理標識符(PID) 寄存器,復位時值爲0x0。
由CP15 寄存器13讀取返回FCSE PID值。
向CP15 寄存器13寫入置位FCSE PID。
FCSE PID 設置ARM9TDMI 與緩存存儲器MMU 間映射。
ARM9TDMI 地址範圍爲0 ~ 32 M字節,通過FCSE PID 轉換。
CP15寄存器14, 保留
對這些寄存器的訪問( 讀或寫) 結果不可預見。
CP15寄存器15,測試配置寄存器
CP15寄存器15,或測試配置寄存器用於測試。對該寄存器的訪問( 讀或寫) 結果不可預見。
四、設置MMU
下面是一個設置MMU進行地址重映射的一個實例
對於實際編程工作而言,主要是確定如何編寫頁表中的內容並如何確定頁表項地址。現舉例如下:
假設物理地址爲0x3000_0000~0x30ff_ffff(1M空間)的一塊連續空間需映射爲0x0000_0000~0x000f_ffff的一塊連續空間:
1.確定頁表項中的內容:把物理地址的基地址作爲頁表項的高12位(31bit~21bit),填寫訪問屬性。假設可以讀寫,可以讀緩存、寫緩衝,這樣該頁表項內容爲0x3000_C00E;
2.確定頁表基地址,填寫頁表基地址到CP15寄存器的C2中。頁表的基地址要爲64KB對齊,此處爲0x305f_c000;
3.計算出偏移地址,把內容填寫到頁表項地址中。頁表項地址=頁表基地址+(虛擬地址基地址>>18),如頁表基地址爲0x305f_c000,那麼,頁表項地址=0x305f_c000;
4.將頁表項數值寫到對應的頁表項地址中。上例中,需要向地址0x305f_c000中寫入0x3000_COOE。
下面是程序的具體實現
;init MMU
;寫MMU表到on chip sram from 0x60010000 to 0x60014000
import write_mmu_table
ldr r0,=table ;0x305f_c000
bl write_mmu_table ;
nop
nop
ldr r2,=0x55555555
mcr p15,0x0,r2,c3,c0,0 ;16個域均爲0b01,客戶模式
nop
nop
nop
nop
ldr r0,=table ;
mcr p15,0x0,r0,c2,c0,0 ;變換表基地址寫入cp15 r2
nop
nop
nop
nop
mov r2,#0x7d ;0b0111 1101,使能cache,write buffer,MMU
mcr p15,0x0,r2,c1,c0,0
nop
nop
nop
nop
nop
nop
就這些,mmu初始化完了
write_mmu_table()是c的小程序,往ram寫地址轉換的描述
void write_mmu_table(UINT32 *base)
{
UINT32 *p_table;
UINT32 description;
UINT32 i;
p_table = base;
description = 0x3000_C00E; //頁表項的值
*p_table = description;
p_table++;
description = 0x31000c10 //下面使除了上面映射地址之外,所有的虛擬地址都爲無效
//地址..bits[1:0]==0b00,所關聯的地址沒有被映射
for (i=1;i<4096;i++)
{
*p_table = description;
description = description +0x00100000;
p_table ++;
}
//return;
}