MMU與CACHE詳解_第1頁
MMU與CACHE詳解_第2頁
MMU與CACHE詳解_第3頁
MMU與CACHE詳解_第4頁
MMU與CACHE詳解_第5頁
已閱讀5頁,還剩21頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、ARM920T的MMU與Cache目錄    虛擬地址和物理地址的概念     虛擬內存管理     ARM920T的CP15協處理器      MMU      Cache      操作MMU和Cache的內核啟動代碼      參考資料 索引虛擬地址和物理地址的概念    CPU通過

2、地址來訪問內存中的單元,地址有虛擬地址和物理地址之分,如果CPU沒有MMU(Memory Management Unit,內存管理單元),或者有MMU但沒有啟用,CPU核在取指令或訪問內存時發出的地址將直接傳到CPU芯片的外部地址引腳上,直接被內存芯片(以下稱為物理內存,以便與虛擬內存區分)接收,這稱為物理地址(Physical Address,以下簡稱PA),如下圖所示。圖 1. 物理地址示意圖     如果CPU啟用了MMU,CPU核發出的地址將被MMU截獲,從CPU到MMU的地址稱為虛擬地址(Virtual Address,以下簡稱VA),而MMU

3、將這個地址翻譯成另一個地址發到CPU芯片的外部地址引腳上,也就是將虛擬地址映射成物理地址,如下圖所示1。圖 2. 虛擬地址示意圖     MMU將虛擬地址映射到物理地址是以頁(Page)為單位的,對于32位CPU通常一頁為4K。例如,虛擬地址0xb700 10000xb700 1fff是一個頁,可能被MMU映射到物理地址0x20000x2fff,物理內存中的一個物理頁面也稱為一個頁框(Page Frame)。虛擬內存管理現代操作系統充分利用MMU提供的VA到PA的映射機制來做內存管理,以下稱為虛擬內存管理(Virtual Memory Managemen

4、t)。首先看下面的例子:   例 1. 進程的地址空間   這是bash進程的虛擬地址空間,32位CPU的虛擬地址空間是4GB,也就是0x0000 0000-0xffff ffff,該進程占用的地址范圍近似為0x0000 0000-0xbfff ffff,地址范圍0xc000 0000-0xffff ffff由內核占用,用戶進程不允許訪問。在這個bash進程的地址空間中,從0x0804 8000開始的668K的權限為r-x-,表示代碼段,從0x080e f000開始的24K的權限是rw-,表示數據段,從0x080f 5000開始的2056K的權限也是rw

5、-,但是沒有對應任何磁盤文件,而是用 anon (anonymous,匿名)來表示,這是堆所占的空間,從0xb7c6 d000開始是共享庫和資源文件的映射空間,每個共享庫也分為代碼段和數據段,用不同的權限表示,可以看到,從堆空間到下面的共享庫映射空間之間有很大的地址空洞,最末從0xbfad 4000開始的84K是棧空間。   為什么需要虛擬內存管理呢?可以從以下幾個方面來理解。   第一,讓每個進程有獨立的地址空間是引入虛擬內存管理的最主要目的。所謂獨立的地址空間是指,不同進程中的同一個VA被MMU映射到不同的PA,并且在某一個進程中訪問任何地址都不可能

6、訪問到另外一個進程的數據,這樣使得任何一個進程由于程序BUG或惡意代碼所導致的非法內存訪問都不會意外改寫其它進程的數據,不會影響其它進程的運行,從而保證了整個系統的穩定性。另一方面,每個進程都認為自己獨占4GB的地址空間,編寫程序會比較方便,不必為每個進程分配一個地址范圍,而是每個進程都可以使用一個完整的地址空間中的任何地址。   我們繼續用上面的例子來理解,再打開一個shell窗口,用pmap命令看一下這個新的bash進程的地址空間,可以發現和剛才的地址空間布局差不多:   該進程也占用了0x0000 0000-0xbfff ffff的地址空間,代碼段

7、也是從0x0804 8000開始的668K,數據段也是從0x080e f000開始的24K,共享庫的內存布局也差不多。這個進程和剛才的例子是同一個系統中同時運行著的兩個進程,它們都認為自己占有0x0000 0000-0xbfff ffff的地址空間,并且它們的數據段的地址范圍是重合的,但是兩個進程各自干各自的事情,顯然數據段中的數據是不同的,正是因為不同進程中的同一個VA被映射到了不同的PA,所以兩個進程的數據段其實是在不同的物理地址上,如下圖所示。圖 4. 進程地址空間是獨立的    從圖中還可以看到,兩個進程都是bash進程,代碼段是一樣的,并且代碼段是只讀的

