天天看點

[架構之路-47]:目标系統 - 系統軟體 - Linux OS硬體裝置驅動 - CPU記憶體管理單元MMU、DMA與IO記憶體管理單元IOMMU

目錄

​​第1章 記憶體管理單元MMU​​

​​1.1 什麼是記憶體管理單元MMU​​

​​1.2 基本原理​​

​​1.3 關鍵概念​​

​​1.4 程式的局部性原理​​

​​第2章 DMA機制​​

​​2.1 什麼是DMA​​

​​2.2 DMA的原理​​

​​2.3 基本過程​​

​​2.4 DMA的傳送方式​​

​​第3章 IOMMU​​

​​3.1 什麼是IOMMU​​

​​3.2 DMA重映射:裝置邏輯/虛拟位址與任意實體記憶體位址的分離​​

​​3.3 DMA重映射:連續虛拟位址與不連續實體位址的映射(scatter/gather機制)​​

​​3.4 DMA重映射:對虛拟化的支援​​

​​3.5 中斷重映射(可選)​​

​​它山之石:​​

第1章 記憶體管理單元MMU

1.1 什麼是記憶體管理單元MMU

MMU是Memory Management Unit的縮寫,中文名是​​記憶體管理​​單元,有時稱作分頁記憶體管理單元(英語:paged memory management unit,縮寫為PMMU)。它是一種負責處理​​中央處理器​​​(CPU)的​​記憶體​​​通路請求的​​計算機硬體​​​。它的功能包括​​虛拟位址​​​到​​實體位址​​​的轉換(即​​虛拟記憶體​​​管理)、記憶體保護、中央處理器​​高速緩存​​​的控制,在較為簡單的計算機體系結構中,負責​​總線​​​的​​仲裁​​以及存儲體切換(bank switching)。

1.2 基本原理

MMU位于​​處理器​​​核心和連接配接​​高速緩存​​​以及​​實體存儲器​​​的​​總線​​​之間。當處理器​​核心​​​取指令或者存取資料的時候,都會提供一個有效位址(effective address),或者稱為​​邏輯位址​​​、​​虛拟位址​​​。這個位址是​​可執行代碼​​​在編譯的時候由連結器生成的。不同于開發​​嵌入式處理器​​​系統的程式員,桌面型電腦的程式開發人員通常對硬體的實體配置資訊所知甚少。将​​存儲器​​​系統虛拟化,程式員就不需要了解存儲器的實體配置細節。當應用代碼需要使用存儲空間時,作業系統通過MMU為其配置設定合适的實體存儲空間。​​有效位址​​​不需要和系統的實際硬體實體位址相比對,而是通過MMU将有效位址映射成對應的​​實體位址​​,以通路指令和資料。

[架構之路-47]:目标系統 - 系統軟體 - Linux OS硬體裝置驅動 - CPU記憶體管理單元MMU、DMA與IO記憶體管理單元IOMMU

每條MMU比對規則所對應的​​存儲器​​​的大小定義為頁。頁的大小通常設定為不會對程式的性能造成顯著影響的最小的程式和代碼的長度。當暫時不使用​​實體記憶體​​​的内容時,可将其儲存到硬碟等​​外部存儲器​​​裡,将其空間用于其他程式;當再次使用這部分内容時再從外部存儲器寫回到實際實體記憶體中。通過這種方法,系統就可以提供多于實際實體記憶體容量的“​​虛拟記憶體​​”。

如果MMU定義的頁太大,那麼進行​​虛拟記憶體​​頁面替換所花費的時間就太長;

如果頁太小,就會引起過于頻繁的頁面替換。

通常最小的頁設定為4 KB。

為了加快MMU規則比對的處理過程,​​有效位址​​​和實際​​實體位址​​的對應表(頁表)通常儲存在一塊單獨的高速緩存中,稱為對應查找表(Translation Lookaside Buffer,TLB),​​TLB​​和實際實體存儲器可以同時進行并行的通路。有效位址的高位作為在​​TLB​​​進行比對查找的依據,而​​有效位址​​的低位作為頁面内的偏址。 

[架構之路-47]:目标系統 - 系統軟體 - Linux OS硬體裝置驅動 - CPU記憶體管理單元MMU、DMA與IO記憶體管理單元IOMMU

​​TLB​​​可以包含很多個表項(​​entry​​),每個表項對應一個MMU的頁。作業系統或者應用啟動代碼必須正确的初始化TLB的所有表項。

當應用程式提供的有效位址正好位于某個​​TLB​​表項制定的位址範圍内時,稱為産生了一次TLB命中;

