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