8、,不會被改寫,因此操作系統會安排兩個進程的代碼段共享相同的物理內存。由于每個進程都有自己的一套VA到PA的映射表,整個地址空間中的任何VA都在每個進程自己的映射表中查找相應的物理地址,因此不可能訪問到其它進程的地址,也就沒有可能意外改寫其它進程的數據。    第二,引入VA到PA的映射也會給分配和釋放內存帶來方便,物理上不連續的空間可以映射為邏輯上連續的虛擬地址空間。比如要malloc一塊很大的內存空間,而物理內存雖然有足夠的空閑內存,卻沒有足夠大的連續空閑內存,這時就可以分配多個不連續的物理頁面,而映射為連續的虛擬地址范圍。如下圖所示。圖 5. 不連續的PA可以

9、映射為連續的VA    第三,一個系統如果同時運行著很多進程,為各進程分配的內存之和可能會大于實際可用的物理內存,虛擬內存管理使得這種情況下各進程仍然能夠正常運行。因為各進程分配的只不過是虛擬內存的頁,這個頁的內容可以映射到物理內存的頁框,也可以臨時保存到磁盤上而不占用物理內存的頁框,磁盤上這一部分稱為交換設備(Swap Device),可能是一個磁盤分區,也可能是一個磁盤文件。當物理內存不夠時將物理內存中不常用的頁框臨時保存到磁盤上,而當用到這些頁框時再從磁盤加載回內存,這稱為換頁(Paging)因此:     系統中可分配的內存總

10、量 = 物理內存的大小 + 交換設備的大小    如下圖所示。第一張圖是換出(Page out),將物理頁面的內容保存到磁盤,并解除地址映射,釋放物理頁面。第二張圖是換入(Page in),從空閑的物理頁面中分配一個,將磁盤暫存的頁面加載回內存,并建立地址映射。圖 6. 換頁    第四,虛擬內存管理可以控制物理頁面的訪問權限。物理內存本身是不限制訪問的,任何地址都可以讀寫,而操作系統要求實現各種不同的訪問權限,在先前的例子中我們已經看到,代碼段要求是rx的,數據段要求是rw的,用戶進程不能訪問屬于內核的地址空間,這些都是操作系統和M

11、MU配合實現的。    MMU中還實現了一種訪問限制是關于Cache的。Cache(高速緩存)是CPU內的一小塊高速RAM,用來緩存最近訪問過的內存數據,CPU訪問Cache的速度是訪問內存速度的數十倍,所以有效地利用Cache可以大大提高計算機的整體性能。CPU核要訪問數據時首先發出VA,Cache利用VA查找相應的數據有沒有被緩存2,如果有就通知CPU核,如果是讀操作就直接將Cache中的數據傳給CPU核中的寄存器,如果是寫操作就直接改寫Cache中的數據,而不需要訪問物理內存。但是,有些VA所對應的PA并不是物理內存中的地址而是設備寄存器的地址,對這些寄存器

12、進行讀寫并不是為了保存數據,而是對設備做特殊操作,這種VA通常是不允許緩存的,因為如果緩存了,對VA的讀寫將只在Cache中起作用,而不會傳到設備寄存器對設備進行操作。以串口的收發寄存器為例,如果收發寄存器地址被緩存了會出現什么問題呢?如下圖所示。    如果發送寄存器的地址被緩存起來,CPU核往發送寄存器的地址做寫操作都寫到Cache中去了,發送寄存器并沒有及時得到數據,也就不能及時發送,此外,CPU核先后發出的1、2、3三個數據都會寫到Cache中的同一個地址,最后Cache中只保存了第3個數據,如果這時Cache的數據寫回到發送寄存器去,只能把第3個數據發送

13、出去,前兩個數據就丟失了。與此類似,如果接收寄存器的地址被緩存起來,CPU核在讀第1個數據時,Cache會從接收寄存器讀進來緩存,然而接收寄存器后面收到2、3兩個數據Cache并不知道,因為Cache把接收寄存器當作內存,并且相信內存中的數據是不會自己變的,所以以后每次CPU核讀接收寄存器時,Cache都提供給CPU核第1個數據。ARM920T的CP15協處理器    ARM920T的MMU和Cache都集成在CP15協處理器中,MMU和Cache的聯系非常密切,本節首先從總體上介紹MMU、Cache和CPU核是如何協同工作的,后面兩節分別講解MMU和Cache的