如果這個有效位址沒有位于任何一個​​TLB​​​表項制定的位址範圍内,稱為一個TLB​​缺失​​​,或者TLB未​​命中​​​。TLB未命中往往發生在應用程式出現錯誤的時候,是以TLB未命中所引發的​​異常處理​​​可以很有效的發現和調試這類錯誤。虛拟記憶體利用TLB未命中的異常來完成頁面交換,并根據交換的内容對應的調整TLB表項的參數。通常TLB表項還會指定一些​​存儲器​​讀寫的其他參數,隻有當這些參數也和目前的存儲器讀寫的參數符合的時候,才能産生TLB命中。

1.3 關鍵概念

  • 位址範圍

任何時候,計算機上都存在一個程式能夠産生的連續的位址集合,我們稱之為位址範圍。

位址範圍的大小由CPU的位數決定,例如一個32位的CPU,它的位址範圍是0~0xFFFFFFFF (4G),而對于一個64位的CPU,它的位址範圍為0~0xFFFFFFFFFFFFFFFF (16E)。

  • ​​虛拟位址​​

這個範圍就是我們的程式能夠産生的位址範圍,我們把這個位址範圍稱為​​虛拟位址​​空間,該空間中的某一個位址我們稱之為虛拟位址。

  • ​​實體位址​​

與虛拟位址空間和虛拟位址相對應的則是實體位址空間和實體位址,大多數時候我們的系統所具備的實體位址空間隻是虛拟位址空間的一個子集。

這裡舉一個最簡單的例子直覺地說明這兩者,對于一台記憶體為256M的32bit x86主機來說,

它的虛拟位址空間範圍是0~0xFFFFFFFF(4G),

而實體位址空間範圍是0x00000000 ~ 0x0FFFFFFF(256M)。 

  • 位址映射

在沒有使用​​虛拟存儲器​​​的機器上,​​程式位址​​被直接送到記憶體總線上,使具有相同位址的實體存儲器被讀寫;

而在使用了虛拟存儲器的情況下,虛拟位址不是被直接送到​​記憶體位址​​​總線上,而是送到​​存儲器管理​​單元MMU,把虛拟位址映射為實體位址。

[架構之路-47]:目标系統 - 系統軟體 - Linux OS硬體裝置驅動 - CPU記憶體管理單元MMU、DMA與IO記憶體管理單元IOMMU
  • ​​分頁​​機制

大多數使用虛拟存儲器的系統都使用一種稱為​​分頁​​(paging)機制。

虛拟位址空間劃分成稱為頁(page)的機關,而相應的​​實體位址​​空間也被進行劃分,機關是頁幀(frame),頁和頁幀的大小必須相同。

在這個例子中我們有一台可以生成32位位址的機器,它的​​虛拟位址​​範圍從0~0xFFFFFFFF(4G),而這台機器隻有256M的實體位址,是以他可以運作4G位址空間大小的程式,但該程式不能一次性調入記憶體運作。這台機器必須有一個達到可以存放4G程式的外部​​存儲器​​​(例如磁盤或是FLASH),以保證程式片段在需要時可以被調用。在這個例子中,頁的大小為4K,頁幀大小與頁相同——這點是必須保證的,因為記憶體和外圍​​存儲器​​之間的傳輸總是以頁為機關的。對應4G的虛拟位址和256M的實體存儲器,他們分别包含了1M個頁和64K個頁幀。

很顯然,可執行程式的位址空間可以大于實體記憶體RAM的位址空間範圍。

而程式有必須調入到高速的實體記憶體中才能高效執行。這就需要利用到頁表的命中、不命中、替換等機制。而頁表機制之是以能夠工作,得益于頁表程式的程式的局部性原理。

1.4 程式的局部性原理

頁表存在的基本原理是:程式的局部性原理

程式的局部性原理是指程式在執行時呈現出局部性規律,即在一段時間内,整個程式的執行僅限于程式中的某一部分。相應地,執行所通路的存儲空間也局限于某個記憶體區域。

局部性原理又表現為:時間局部性和空間局部性。

時間局部性是指如果程式中的某條指令一旦執行,則不久之後該指令可能再次被執行; 如果某資料被通路,則不久之後該資料可能再次被通路。(得益于程式三大基本結構之循環執行結構)

空間局部性是指一旦程式通路了某個存儲單元,則不久之後,其附近的存儲單元也将被通路。(得益于程式三大基本結構之順序執行結構)

