深入淺出MIPS 二 MIPS的記憶體對映 .
二 MIPS的記憶體對映
在32位MIPS體系結構下,最多可定址4GB地址空間。這4GB空間的分配是怎樣的呢?讓我們看下面這張圖:
+----------------------------------------------+
| | 0xFFFFFFFF
| |
| |
| Kernel Space Mapped Cached |
| |
| |
0xC0000000 | |
+----------------------------------------------+
| | 0xBFFFFFFF
| Kernel Space Unmapped Cached |
| |
0xA0000000 +----------------------------------------------+
| | 0x9FFFFFFF
| Kernel Space Unmapped Uncached |
| |
0x80000000 +----------------------------------------------+
| | 0x7FFFFFFF
| |
| |
| |
| User Space |
| |
| |
| |
| |
| |
0x00000000 +----------------------------------------------+
Figure 2-1 MIPS Logical Addressing Space
上圖是MIPS處理器的邏輯定址空間分佈圖。我們看到,2GB以下的地址空間,也就是從0x00000000到0x7FFFFFFF的這一段空間,為User Space,可以在User Mode下訪問,當然,在Kernel Mode下也是可以訪問的。程式在訪問User Space的記憶體時,會通過MMU的TLB,對映到實際的實體地址上。也就是說,這一段邏輯地址空間和實體地址空間的對應關係,是由MMU中的TLB表項決定的。
從0x80000000到0xFFFFFFFF的一段為Kernel Space,僅限於Kernel Mode訪問。如果在User Mode下試圖訪問這一段記憶體,將會引發系統的一個Exception。MIPS的 Kernel Space又可以劃分為三部分。首先是通過MMU對映到實體地址的1GB空間,地址範圍從0xC0000000到0xFFFFFFFF。這1GB空間可以用來訪問實際的DRAM記憶體
MIPS的Kernel Space中,還有兩段特殊的地址空間,分別是從0x80000000到0x9FFFFFFF的Kernel Space Unmapped Uncached和0xA0000000到0xBFFFFFFF的Kernel Space Unmapped Cached。之所以說它們特殊,是因為這兩段邏輯地址到實體地址的對映關係是硬體直接確定的,不通過MMU,而且兩段實際上是重疊的,均對應0x00000000到0x20000000的實體地址。那麼,為什麼一段同樣的實體地址有兩個邏輯地址對應呢?它們的區別又在哪裡呢?
原來,這是MIPS的設計特色之一。軟體在訪問Kernel Space Unmapped Uncached這段地址空間的時候,不經過MIPS的Cache。這樣,雖然速度會比較慢,但是,對於硬體I/O暫存器來說,就不存在所謂的Cache一致性問題。Cache一致性問題,是指硬體將某個地址的內容跳過軟體而改變了,Cache中的內容尚未同步。這樣,如果軟體讀取該地址,有可能從Cache中獲取到錯誤的內容。將硬體I/O暫存器設定在這段地址空間,就可以避免Cache一致性帶來的問
另一段特殊的地址Kernel Space Unapped Cached,與前者類似,直接對映到0x00000000到0x20000000,與Kernel Space Unmapped Uncached重疊。因為通過Cache,這段地址空間的訪問速度比前者為快。一般地,這段記憶體空間用於核心程式碼段,或者核心中的堆疊。
顯然地,當工程師們換算Kernel Space中的這兩段的實體地址和邏輯地址時,只需要改變地址的高3bit就可以了。
那麼,什麼時候需要使用實體地址,什麼時候需要使用邏輯地址呢?我們知道,邏輯地址是程式中訪問的記憶體地址,譬如,下面的這條指令:
lw a0, 128(t2)
這條指令的內容是從t2暫存器內的地址 + 偏移128位元組處,讀取一個word (4Byte)到暫存器a0內。如果t2的值為0x88200100,則最終訪問的實體地址為0x88200180。
而實體地址,從工程上可以理解為,將邏輯分析儀連線到記憶體匯流排(Memory Bus)上,邏輯分析儀指示的地址,就是實體地址。假如,在上一個例子中,我們把邏輯分析儀接到處理器的前端記憶體匯流排,我們就可以看到,執行該指令時,系統訪問的實體地址為0x08200180。實體地址和邏輯地址的換算,不僅限於電子工程師在設計硬體線路時需要。在核心工程師編寫支援DMA的外部裝置驅動時,需要將向作業系統申請到的資料緩衝區地址(當然,這是一個邏輯地址)轉換為實體地址,並“告訴”相關外設。這樣,外設就可以在收到資料後,使用DMA模式儲存在系統的主存中,並向系統發起一個IRQ。作業系統在IRQ的handler中,從外設的相應IO暫存器讀取到這段記憶體的地址(當然,是實體地址)並轉換為邏輯地址並處理之。這個過程中,如果沒有正確使用和分辨實體地址和邏輯地址,驅動程式便會導致核心的一個panic錯誤。
實體地址到邏輯地址的對映關係是由什麼決定的呢?除了上面提到的兩段Unmapped的地址空間,其餘都是由TLB確定的,由MMU來執行。這是後話。