14、細節。三星公司的S3C2410是一種很常見的采用ARM920T的芯片,涉及到具體的芯片時我們以S3C2410為例。   以下是CP15協處理器的寄存器列表(摘自S3C2410用戶手冊),和CPU核的r0到r15寄存器一樣,協處理器寄存器也是用0到15來編號,在指令中用4個bit來表示寄存器編號,有些協處理器寄存器有影子寄存器,這種情況下對同一個編號的寄存器使用不同的選項讀或者寫實際上訪問的是不同的寄存器,后文用到某個寄存器時會詳細說明它的功能。表 1. CP15協處理器的寄存器列表    對CP15協處理器的操作使用mcr和mrc兩條

15、協處理器指令,這兩條指令的記法是從后往前看:mcr是把r(CPU核寄存器)中的數據傳送到c(協處理器寄存器)中,mrc則是把c(協處理器寄存器)中的數據傳送到r(CPU核寄存器)中。對CP15協處理器的所有操作都是通過CPU核寄存器和CP15寄存器之間交換數據來完成的。下圖是協處理器的指令格式(摘自S3C2410用戶手冊)。圖 8. 協處理器指令格式    和其它ARM指令一樣,Cond是條件碼,bit 20是L位,表示該指令是讀還是寫,如果L=1就表示Load,從外面讀到CPU核中,也就是mrc指令,如果L=0就表示Store,也就是mcr指令。11:8這四個位

16、是協處理器編號,CP15的編號是15,因此是4個1。CRn是CP15寄存器編號,Rd是CPU核寄存器編號,各占4個位。對于CP15協處理器,規定opcode1應該為0,opcode2和CRm是指令的選項,具體含義取決于不同的寄存器。    雖然這里介紹了協處理器的寄存器編號和相關指令,但讀者只需了解對協處理器是這樣進行操作的就可以了,我們的重點是講解MMU和Cache的基本概念,具體各種操作的指令該怎么寫可以參考S3C2410用戶手冊。   MMU是如何把VA映射成PA的呢?從圖 4 “進程地址空間是獨立的”來看,好像是有一張VA轉PA的表,給

17、一個VA查表就可以查到PA,實際上并不是這么簡單,通常要有一個多級的查表過程,對于ARM體系結構是兩級查表,對于一些64位體系結構則需要更多級。看下面的圖示。圖 9. Translation Table Walk    首先將32位的VA3分成三段,前兩段31:20和19:12作為兩次查表的索引,第三段11:0作為頁內的偏移。查表的步驟如下:    1 CP15協處理器的TTB寄存器(看看表 1 “CP15協處理器的寄存器列表”中這是第幾個寄存器?C2)中保存著第一級頁表(Translation Table)的基地址,這個基地址指的是

18、PA,也就是說頁表是直接按這個地址存在物理內存中的。    2 以TTB中的內容為基地址,以VA31:20為索引在表中查出一項(想一下這個表中一共有多少項?4096項),這個表項中保存著第二級頁表(Coarse Page Table)的基地址,同樣是物理地址,也就是說第二級頁表也是直接按這個地址存在物理內存中的。    3 以VA19:12為索引在第二級頁表中查出一項(想一下這個表中一共有多少項?256項),這個表項中就保存著物理頁面的基地址,先前我們說虛擬內存管理是以頁為單位的,一個虛擬內存的頁映射到一個物理內存的頁框,從這里就可以

19、得到印證,因為查表是以頁為單位來查的。    4 有了物理頁面的基地址之后(兩級總共4096+4096*256=4K+1M個表項?),加上VA11:0這個偏移量就可以取出相應地址上的數據(想一下一個頁是多少字節?4K)。   這個過程稱為Translation Table Walk,Walk這個詞用得非常形象。從TTB走到一級頁表,又走到二級頁表,又走到物理頁面,一次尋址其實是三次訪問物理內存。注意這個“走”的過程完全是硬件做的,每次CPU尋址時MMU就自動完成以上四步,不需要編寫指令指示MMU去做,前提是操作系統要維護頁表項的正確性,每次分配

20、內存時填寫相應的頁表項,每次釋放內存時清除相應的頁表項,在必要的時候分配或釋放整個頁表。    有了以上基本概念,我們來看CPU訪問內存時的硬件操作順序(摘自ARM參考手冊)。圖 10. CPU訪問內存時的硬件操作順序    我們以CPU讀內存為例解釋一下圖中的步驟,各步驟在圖中有對應的標號。    1 CPU核(圖中的“ARM”框)發出VA請求讀數據,TLB(Translation Lookaside Buffer)接收到該地址。TLB是MMU中的一塊高速緩存(也是一種Cache),它緩存最近查找過的V

