深度分析Linux內(nèi)核高端內(nèi)存分析.doc_第1頁(yè)
深度分析Linux內(nèi)核高端內(nèi)存分析.doc_第2頁(yè)
深度分析Linux內(nèi)核高端內(nèi)存分析.doc_第3頁(yè)
深度分析Linux內(nèi)核高端內(nèi)存分析.doc_第4頁(yè)
深度分析Linux內(nèi)核高端內(nèi)存分析.doc_第5頁(yè)
已閱讀5頁(yè),還剩1頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Linux內(nèi)核高端內(nèi)存1. Linux內(nèi)核地址映射模型x86 CPU采用了段頁(yè)式地址映射模型。進(jìn)程代碼中的地址為邏輯地址,經(jīng)過(guò)段頁(yè)式地址映射后,才真正訪問(wèn)物理內(nèi)存。段頁(yè)式機(jī)制如下圖。2.Linux內(nèi)核地址空間劃分通常32位Linux內(nèi)核地址空間劃分03G為用戶空間,34G為內(nèi)核空間。注意這里是32位內(nèi)核地址空間劃分,64位內(nèi)核地址空間劃分是不同的。3.Linux內(nèi)核高端內(nèi)存的由來(lái)當(dāng)內(nèi)核模塊代碼或線程訪問(wèn)內(nèi)存時(shí),代碼中的內(nèi)存地址都為邏輯地址,而對(duì)應(yīng)到真正的物理內(nèi)存地址,需要地址一對(duì)一的映射,如邏輯地址0xc0000003對(duì)應(yīng)的物理地址為0x3,0xc0000004對(duì)應(yīng)的物理地址為0x4, ,邏輯地址與物理地址對(duì)應(yīng)的關(guān)系為物理地址 = 邏輯地址 0xC0000000邏輯地址物理內(nèi)存地址0xc00000000x00xc00000010x10xc00000020x20xc00000030x30xe00000000x200000000xffffffff0x40000000 ?假設(shè)按照上述簡(jiǎn)單的地址映射關(guān)系,那么內(nèi)核邏輯地址空間訪問(wèn)為0xc0000000 0xffffffff,那么對(duì)應(yīng)的物理內(nèi)存范圍就為0x0 0x40000000,即只能訪問(wèn)1G物理內(nèi)存。若機(jī)器中安裝8G物理內(nèi)存,那么內(nèi)核就只能訪問(wèn)前1G物理內(nèi)存,后面7G物理內(nèi)存將會(huì)無(wú)法訪問(wèn),因?yàn)閮?nèi)核的地址空間已經(jīng)全部映射到物理內(nèi)存地址范圍0x0 0x40000000。即使安裝了8G物理內(nèi)存,那么物理地址為0x40000001的內(nèi)存,內(nèi)核該怎么去訪問(wèn)呢?代碼中必須要有內(nèi)存邏輯地址的,0xc0000000 0xffffffff的地址空間已經(jīng)被用完了,所以無(wú)法訪問(wèn)物理地址0x40000000以后的內(nèi)存。顯然不能將內(nèi)核地址空間0xc0000000 0xfffffff全部用來(lái)簡(jiǎn)單的地址映射。因此x86架構(gòu)中將內(nèi)核地址空間劃分三部分:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_HIGHMEM即為高端內(nèi)存,這就是內(nèi)存高端內(nèi)存概念的由來(lái)。在x86結(jié)構(gòu)中,三種類型的區(qū)域如下:ZONE_DMA 內(nèi)存開(kāi)始的16MBZONE_NORMAL 16MB896MBZONE_HIGHMEM 896MB 結(jié)束4.Linux內(nèi)核高端內(nèi)存的理解前面我們解釋了高端內(nèi)存的由來(lái)。 Linux將內(nèi)核地址空間劃分為三部分ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,高端內(nèi)存HIGH_MEM地址空間范圍為0xF8000000 0xFFFFFFFF(896MB1024MB)。那么如內(nèi)核是如何借助128MB高端內(nèi)存地址空間是如何實(shí)現(xiàn)訪問(wèn)可以所有物理內(nèi)存?當(dāng)內(nèi)核想訪問(wèn)高于896MB物理地址內(nèi)存時(shí),從0xF8000000 0xFFFFFFFF地址空間范圍內(nèi)找一段相應(yīng)大小空閑的邏輯地址空間,借用一會(huì)。借用這段邏輯地址空間,建立映射到想訪問(wèn)的那段物理內(nèi)存(即填充內(nèi)核PTE頁(yè)面表),臨時(shí)用一會(huì),用完后歸還。這樣別人也可以借用這段地址空間訪問(wèn)其他物理內(nèi)存,實(shí)現(xiàn)了使用有限的地址空間,訪問(wèn)所有所有物理內(nèi)存。如下圖。例如內(nèi)核想訪問(wèn)2G開(kāi)始的一段大小為1MB的物理內(nèi)存,即物理地址范圍為0x80000000 0x800FFFFF。訪問(wèn)之前先找到一段1MB大小的空閑地址空間,假設(shè)找到的空閑地址空間為0xF8700000 0xF87FFFFF,用這1MB的邏輯地址空間映射到物理地址空間0x80000000 0x800FFFFF的內(nèi)存。映射關(guān)系如下:邏輯地址物理內(nèi)存地址0xF87000000x800000000xF87000010x800000010xF87000020x800000020xF87FFFFF0x800FFFFF當(dāng)內(nèi)核訪問(wèn)完0x80000000 0x800FFFFF物理內(nèi)存后,就將0xF8700000 0xF87FFFFF內(nèi)核線性空間釋放。這樣其他進(jìn)程或代碼也可以使用0xF8700000 0xF87FFFFF這段地址訪問(wèn)其他物理內(nèi)存。從上面的描述,我們可以知道高端內(nèi)存的最基本思想:借一段地址空間,建立臨時(shí)地址映射,用完后釋放,達(dá)到這段地址空間可以循環(huán)使用,訪問(wèn)所有物理內(nèi)存。看到這里,不禁有人會(huì)問(wèn):萬(wàn)一有內(nèi)核進(jìn)程或模塊一直占用某段邏輯地址空間不釋放,怎么辦?若真的出現(xiàn)的這種情況,則內(nèi)核的高端內(nèi)存地址空間越來(lái)越緊張,若都被占用不釋放,則沒(méi)有建立映射到物理內(nèi)存都無(wú)法訪問(wèn)了。在香港尖沙咀有些寫(xiě)字樓,洗手間很少且有門(mén)鎖的??蛻粢ハ词珠g的話,可以向前臺(tái)拿鑰匙,方便完后,把鑰匙歸還到前臺(tái)。這樣雖然只有一個(gè)洗手間,但可以滿足所有客戶去洗手間的需求。要是某個(gè)客戶一直占用洗手間、鑰匙不歸還,那么其他客戶都無(wú)法上洗手間了。Linux內(nèi)核高端內(nèi)存管理的思想類似。5.Linux內(nèi)核高端內(nèi)存的劃分內(nèi)核將高端內(nèi)存劃分為3部分:VMALLOC_STARTVMALLOC_END、KMAP_BASEFIXADDR_START和FIXADDR_START4G。對(duì)于高端內(nèi)存,可以通過(guò) alloc_page() 或者其它函數(shù)獲得對(duì)應(yīng)的 page,但是要想訪問(wèn)實(shí)際物理內(nèi)存,還得把 page 轉(zhuǎn)為線性地址才行(為什么?想想 MMU 是如何訪問(wèn)物理內(nèi)存的),也就是說(shuō),我們需要為高端內(nèi)存對(duì)應(yīng)的 page 找一個(gè)線性空間,這個(gè)過(guò)程稱為高端內(nèi)存映射。對(duì)應(yīng)高端內(nèi)存的3部分,高端內(nèi)存映射有三種方式:映射到”內(nèi)核動(dòng)態(tài)映射空間”(noncontiguous memory allocation)這種方式很簡(jiǎn)單,因?yàn)橥ㄟ^(guò) vmalloc() ,在”內(nèi)核動(dòng)態(tài)映射空間”申請(qǐng)內(nèi)存的時(shí)候,就可能從高端內(nèi)存獲得頁(yè)面(參看 vmalloc 的實(shí)現(xiàn)),因此說(shuō)高端內(nèi)存有可能映射到”內(nèi)核動(dòng)態(tài)映射空間”中。持久內(nèi)核映射(permanent kernel mapping)如果是通過(guò) alloc_page() 獲得了高端內(nèi)存對(duì)應(yīng)的 page,如何給它找個(gè)線性空間??jī)?nèi)核專門(mén)為此留出一塊線性空間,從 PKMAP_BASE 到 FIXADDR_START ,用于映射高端內(nèi)存。在 2.6內(nèi)核上,這個(gè)地址范圍是 4G-8M 到 4G-4M 之間。這個(gè)空間起叫”內(nèi)核永久映射空間”或者”永久內(nèi)核映射空間”。這個(gè)空間和其它空間使用同樣的頁(yè)目錄表,對(duì)于內(nèi)核來(lái)說(shuō),就是 swapper_pg_dir,對(duì)普通進(jìn)程來(lái)說(shuō),通過(guò) CR3 寄存器指向。通常情況下,這個(gè)空間是 4M 大小,因此僅僅需要一個(gè)頁(yè)表即可,內(nèi)核通過(guò)來(lái) pkmap_page_table 尋找這個(gè)頁(yè)表。通過(guò) kmap(),可以把一個(gè) page 映射到這個(gè)空間來(lái)。由于這個(gè)空間是 4M 大小,最多能同時(shí)映射 1024 個(gè) page。因此,對(duì)于不使用的的 page,及應(yīng)該時(shí)從這個(gè)空間釋放掉(也就是解除映射關(guān)系),通過(guò) kunmap() ,可以把一個(gè) page 對(duì)應(yīng)的線性地址從這個(gè)空間釋放出來(lái)。臨時(shí)映射(temporary kernel mapping)內(nèi)核在 FIXADDR_START 到 FIXADDR_TOP 之間保留了一些線性空間用于特殊需求。這個(gè)空間稱為”固定映射空間”在這個(gè)空間中,有一部分用于高端內(nèi)存的臨時(shí)映射。這塊空間具有如下特點(diǎn):(1)每個(gè) CPU 占用一塊空間(2)在每個(gè) CPU 占用的那塊空間中,又分為多個(gè)小空間,每個(gè)小空間大小是 1 個(gè) page,每個(gè)小空間用于一個(gè)目的,這些目的定義在 kmap_types.h 中的 km_type 中。當(dāng)要進(jìn)行一次臨時(shí)映射的時(shí)候,需要指定映射的目的,根據(jù)映射目的,可以找到對(duì)應(yīng)的小空間,然后把這個(gè)空間的地址作為映射地址。這意味著一次臨時(shí)映射會(huì)導(dǎo)致以前的映射被覆蓋。通過(guò) kmap_atomic() 可實(shí)現(xiàn)臨時(shí)映射。6.常見(jiàn)問(wèn)題:1、用戶空間(進(jìn)程)是否有高端內(nèi)存概念?用戶進(jìn)程沒(méi)有高端內(nèi)存概念。只有在內(nèi)核空間才存在高端內(nèi)存。用戶進(jìn)程最多只可以訪問(wèn)3G物理內(nèi)存,而內(nèi)核進(jìn)程可以訪問(wèn)所有物理內(nèi)存。2、64位內(nèi)核中有高端內(nèi)存嗎?目前現(xiàn)實(shí)中,64位Linux內(nèi)核不存在高端內(nèi)存,因?yàn)?4位內(nèi)核可以支持超過(guò)512GB內(nèi)存。若機(jī)器安裝的物理內(nèi)存超過(guò)內(nèi)核地址空間范圍,就會(huì)存在高端內(nèi)存。3、用戶進(jìn)程能訪問(wèn)多少物理內(nèi)存??jī)?nèi)核代碼能訪問(wèn)多少物理內(nèi)存?32位系統(tǒng)用戶進(jìn)程最大可以訪問(wèn)3

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論