另外,根據程式的局部性理論,Denning提出了工作集理論。所謂工作集是指程序運作時被頻繁通路的頁面集合。顯然我們知道隻要使程式的工作集全部集中在記憶體中,就可以大大減少程序的缺頁次數;否則會使程序在運作過程中頻繁出現缺頁中斷,進而出現頻繁的頁面調入/調出現象,造成系統性能的下降,甚至出現“抖動”。

劃分工作集可以按定長時間或定長頁面兩種方法進行劃分。當颠簸現象發生時,說明系統的負荷過大,通常采用處理器均衡排程。另一種是控制缺頁率,當缺頁率達到上限時,則增加記憶體配置設定量;當缺頁率達到下限時,就減少記憶體的配置設定量。

第2章 DMA機制

IOMMU主要用來解決裝置DMA的位址映射,是以在了解IOMMU之前,有必要先了解一下DMA機制。

2.1 什麼是DMA

DMA(Direct Memory Access,直接​​存儲器​​​通路) 是所有現代​​電腦​​​的重要特色,它允許不同速度的硬體裝置來溝通,而不需要依賴于​​ CPU ​​​的大量中斷負載。否則,CPU 需要從來源把每一片段的資料複制到​​暫存器​​,然後把它們再次寫回到新的地方。在這個時間中,CPU 對于其他的工作來說就無法使用。

2.2 DMA的原理

 DMA 傳輸将資料從一個位址空間複制到另外一個位址空間。當CPU 初始化這個傳輸動作,傳輸動作本身是由 DMA 控制器來實行和完成。典型的例子就是移動一個外部記憶體的區塊到晶片内部更快的記憶體區。像是這樣的操作并沒有讓​​處理器​​工作拖延,反而可以被重新排程去處理其他的工作。DMA 傳輸對于高效能 嵌入式系統算法和網絡是很重要的。

[架構之路-47]:目标系統 - 系統軟體 - Linux OS硬體裝置驅動 - CPU記憶體管理單元MMU、DMA與IO記憶體管理單元IOMMU

在實作DMA傳輸時,是由​​DMA控制器​​直接掌管總線,是以,存在着一個總線控制權轉移問題。即DMA傳輸前,CPU要把總線控制權交給DMA控制器,而在結束DMA傳輸後,DMA控制器應立即把總線控制權再交回給CPU。一個完整的DMA傳輸過程必須經過DMA請求、DMA響應、DMA傳輸、DMA結束4個步驟。在DMA控制總線的過程中,CPU隻是暫停總線的範圍,并沒有進行程序上下文的切換。

2.3 基本過程

(1)請求:

CPU對DMA控制器初始化,并向​​I/O接口​​發出操作指令,I/O接口提出DMA請求。

(2)響應

DMA控制器對DMA請求判别優先級及屏蔽,向總線裁決邏輯提出總線請求。當CPU執行完目前總線周期即可釋放總線控制權。此時,總線裁決邏輯輸出總線應答,表示DMA已經響應,通過DMA控制器通知I/O接口開始DMA傳輸。

(3)傳輸

DMA控制器獲得總線控制權後,CPU即刻挂起或隻執行内部操作,由DMA控制器輸出讀寫指令,直接控制RAM與I/O接口進行DMA傳輸。

在DMA控制器的控制下,在存儲器和外部裝置之間直接進行資料傳送,在傳送過程中不需要​​中央處理器​​的參與。開始時需提供要傳送的資料的起始位置和資料長度。

(4)結束

當完成規定的成批資料傳送後,DMA控制器即釋放總線控制權,并向I/O接口發出結束信号。

當I/O接口收到結束信号後,一方面停 止​​I/O裝置​​的工作,另一方面向CPU提出中斷請求,使CPU從不介入的狀态解脫,并執行一段檢查本次DMA傳輸操作正确性的代碼。最後,帶着本次操作結果及狀态繼續執行原來的程式。

由此可見,DMA傳輸方式無需CPU直接控制傳輸,也沒有中斷處理方式那樣保留現場和恢複現場的過程,通過硬體為RAM與I/O裝置開辟一條直接傳送資料的通路,使CPU的效率大為提高。

2.4 DMA的傳送方式

DMA技術的出現,使得外圍裝置可以通過DMA控制器直接通路記憶體。與此同時,CPU可以繼續執行程式。

那麼DMA控制器與CPU怎樣分時使用記憶體呢?通常采用以下三種方法:

(1)停止CPU通路記憶體

當外圍裝置要求傳送一批資料時,由DMA控制器發一個停止信号給CPU,要求CPU放棄對位址總線、資料總線和有關控制總線的使用權。DMA控制器獲得總線控制權以後,開始進行資料傳送。在一批資料傳送完畢後,DMA控制器通知CPU可以使用記憶體,并把總線控制權交還給CPU。圖(a)是這種傳送方式的時間圖。很顯然,在這種DMA傳送過程中,CPU基本處于不工作狀态或者說保持狀态。