21、A對應的頁表項,如果TLB里緩存了當前VA的頁表項就不必做Translation Table Walk了,否則去物理內存中讀出頁表項保存在TLB中,TLB緩存可以減少訪問物理內存的次數。   2 頁表項中不僅保存著物理頁面的基地址,還保存著權限位和是否允許Cache的標志。MMU首先檢查權限位,如果沒有訪問權限,就引發一個異常給CPU核。然后檢查是否允許Cache,如果允許Cache就啟用Cache和CPU核互操作,圖中的“C, B bits”可以理解為直寫和回寫線,后面再詳細解釋這兩個位的作用。   3 如果不允許Cache,則直接發出PA從物理內存中

22、讀取數據到CPU核。   4 如果允許Cache,則以VA為索引到Cache中查找是否緩存了要讀取的數據,如果Cache中已經緩存了該數據(稱為Cache Hit)則直接返回給CPU核,如果Cache中沒有緩存該數據(稱為Cache Miss),則發出PA從物理內存中讀取數據并緩存到Cache中,同時返回給CPU核。然而Cache并不是只取CPU核所要的數據,而是把相鄰的數據都取上來緩存,這稱為一個Cache Line。ARM920T的Cache Line是32字節,例如CPU核要讀取地址0x134-0x137的4字節數據,Cache會把地址0x120-0x13f

23、(對齊到32字節地址邊界)的32字節都取上來緩存。    MMU     我們已經簡單了解了一下查頁表的過程,實際上ARM920T支持多種尺寸規格的頁表,圖 9 “Translation Table Walk”所示的只是其中一種情況。下圖示意了所有可能的情況(本節的圖表均摘自S3C2410用戶手冊)。 圖 11. 查頁表的過程     回顧一下查表的過程,首先從CP15的TTB寄存器找到一級頁表的基地址,再把VA31:20(共4096項)作為索引從表中找出一項,這個表項稱為一級頁描述符(Level 1 D

24、escriptor),一個這樣的表項占4個字節,可以是以下四種格式之一: 圖 12. 一級頁描述符   如果描述符的最低兩位是00,屬于Fault格式,表示該范圍的VA沒有映射到PA。如果描述符的最低兩位是10,屬于Section格式,這種格式沒有二級頁表而是直接映射到物理頁面,一個Section是1M的大頁面,描述符中31:20位就是這個頁面的基地址,基地址的19:0低位全為0,對齊到1M地址邊界,描述符中的Domain和AP位控制訪問權限,C、B兩位控制緩存,后面再詳細解釋每個位的含義。如果描述符的最低兩位是01或11,則分別對應兩種不同規格的二級頁表(VA19:12則

25、為256項)。根據地址對齊的規律想一下,這兩種頁表分別是多大?從一級描述符中取出二級頁表的基地址,再把VA的一部分作為索引去查二級描述符(Level 2 Descriptor)(如果是Coarse Page Table則VA19:12是索引,如果是Fine Page Table則VA19:10是索引),二級描述符可以是以下四種格式之一:圖 13. 二級頁描述符    描述符最低兩位是00屬于Fault格式,其它三種情況分別對應三種不同規格的物理頁面。Large Page和Small Page有四組AP權限位,每組兩個bit,這樣可以為每1/4個物理頁面分別設置不同

26、的權限,也就是說,Large Page可以為每16K設置不同的權限,Small Page可以為每1K設置不同的權限。    ARM920T提供了多種頁表和頁面規格,但操作系統只采用其中一種,Linux采用的就是圖 9 “Translation Table Walk”所示的規格,一級描述符是Coarse Page Table格式,二級描述符是Small Page格式,每個物理頁面4K。我們以此為例,結合前面的的解釋和頁描述符的格式,再看一下Translation Table Walk的詳細過程:圖 14. Translation Table Walk的詳細過程

27、60;   從上到下依次解釋如下:    1 VA被劃分為三段用于地址映射過程,各段的長度取決于頁描述符的格式。    2 TTB寄存器中只有31:14位有效,低14位全為0,因此一級頁表的基地址對齊到16K地址邊界,而一級頁表的大小也是16K。    3 一級頁表的基地址加上VA31:20左移兩位組裝成一個物理地址。想一想為什么VA31:20要左移兩位占據13:2的位置,而空出1:0兩位呢?類型?   4 用這個組裝的物理地址從物理內存中讀取一級頁描述符,這是一個

