SoC嵌入式软件架构设计之二:虚拟内存管理原理、MMU硬件设计及代码分块管理...
? ? ? ? 程序的大部分代碼都可以在必要的時候才加載到內(nèi)存去執(zhí)行,運行完后可以被直接丟棄或者被其他代碼覆蓋。我們PC上同時跑著很多的應用程序,每個應用程序使用的虛擬地址空間幾乎可以整個線性地址空間(除了部分留給操作系統(tǒng)或者預留它用),可以認為每個應用程序都獨占了整個虛擬地址空間(字長是32的CPU是4G的虛擬地址空間),但我們的物理內(nèi)存只是1G或者2G。即多個應用程序在同時競爭使用這塊物理內(nèi)存,其必然會導致某個時刻只存在程序的某個片段在執(zhí)行,也即是所有程序代碼和數(shù)據(jù)分時復用物理內(nèi)存空間—這就是內(nèi)存管理單元(MMU)工作核心作用所在。
?????? 處理器系列的芯片(如X86、ARM7以上、MIPS)一般都會有MMU,跟操作系統(tǒng)一塊實現(xiàn)虛擬內(nèi)存管理,MMU也是Linux、Wince等操作系統(tǒng)的硬件要求。而控制器系統(tǒng)的芯片(面向低端控制領域,ARM7,MIPS M系列,80251等)一般都沒有MMU,或者其只有單一的線性映射機制。
?????? 本文要談的是控制器領域SoC的內(nèi)存管理單元的硬件設計,其重要的理念同樣是代碼和數(shù)據(jù)分時復用物理內(nèi)存空間,在保障系統(tǒng)功能和性能的基礎上最大限度地節(jié)省物理內(nèi)存的目的。相關的文章包括:SoC軟件架構(gòu)設計之一:系統(tǒng)內(nèi)存需求評估和節(jié)省內(nèi)存的軟件設計技巧。
?
一、內(nèi)存管理單元(MMU)的工作機制
在闡述控制器領域的內(nèi)存管理之前,還是要先介紹處理器領域的虛擬內(nèi)存管理機制,前者很大程度上是對后者核心機制精髓的借鑒。實現(xiàn)虛擬內(nèi)存管理有幾個模塊是協(xié)調(diào)工作的:CPU、MMU、操作系統(tǒng)、物理內(nèi)存,如圖示(假設該芯片系列沒有cache):
?
? ? ? ?我們根據(jù)上圖來分析一下CPU訪問內(nèi)存的過程,假設尋址是0x10000008,一頁大小為4K(12比特)。則虛擬地址會分成兩個部分:頁映射部分(20bit,0x10000)+頁內(nèi)偏移(12bit, 0x8)。CPU通過總線把地址信號(0x10000008)送給MMU,MMU會把該地址的頁映射部分(20bit)拿到TLB中匹配。
TLB是什么東西?Translation Lookaside Buffer,網(wǎng)上有稱為“翻譯后備緩沖器”。這個翻譯都不知道它干什么。它的作用就是頁表的緩沖,我喜歡叫它為頁表cache。其結(jié)構(gòu)圖如下:
?
? ? ? ?可以想象,TLB就是索引地址數(shù)組,數(shù)組的每個元素就是一個索引結(jié)構(gòu),包含虛擬頁地址和物理頁地址。其在芯片內(nèi)部表現(xiàn)為寄存器形式,一般寄存器都是32位,實際上TLB中的頁地址也是32位寄存器,只不過索引比較時是比較前20bit,后12bit其實也是有用的,例如可以設置某個bit是表示常駐的,即該索引是永遠有效的,不能更換,這種場景一般是為適合一些性能要求特別高的編解碼算法而設計的。非常駐內(nèi)存的一般在某個時刻(如TLB填滿時訪問一個新的頁地址)就會發(fā)生置換。
1)?假如0x10000008的前20bit在TLB中第M個索引中命中,這時就表示該虛擬頁在物理內(nèi)存中已經(jīng)給它分配好對應的物理內(nèi)存,頁表中也已經(jīng)做好記錄。至于虛擬地址對應的代碼頁是否從外存儲(flash,card,硬盤)的程序中加載到內(nèi)存中還需要要另外的標記,怎么標記呢?就是利用上面所講的TLB低12位的某一bit(我們稱為K)來標識,1標識代碼數(shù)據(jù)已經(jīng)加載到內(nèi)存,0表示還沒加載到內(nèi)存。假如是1,那就會用M中的物理地址作為高20bit,以頁內(nèi)偏移0x8作為低12bit,形成一個物理地址,送到內(nèi)存去訪問。此時該次訪問就會完成。
2)?假如K是0,那意味著代碼數(shù)據(jù)尚未加載到內(nèi)存,這時MMU會向中斷管理模塊輸出信號,觸發(fā)一個中斷進行內(nèi)核態(tài),由操作系統(tǒng)負責將對應的代碼頁加載到內(nèi)存。并修改對應頁表項的K比特和TLB對應項的K比特為1.
3)?假如0x10000008的前20bit在TLB所有索引中都沒有命中,則MMU也會向中斷管理模塊輸出一個信號觸發(fā)中斷進入內(nèi)核態(tài),由操作系統(tǒng)將0x10000008右移12位(即除以4K)到頁表中去取得對應的物理頁值,假如物理頁值非0有效,說明代碼已經(jīng)加載到內(nèi)存了,這時將頁表項的值填入到某一個空閑的TLB項中;假如物理頁值為0,說明尚未給這個虛擬頁分配實際的物理內(nèi)存空間,這時會給它分配實際的物理內(nèi)存,并寫好頁表的對應項(這時K是0),最后將這索引項寫入TLB的其中一條。
2)和3)其實都是在中斷內(nèi)核態(tài)中完成的,為什么不一塊做了呢?主要是因為一次中斷不應該做太多事情,以加大中斷延時,影響系統(tǒng)性能。當然如果有芯片將兩者做成一個中斷也是可以理解的。我們再來看看頁表的結(jié)構(gòu)。頁表當然也可以按TLB那樣做成索引數(shù)組,但是這樣有兩個不好的地方:
1)頁表是要映射所有的虛擬頁面的,其維護在內(nèi)存中也需要不小的空間。頁大小是4K時,那映射全部就是4G/4K=1M條索引,每條索引4*2=8個字節(jié),就是8M內(nèi)存。
2)假如按TLB那種結(jié)構(gòu),那匹配索引的過程就是一個for循環(huán)匹配電路,效率很低,要知道我們做這個都是在中斷態(tài)完成的。
所以一般的頁表都是設計成一維數(shù)組,即以整個線性虛擬地址空間按頁為單位依次作為數(shù)組的下標,即頁表的第一個字(4字節(jié))就映射虛擬地址空間的最低4K,第二個字映射虛擬地址最低的第二個4K,以此類推,頁表的第N個字就映射虛擬地址空間的第N個4K空間,即(N-1)*4K~4KN的地址空間。這樣頁表的大小就是1M*4=4M字節(jié),而且匹配索引的時候只是一個偏移計算,非常快。
?
承前啟后,在引出第二部分之前先明確兩個概念:
1. Bank表示代碼分塊的意思,類似于上面提到的頁的概念。
2.不同代碼分時復用內(nèi)存:不同代碼即意味著不同的虛擬地址對應的代碼,(程序鏈接后的地址都是虛擬地址),內(nèi)存即物理內(nèi)存,即一定大小的不同虛擬地址的代碼在不同的時刻都跑在同一塊一定大小的物理內(nèi)存空間上。每一塊不同的代碼塊即是不同的代碼Bank。?
?
二、控制器領域SoC內(nèi)存管理單元的硬件設計
?????? 這里專指沒有內(nèi)存管理單元的SoC設計,一般為了降低成本,在性能足夠時,如果16位或者24位字長CPU能夠解決問題,一般都不會去選32位字長的CPU,除非是計算性能考慮,或者32位CPU的license更便宜(一般很少見)。只要能夠達到高效地進行內(nèi)存管理,實現(xiàn)物理內(nèi)存分時復用的目的,那都可以稱為是成功或者有效的。
? ? ? ?有兩種方法可以實現(xiàn)在MMU硬件單元的情況下實現(xiàn)代碼分塊管理:
? ? ? ?1)利用工具鏈來實現(xiàn)內(nèi)存分時復用的機制。
? ? ? ?2)結(jié)合MMU和這個工具鏈實現(xiàn)的分塊處理方法去設計我們新的內(nèi)存管理單元,包括其硬件工作機制和軟件設計和關鍵機制。?
? ? ? ?由于2)中的內(nèi)容涉及到在審專利,暫時隱藏,后續(xù)再公開,抱歉!?
? ? ? ? 在集成沒有MMU的CPU時,SoC要實現(xiàn)內(nèi)存管理,需要另外設計一個內(nèi)存管理模塊,實現(xiàn)MMU的核心功能,即代碼分頁(塊)映射的功能,而且需要簡化設計以達到最高的效率,同時代碼分塊需要直接地體現(xiàn)在鏈接腳本上。為了追求效率,編譯鏈接后的可執(zhí)行性文件還會被離線解析組織成一個更簡化的執(zhí)行文件,把不需要的段都刪除,并將分塊代碼按邏輯順序放好,以便于操作系統(tǒng)在必要時更快地加載。當然,操作系統(tǒng)的代碼內(nèi)存管理也需要配合內(nèi)存管理硬件電路,并能夠解析重新打包后的執(zhí)行程序文件。因此內(nèi)存管理的實現(xiàn)是需要架構(gòu)師從軟件和硬件上全面考慮,盡可能地在實現(xiàn)核心功能的基礎上簡化電路和設計,涉及的模塊包括:硬件機制設計、物理內(nèi)存分配、代碼分塊原則、linker腳本定義、打包執(zhí)行文件、操作系統(tǒng)定制等等。
轉(zhuǎn)載于:https://www.cnblogs.com/yueqian-scut/p/4013858.html
總結(jié)
以上是生活随笔為你收集整理的SoC嵌入式软件架构设计之二:虚拟内存管理原理、MMU硬件设计及代码分块管理...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win7上帝模式
- 下一篇: [原]HAproxy 代理技术原理探究