Linux內(nèi)核分析(三)初識(shí)linux內(nèi)存管理子系統(tǒng)
昨天我們對(duì)內(nèi)核模塊進(jìn)行了簡(jiǎn)單的分析,今天為了讓我們今后的分析沒(méi)有太多障礙,我們今天先簡(jiǎn)單的分析一下linux的內(nèi)存管理子系統(tǒng),linux的內(nèi)存管理子系統(tǒng)相當(dāng)?shù)凝嫶?,所以我們今天只是初識(shí),只要對(duì)其進(jìn)行簡(jiǎn)單的了解就好了,不會(huì)去追究代碼,但是在后面我們還會(huì)對(duì)內(nèi)存管理子系統(tǒng)進(jìn)行一次深度的分析。

所以今天我們會(huì)分析到以下內(nèi)容:
1. Linux地址映射
2. Linux內(nèi)存分配
一、Linux地址映射
下面的分析我們依據(jù)上圖進(jìn)行分析,首先我們來(lái)看其最右邊的地址分布圖(當(dāng)然這是虛擬空間)。其地址分布總的可以分為兩個(gè)部分我們下面慢慢分析(基于32位處理器)。

【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【865977150】或者
系統(tǒng)課程學(xué)習(xí)咨詢(xún)微信【2207032995】,備注一下(玩轉(zhuǎn)Linux內(nèi)核);整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書(shū)籍、視頻資料,有需要的可以自行添加哦?。。?/p>

1.?用戶空間(0~3G)
a)?空間簡(jiǎn)介
其從0x00000000到0xBFFFFFFF共3GB的線性地址空間,每個(gè)進(jìn)程都有一個(gè)獨(dú)立的3GB用戶空間,當(dāng)然這是虛擬的空間。
b)?如何轉(zhuǎn)換為物理空間
這一部分虛擬空間到物理空間的轉(zhuǎn)換方法是我們以前在
http://www.cnblogs.com/wrjvszq/p/4246634.html
一文中分析過(guò)的MMU地址轉(zhuǎn)換。
2.?內(nèi)核空間(3~4G)
其從0xC0000000到0xFFFFFFFF共1GB大小,內(nèi)核空間又可以根據(jù)映射方式的不同分為下面四塊,我們一一分析
a)?內(nèi)核邏輯地址空間
l?空間簡(jiǎn)介
其從0xC0000000到high_memory(圖中896MB的地方)最大為896MB(也就是說(shuō)這塊空間有可能不滿,但最大為896MB),當(dāng)然是虛擬空間。
注:在此注意一下896MB我們一會(huì)在分析。
l?如何轉(zhuǎn)換為物理空間
這一部分虛擬地址與物理內(nèi)存中對(duì)應(yīng)的地址只差一個(gè)固定偏移量(3G),如果內(nèi)存物理地址空間從0x00000000地址編址,那么這個(gè)固定偏移量就是PAGE_OFFSET(如上圖)。
b)?Vmalloc空間
l?空間簡(jiǎn)介
其地址沒(méi)有嚴(yán)格的界限,這段空間既可以訪問(wèn)到我們的高端內(nèi)存,也可以訪問(wèn)到低端內(nèi)存。(高端和低端一會(huì)解釋?zhuān)?/p>
l?如何轉(zhuǎn)換為物理空間
不是通過(guò)簡(jiǎn)單的線性關(guān)系映射,在此不研究。
c)?永久內(nèi)核映射
l?空間簡(jiǎn)介
其固定用來(lái)訪問(wèn)高端內(nèi)存。
l?如何轉(zhuǎn)換為物理空間
不是通過(guò)簡(jiǎn)單的線性關(guān)系映射,在此不研究。
d)?固定映射
l?空間簡(jiǎn)介
其在系統(tǒng)初始化期間永久映射I/O地址空間,或者特殊的寄存器。
3.?遺留知識(shí)
在剛才我們前面的分析中我們留下了一些問(wèn)題下面進(jìn)行解釋。
a)?低端內(nèi)存
內(nèi)核邏輯地址空間所映射的物理內(nèi)存就是低端內(nèi)存(實(shí)際物理內(nèi)存的大小,但是小于896MB)
b)?高端內(nèi)存
低端內(nèi)存地址之上的物理內(nèi)存是高端內(nèi)存(物理內(nèi)存896MB之上)。
c)?896MB來(lái)由
Linux將內(nèi)存分為內(nèi)核空間和用戶空間,其中內(nèi)核空間中的0xC0000000~high_memory部分用來(lái)映射物理內(nèi)存,但是我們還需要映射I/O空間和固定的寄存器,所以留出了high_memory~0xFFFFFFFF之間的地址來(lái)映射I/O空間和固定的寄存器,而在X86平臺(tái)根據(jù)經(jīng)驗(yàn)設(shè)定了這個(gè)high_memory為896MB。
二、Linux內(nèi)存分配
通過(guò)上面的介紹我們對(duì)linux對(duì)內(nèi)存的管理,以及地址的映射有了一個(gè)了解,下面我們來(lái)分析linux是如何進(jìn)行內(nèi)存分配的。

通過(guò)上圖我們可以分析出內(nèi)存的分配過(guò)程:
1. 由malloc、fork等系統(tǒng)調(diào)用和kmalloc、vmalloc申請(qǐng)得到虛擬內(nèi)存。
2. 在我們使用該內(nèi)存的時(shí)候,產(chǎn)生請(qǐng)頁(yè)異常(kmalloc除外)
3. 從空閑的頁(yè)框分配物理內(nèi)存,和虛擬地址建立映射。
注:kmalloc申請(qǐng)空間是不用經(jīng)過(guò)請(qǐng)頁(yè)異常的,返回的虛擬地址已經(jīng)對(duì)應(yīng)了物理內(nèi)存。Kmalloc可以分配到連續(xù)的物理內(nèi)存,vmalloc分配的是非連續(xù)的物理內(nèi)存。