28、Coarse Page Table格式的描述符。   5 通過Domain權限檢查后,Coarse Page Table的基地址再加上VA19:12左移兩位組裝成一個物理地址。   6 用這個組裝的物理地址從物理內存中讀取二級頁描述符,這是一個Small Page格式的描述符。   7 通過AP權限檢查后,Small Page的基地址再加上VA11:0就是最終的物理地址。想一想為什么這次不左移兩位了呢?   下面解釋一下Domain和AP位。CP15的Domain訪問控制寄存器(見表 1 “CP15協處理器的寄存器

29、列表”寄存器3)表示了16個域(Domain),每兩位表示一個Domain的訪問權限,以下是該寄存器的格式:   圖 15. Domain Access Control Register   每個Domain的兩個位可以取值為00、01、10或11,如果取值為00或10則表示該Domain不可訪問,如果取值為01則表示訪問該Domain需要進一步檢查AP位,如果取值為11則表示可以直接訪問該Domain而無需檢查AP位。回想一下,一級頁描述符中的Domain字段由4個位組成,可以有16個不同的取值,就表示該描述符所描述的二級頁表或Section屬于這16

30、個Domain中的哪一個。快速上下文切換、Domain和多種規格的頁表是ARM特有的機制,是針對嵌入式系統軟件的特點而設計的,其它處理器不一定有類似的機制,例如也許沒有Domain和快速上下文切換的概念,也許只有一種規格的頁表。為了能夠在多種不同的平臺上移植,Linux內核代碼不會利用ARM特有的這些機制。除了這些特例之外,我們在這里介紹的其它機制都具有普遍性,讀者應重點把握具有普遍意義的基本原理和基本概念。   CP15的控制寄存器(見表 1 “CP15協處理器的寄存器列表”寄存器1)中的S和R位與頁描述符的AP位合在一起決定訪問權限,如下所示:圖 16. AP權限檢查&

31、#160;   可見,同樣的AP、S、R位對用戶模式和特權模式來說具有不同的意義,特權模式的權限都不低于用戶模式的權限。最后將各種由內存訪問產生的異常總結如下:    Alignment Fault以Word為單位的數據訪問指令地址未對齊到4字節邊界,或者以Half Word為單位的數據訪問指令地址未對齊到2字節邊界。    Translation Fault頁描述符的1:0為00,屬于Fault格式,無效表項。    Domain Fault一級頁描述符或Section所屬Domai

32、n的權限位為00或10。   Permission Fault根據AP位和CP15寄存器1的S、R位檢查訪問權限,若所屬Domain的權限位為11則跳過這一步檢查。    External Abort總線異常,例如此物理地址上沒有掛RAM芯片,或者其它硬件故障。Cache ARM920T有16K的數據Cache和16K的指令Cache,這兩個Cache是基本相同的,數據Cache多了一些寫回內存的機制,后面我們以數據Cache為例來介紹Cache的基本原理。我們已經知道,Cache中的存儲單位是Cache Line,ARM920T的一個Cach

33、e Line是32字節,因此16K的Cache由512條Cache Line組成。要了解Cache的基本原理,我們從如何設計Cache這個問題入手。   設計Cache的一種最樸素的想法是,把VA分成以32字節為單位,從任何一個對齊到32字節地址邊界的VA開始連續的32個字節(比如0x00-0x1f,0x20-0x3f,0x40-0x5f等等)都可以緩存到512條Cache Line中的任何一條。那么一條Cache Line中的32個字節怎么知道是來自哪個VA的呢?這就需要把VA也保存在Cache中,由于這32字節的起始地址是對齊到32字節地址邊界的,末5位全為0,因此只需

34、要保存VA31:5即可,這稱為VA Tag4,Tag是VA的一部分,是Cache Line中數據的標識,表明這32字節數據來自哪個VA。這樣設計的Cache稱為全相聯Cache(Fully Associative Cache),圖示如下: 圖 17. 全相聯Cache   給定一個VA,如何在Cache中查找對應的數據呢?首先到Cache中比較查找哪一行的Tag等于VA31:5,找到對應的Cache Line后,再根據VA4:0決定要訪問的是該Cache Line緩存的32個字節中的哪一個字節。由于有512條Cache Line,如果這個VA沒有緩存在Cache中則需要比較

35、512次才知道,這是最壞的情況,也是最常見的情況,下面我們要改進Cache的設計來解決這個問題。   全相聯Cache的特點是任何VA都可以緩存到任何一條Cache Line,給定一個VA做查找時,由于它有可能緩存在512條Cache Line中的任何一條,就只好全部都找一遍了。如果限定某一個VA只允許緩存在某一條Cache Line中,那么查找的過程就快多了:檢查一下應該緩存這個VA的那條Cache Line,看Tag一致不一致,如果一致就是Cache Hit,如果不一致就是Cache Miss,可以直接訪問物理內存而不必再找其它Cache Line了。這種設計稱為直接映