優點: 控制簡單,它适用于​​資料傳輸率​​很高的裝置進行成組傳送。

缺點: 在DMA控制器通路記憶體階段,記憶體的效能沒有充分發揮,相當一部分記憶體工作周期是空閑的。這是因為,外圍裝置傳送兩個資料之間的間隔一般總是大于記憶體存儲周期,即使高速I/O裝置也是如此。例如,軟碟讀出一個8位二進制數大約需要32us,而半導體記憶體的存儲周期小于0.5us,是以許多空閑的存儲周期不能被CPU利用。

[架構之路-47]:目标系統 - 系統軟體 - Linux OS硬體裝置驅動 - CPU記憶體管理單元MMU、DMA與IO記憶體管理單元IOMMU

(2)周期挪用(CPU并沒有停止不通路記憶體的指令)

當I/O裝置沒有DMA請求時,CPU按程式要求通路記憶體;

一旦I/O裝置有DMA請求,則由I/O裝置挪用一個或幾個記憶體周期。

這種傳送方式的時間圖如下圖(b):

I/O裝置要求DMA傳送時可能遇到兩種情況:

(1) 此時CPU不需要訪内,如CPU正在執行乘法指令。由于乘法指令執行時間較長,此時I/O訪内與CPU訪内沒有沖突,即I/O裝置挪用一二個記憶體周期對CPU執行程式沒有任何影響。

(2) I/O裝置要求訪内時CPU也要求訪内,這就産生了訪内沖突,在這種情況下I/O裝置訪内優先,因為I/O訪内有時間要求,前一個I/O資料必須在下一個通路請求到來之前存取完畢。顯然,在這種情況下I/O 裝置挪用一二個記憶體周期,意味着CPU延緩了對指令的執行,或者更明确地說,在CPU執行訪内指令的過程中插入DMA請求,挪用了一二個記憶體周期。 與停止CPU訪内的DMA方法比較,周期挪用的方法既實作了I/O傳送,又較好地發揮了記憶體和CPU的效率,是一種廣泛采用的方法。但是I/O裝置每一次周期挪用都有申請總線控制權、建立線控制權和歸還總線控制權的過程,是以傳送一個字對記憶體來說要占用一個周期,但對DMA控制器來說一般要2—5個記憶體周期(視邏輯線路的延遲而定)。是以,周期挪用的方法适用于I/O裝置讀寫周期大于記憶體存儲周期的情況。

[架構之路-47]:目标系統 - 系統軟體 - Linux OS硬體裝置驅動 - CPU記憶體管理單元MMU、DMA與IO記憶體管理單元IOMMU

(3)DMA與CPU交替通路記憶體

如果CPU的工作周期比記憶體存取周期長很多,此時采用交替訪内的方法可以使DMA傳送和CPU同時發揮最高的效率。

這種傳送方式的時間圖如下:

[架構之路-47]:目标系統 - 系統軟體 - Linux OS硬體裝置驅動 - CPU記憶體管理單元MMU、DMA與IO記憶體管理單元IOMMU

此圖是DMA與CPU交替訪内的詳細時間圖.假設CPU工作周期為1.2us,記憶體存取周期小于0.6us,那麼一個CPU周期可分為C1和C2兩個分周期,其中C1專供DMA控制器訪内,C2專供CPU訪内。

這種方式不需要總線使用權的申請、建立和歸還過程,總線使用權是通過C1和C2分時制的。CPU和DMA控制器各自有自己的訪内​​位址寄存器​​​、資料寄存器和讀/寫信号等控制寄存器。在C1周期中,如果DMA控制器有訪内請求,可将位址、資料等信号送到總線上。在C2周期中,如CPU有訪内請求,同樣傳送位址、資料等信号。事實上,對于總線,這是用C1,C2控制的一個多路​​轉換器​​,這種總線控制權的轉移幾乎不需要什麼時間,是以對DMA傳送來講效率是很高的。

這種傳送方式又稱為“透明的DMA”方式,其來由是這種DMA傳送對CPU來說,如同透明的玻璃一般,沒有任何感覺或影響。在透明的​​DMA方式​​下工作,CPU既不停止主程式的運作,也不進入等待狀态,是一種高效率的工作方式。當然,相應的硬體邏輯也就更加複雜。

第3章 IOMMU

3.1 什麼是IOMMU

IOMMU:input/output memory management unit。Device的IOMMU類似于CPU的MMU。