36、射Cache(Direct Mapped Cache),如下圖所示:圖 18. 直接映射Cache    地址031應該緩存在第1條Cache Line中,地址3263應該緩存在第2條Cache Line中,依此類推,地址1635216383應該緩存在第512條Cache Line中,下一個地址應該是16384(16K)了,我們又回到開頭,地址16K16K+31應該緩存在第1條Cache Line中,地址16K+3216K+63應該緩存在第2條Cache Line中,依此類推,再次回到開頭的地址應該是32K,32K32K+31應該緩存在第1條Cache Line中

37、,32K+3232K+63應該緩存在第2條Cache Line中,依此類推。讀者應該可以總結出規律了:給定一個VA,將它除以16K得的余數決定了它應該緩存在哪一條Cache Line中,那么除以16K的商數部分就應該是VA Tag,用以區別Cache Line中緩存的到底是0還是16K還是32K地址上的數據。那么除以16K的商數和余數怎么表示呢?VA31:14就是除以16K的商數,VA13:0就是余數,所以上圖的Tag處標著VA31:14。余數VA13:0是16K Cache里的一個字節偏移量,而Cache是按32字節一個Cache Line組織的,所以余數中的高位VA13:5決定了是第幾條C

38、ache Line,余數中的低位VA4:0決定了Cache Line內的字節偏移量。驗算一下,VA13:5一共是9位,作為Cache Line的編號可以表示的Cache Line數目正是512條。    直接映射Cache雖然查找速度很快,但也有缺點。比如,地址031、16K16K+31、32K32K+31都應該緩存到第1條Cache Line中,假如我們程序第一次訪問地址30,地址031的數據就從內存加載到第1條Cache Line,以便下次訪問能更快一些,但是我們程序第二次訪問的卻是地址32770,地址32K32K+31的數據就要從內存加載到第1條Cache

39、Line,把Cache Line里原來存的地址031的數據替換掉,以便下次訪問能更快一些,但是我們程序第三次訪問的卻是地址16392這樣下去,Cache起不到任何加速作用,形同虛設,這種問題稱為Cache抖動(Cache Thrash)。全相聯Cache就不會有這種問題,因為任何VA都可以緩存到任何一條Cache Line,可以把先后幾次訪問的VA緩存到不同的Cache Line,就不會相互沖突。    全相聯Cache和直接映射Cache各有優缺點,全相聯Cache查找很慢,但沒有抖動問題,直接映射Cache則正相反。為了得到更好的性能,實際CPU的Cache設

40、計是取兩者的折衷,把所有Cache Line分成若干個組,每一組有n條Cache Line,稱為n路組相聯Cache(n-way Set Associative Cache)。ARM920T采用64路組相聯Cache,如下圖所示:圖 19. 64路組相聯Cache    有了前面兩種Cache概念的基礎,這種Cache應該很好理解,512條Cache Line分成8組,每組64條,地址0-31、256-587、512-543等等可以緩存到第1組64條Cache Line中的任何一條,地址32-63、288-319、544-575等等可以緩存到第2組64條Cache

41、 Line中的任何一條,依此類推。為什么說組相聯Cache是全相聯和直接映射Cache的一個折衷呢?如果把組分得很大,把全部Cache Line都分到一個組里面去,就變成了全相聯Cache;如果把組分得很小,每組只有一個Cache Line,就變成了直接映射Cache。作為練習,請讀者自己計算一下為什么VA Tag是VA31:8,為什么組的編號用VA7:5表示。    那么,為什么組相聯Cache的性能比直接映射Cache要好呢?一方面,組相聯Cache把一條Cache Line上的沖突分散到了64條Cache Line上,起到了64倍的積極作用。而另一方面,應該

42、緩存到同一個組的VA更多了:對于直接映射Cache,在同一個組(也就是同一條Cache Line)互相沖突的VA有4G/512個;對于組相聯Cache,在同一個組(64條Cache Line)互相沖突的VA有4G/8個。從這個數量關系來看,組相聯Cache又起到了64倍的消極作用。難道這兩種作用不會完全抵銷嗎?我不打算從數學上嚴格證明,這不是本節的重點,讀者可以通過一個生活常識的例子來理解:層數一樣多的兩棟樓,其中一棟樓是一部電梯,每層三戶,而另一棟樓是兩部電梯,每層六戶,每戶的平均人數一樣多,你認為在哪個樓里等電梯的時間較短呢?   接下來解釋一下有關Cache寫回內存的

43、問題。Cache寫回內存有兩種模式:    Write Back:Cache Line中的數據被CPU核修改時并不立刻寫回內存,Cache Line和內存中的數據會暫時不一致,在Cache Line中有一個Dirty位標記這一情況。當一條Cache Line要被其它VA的數據替換時,如果不是Dirty的就直接替換掉,如果是Dirty的就先寫回內存再替換。   Write Through:每當CPU核修改Cache Line中的數據時就立刻寫回內存,Cache Line和內存中的數據總是一致的。如果有多個CPU或設備同時訪問內存,例如采用雙口RA

44、M,那么Cache中的數據和內存保持一致就非常重要了,這時相關的內存頁面通常配置為Write Through模式。    通過讀寫CP15的相關寄存器,可以對Cache做以下操作:   Clean:將Cache Line中的數據寫回內存,清除Dirty位。在程序中的某些同步點上用于確保Cache Line和內存中的數據一致。   Invalidate:在Cache Line中有一個Invalid位表示無效,將這個位置1,下次要訪問時即使VA Tag匹配也重新從內存讀取數據。例如進程切換時需要聲明前一個進程緩存在Cache中的

45、數據無效。     Lock:將某個地址的數據鎖定在Cache中,確保不被替換掉。在實時系統中,這樣做可以保證某個地址的數據能在一個確定的時間內訪問到。    從Cache中查找要訪問的數據時用的是VA,但是Cache寫回內存要用PA,如果寫回內存時還需要查一遍頁表就太沒有效率了,所以實際上每條Cache Line中還保存了PA31:5(PA Tag),完整的Cache構造如下圖所示:圖 20. PA Tag     最后解決我們前面遺留的一個問題:頁描述符中的C、B位具體是什么意思?表 2. 頁描述符中

46、C、B位的含義    C位為1表示允許Cache,這種情況下用B位來表示Write Through還是Write Back。有些頁面不允許Cache,置C位為0,這種情況下可以用B位來選擇是否允許使用Write Buffer。Write Buffer也是一種簡單的Cache,CPU核執行寫指令時可以把數據交給Write Buffer,然后由Write Buffer負責寫回內存,這時CPU可以執行后續指令而不必等待寫回內存這個較慢的操作結束。操作MMU和Cache的內核啟動代碼    bootloader加載linux內核到內存并解壓之

47、后,Linux內核首先在匯編代碼中讀取CPU的基本信息,對CPU做一些基本設置,創建最簡單的臨時頁表,然后開啟MMU和Cache,啟用虛擬內存管理(此后CPU核發出的地址都是虛擬地址),然后跳到C代碼中完成其它初始化工作,比如創建完整的頁表、初始化各種內核子系統、初始化硬件設備等。本節以Linux 2.4內核的啟動代碼為例,了解一下操作MMU和Cache的具體指令是怎么寫的,通過實例來加深對前面內容的理解。本節的內容改編自ARM Linux演義。    假設目標板的RAM物理地址是從0x0800 0000開始的(也就是說,RAM芯片連接到CPU芯片上從0x0800

48、 0000開始的bank)。經過內核的若干初始化代碼之后,寄存器的內容如下:表 3. 寄存器的初始值    接下來的步驟是:    1 創建簡單的臨時頁表和臨時映射    2 配置與MMU和Cache相關的CP15寄存器    3 啟用MMU和Cache    臨時頁表存放在物理內存地址0x0800 4000開始的16K(回想一下,第一級頁表是16K,有4096個頁描述符)。后面將會把頁描述符填寫成Section格式,也就是直接映射到1M的大頁面

49、,這些都是內核初始化階段臨時用的,為了是寫盡可能少的匯編代碼,盡快啟用MMU并跳到C代碼中做剩下的初始化工作,在完整的兩級頁表建立之后臨時頁表就沒有用了。首先將16K的臨時頁表清零:    下面我們將使用Section格式的頁描述符來填充表項,由于是內核初始化階段,還沒有用戶進程,我們只映射4M的地址空間,覆蓋內核本身的代碼和數據就可以了。思考一下,為什么首先要把這16K臨時頁表清零,即使沒用到的表項也要清零?由于Linux內核在編譯時確定的代碼加載地址是0xc000 8000(虛擬地址),而bootloader將內核代碼加載到物理地址0x0800 8000,我們