在計算機領域,IOMMU(Input/Output Memory Management Unit)是一個記憶體管理單元(Memory Management Unit),它的作用是連接配接DMA-capable I/O總線(Direct Memory Access-capable I/O Bus)和主存(main memory)總線。

傳統的記憶體管理單元會把CPU通路的虛拟位址轉化成實際的實體位址。

而IOMMU則是把裝置(device)通路的虛拟位址轉化成實體位址。

為了防止裝置錯誤地通路記憶體,有些IOMMU還提供了通路記憶體保護機制。

[架構之路-47]:目标系統 - 系統軟體 - Linux OS硬體裝置驅動 - CPU記憶體管理單元MMU、DMA與IO記憶體管理單元IOMMU

CPU程式(核心或使用者空間):通過MMU,實作CPU的邏輯位址到實體記憶體位址的映射。

其他硬體裝置,如網口:通過IOMMU,實作外設的邏輯位址到實體記憶體位址的映射。

IOMMU允許系統裝置在​​虛拟記憶體​​中進行尋址,也就是将虛拟記憶體位址映射為實體記憶體位址,讓實體硬體裝置和裝置驅動程式可以在虛拟的記憶體環境中工作,這樣可以幫助系統擴充記憶體容量,提升性能。

IOMMU實作兩大功能:

(1)DMA Remapping =》 DMA重映射 => 裝置邏輯/虛拟位址與任意實體記憶體位址的分離

(2)Interrupt Remapping =》 中斷重映射

(3)虛拟機的支援

3.2 DMA重映射:裝置邏輯/虛拟位址與任意實體記憶體位址的分離

硬體裝置通過DMA,實作裝置邏輯位址到任意實體記憶體位址之間傳送。

要在​​64位​​記憶體系統上支援32位硬體裝置,比如說網卡,即網卡裝置隻能通路32位的實體位址空間。

如果沒有IOMMU,就需要在​​實體記憶體​​底端,也就是32位裝置能夠通路到的地方設定一個叫做"bounce buffers"的東西,如果裝置要通路高端記憶體,作業系統就要在高端記憶體和"bounce buffers"之間做一個拷貝。帶來的性能影響顯而易見。

如果有了IOMMU,這個問題就迎刃而解了。在​​裝置驅動​​做DMA綁定的時候,系統傳回給驅動的不再是實體位址,而是​​核心空間​​的某個位址(有的書上叫做總線位址),傳輸的時候,這個核心空間位址會經由IOMMU單元,IOMMU将這個邏輯位址轉換為實體位址。

[架構之路-47]:目标系統 - 系統軟體 - Linux OS硬體裝置驅動 - CPU記憶體管理單元MMU、DMA與IO記憶體管理單元IOMMU

3.3 DMA重映射:連續虛拟位址與不連續實體位址的映射(scatter/gather機制)

scatter/gather并不會帶來性能上的好處,但是會簡化​​裝置驅動程式​​。

例如​​網卡驅動​​在發送包的時候,DMA綁定後,系統可能會傳回給裝置驅動多個不連續的實體位址,Solaris叫做cookie。這樣的話,每一個cookie都需要占用一個發送描述符。如果系統支援IOMMU的話,系統隻會傳回給​​裝置驅動​​一個cookie。當然了有專家提醒,因為這個原因,如果裝置驅動是在沒有IOMMU的情況下開發的,在支援IOMMU的系統上是沒有問題的。但反之不然。

3.4 DMA重映射:對虛拟化的支援

IOMMU除了上述功能外還加入了對虛拟化的支援。

[架構之路-47]:目标系統 - 系統軟體 - Linux OS硬體裝置驅動 - CPU記憶體管理單元MMU、DMA與IO記憶體管理單元IOMMU

IOMMU允許系統硬體裝置在​​虛拟記憶體​​中進行尋址,也就是将虛拟記憶體位址映射為實體記憶體位址,讓實體裝置可以在虛拟的記憶體環境中工作,這樣可以幫助系統擴充記憶體容量,提升性能。

IOMMU的一個重要用途是在​​虛拟化​​技術(virtualization)

在虛拟化環境中,存在多個虛拟機通路同一個實體機的同一個實體網卡的情形。

虛拟機上運作的作業系統(guest OS)通常不知道它所通路的host-physical記憶體位址。

如果要進行DMA操作,就有可能破壞記憶體,因為實際的硬體(hardware)不知道guest-physical和host-physical記憶體位址之間的映射關系。IOMMU根據guest-physical和host-physical記憶體位址之間的轉換表(translation table),re-mapping硬體通路的位址,就可以解決這個問題。 

它山之石:

繼續閱讀