50、需要把物理地址從0x0800 0000開始的4M映射到虛擬地址從0xc000 0000開始的4M。    但是這里有一個問題:設置好頁表之后,最終有一條指令是啟用MMU的,假設該指令的PA是0x0800 810c,根據我們要做的映射關系,它的VA應該是0xc000 810c,沒有啟用MMU之前CPU核發出的都是物理地址,從0x0800 810c地址取這條指令來執行,然而該指令執行之后,CPU核發出的地址都要被MMU攔截,CPU核就必須用虛擬地址來取指令了,因此下一條指令應該從0xc000 8110處取得,然而這時pc寄存器(也就是r15寄存器)的值并沒有變,CPU

51、核取下一條指令仍然要從0x0800 8110處取得,此時0x0800 8110已經成了非法地址了。如下圖所示。圖 21. 啟用MMU的那條指令導致的問題為了解決這個問題,要求啟用MMU的那條指令及其附近的指令虛擬地址跟物理地址相同,這樣在啟用MMU前后,附近指令的地址不會發生變化,從而實現平穩過渡。因此需要將物理地址從0x0800 0000開始的1M再映射到虛擬地址從0x0800 0000開始的1M,也就是做一個等價映射(identity map)5。現在把需要建立的映射項總結如下:表 4. 需要建立的映射項    以下代碼建立上面所說的等價映射。 &#

52、160; 回頭看一下表 3 “寄存器的初始值”,r8的值是頁描述符標志位,r5的值是RAM起始物理地址0x0800 0000,由于要做的是等價映射,這里的r5既是PA同時也是VA,第一條指令將r5當作PA,r3=r8+r5=0x0800 0c1e得到完整的頁描述符,比對一下看看各bit的含義。圖 22. 等價映射的頁描述符   該描述符所描述的Section屬于第0個Domain,AP位是11,可讀可寫,C、B位都是1,允許Cache,并且Cache是Write Back方式的。第二條指令,將虛擬地址r5右移18位(對照圖 14 “Translation Table Wal

53、k的詳細過程”看一下為什么是右移18位(高12位是段基址),加到頁表基地址上,得到該描述符在頁表中的地址,結果保存在r0中。第三條指令,將第一條指令計算出的頁描述符的值r3保存在第二條指令計算出的r0地址處,這樣就填寫好了頁表項。    下面映射物理地址從0x8000 0000開始的4M到虛擬地址0xc000 0000,其中TEXTADDR是Linux內核在編譯時確定的代碼加載地址0xc000 8000,PAGE_OFFSET定義為0xc000 0000。請讀者自己分析以下代碼。add r0, r4, #(TEXTADDR & 0xfff00000) &g

54、t;> 18 start of kernel 注:r0 = r4+ 0x3000 = 0800 4000 + 3000 = 0800 7000str r3, r0, #4 PAGE_OFFSET + 0MB 注:0800 7000地址的內容為0800 0c1e add r3, r3, #1 << 20 注:r3=0810 0c1estr r3, r0,#4 PAGE_OFFSET + 1MB 注:0800 7004地址的內容為0810 0c1e add r3, r3, #1 << 20 注:r3=0820 0c1e str r3, r0, #4 PAGE_OFFS

55、ET + 2MB 注:0800 7008地址的內容為0820 0c1e add r3, r3, #1 << 20 注:r3=0830 0c1estr r3,r0,#4 PAGE_OFFSET + 3MB 注:0800 700c地址的內容為0830 0c1e    設置好了頁表,接下來設置與MMU和Cache相關的CP15寄存器:   這一段有很多協處理器指令,請讀者對照S3C2410用戶手冊和代碼中的注釋查看各指令的含義。大體上來說做了以下事情:首先禁用指令和數據Cache,等待Write Buffer寫回內存,然后用r4寄存器的值

56、設置CP15的TTB寄存器,然后設置Domain權限位,我們先前填寫的頁描述符都屬于第0個Domain,Domain寄存器中第0個Domain的權限位設置為11,表示訪問不必檢查AP位。接下來讀出CP15的控制寄存器的值來修改,準備啟用MMU,根據內核配置決定是否啟用數據和指令Cache,修改之后一并寫回控制寄存器,使設置生效:    相關索引    C     Cache,高速緩存, 虛擬內存管理    Cache Hit, ARM920T的CP15協處理器 &#

57、160;  Cache Line, ARM920T的CP15協處理器    Cache Miss, ARM920T的CP15協處理器    Cache Thrash,Cache抖動, Cache    Direct Mapped Cache,直接映射Cache, Cache    Fully Associative Cache,全相聯Cache, Cache    n-way Set Associative Cache,n路組相聯Cache, Cache    M     MMU,Memo

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論