昨天咱們對內核模塊進行了簡單的分析,今天爲了讓咱們從此的分析沒有太多障礙,咱們今天先簡單的分析一下linux的內存管理子系統,linux的內存管理子系統至關的龐大,因此咱們今天只是初識,只要對其進行簡單的瞭解就行了,不會去追究代碼,可是在後面咱們還會對內存管理子系統進行一次深度的分析。linux
在分析今天的內容以前,咱們先來看出自http://bbs.chinaunix.net/thread-2018659-2-1.html的一位大神作的內存管理圖,真心佩服大神。其實這張圖能夠分爲兩個部分,一部分是地址映射,另外一部分就是內存分配。spa
因此今天咱們會分析到如下內容:.net
1. Linux地址映射3d
2. Linux內存分配unix
下面的分析咱們依據上圖進行分析,首先咱們來看其最右邊的地址分佈圖(固然這是虛擬空間)。其地址分佈總的能夠分爲兩個部分咱們下面慢慢分析(基於32位處理器)。htm
1. 用戶空間(0~3G)blog
a) 空間簡介進程
其從0x00000000到0xBFFFFFFF共3GB的線性地址空間,每一個進程都有一個獨立的3GB用戶空間,固然這是虛擬的空間。
b) 如何轉換爲物理空間
這一部分虛擬空間到物理空間的轉換方法是咱們之前在http://www.cnblogs.com/wrjvszq/p/4246634.html一文中分析過的MMU地址轉換。
2. 內核空間(3~4G)
其從0xC0000000到0xFFFFFFFF共1GB大小,內核空間又能夠根據映射方式的不一樣分爲下面四塊,咱們一一分析
a) 內核邏輯地址空間
l 空間簡介
其從0xC0000000到high_memory(圖中896MB的地方)最大爲896MB(也就是說這塊空間有可能不滿,但最大爲896MB),固然是虛擬空間。
注:在此注意一下896MB咱們一會在分析。
l 如何轉換爲物理空間
這一部分虛擬地址與物理內存中對應的地址只差一個固定偏移量(3G),若是內存物理地址空間從0x00000000地址編址,那麼這個固定偏移量就是PAGE_OFFSET(如上圖)。
b) Vmalloc空間
l 空間簡介
其地址沒有嚴格的界限,這段空間既能夠訪問到咱們的高端內存,也能夠訪問到低端內存。(高端和低端一會解釋)
l 如何轉換爲物理空間
不是經過簡單的線性關係映射,在此不研究。
c) 永久內核映射
l 空間簡介
其固定用來訪問高端內存。
l 如何轉換爲物理空間
不是經過簡單的線性關係映射,在此不研究。
d) 固定映射
l 空間簡介
其在系統初始化期間永久映射I/O地址空間,或者特殊的寄存器。
3. 遺留知識
在剛纔咱們前面的分析中咱們留下了一些問題下面進行解釋。
a) 低端內存
內核邏輯地址空間所映射的物理內存就是低端內存(實際物理內存的大小,可是小於896MB)
b) 高端內存
低端內存地址之上的物理內存是高端內存(物理內存896MB之上)。
c) 896MB來由
Linux將內存分爲內核空間和用戶空間,其中內核空間中的0xC0000000~high_memory部分用來映射物理內存,可是咱們還須要映射I/O空間和固定的寄存器,因此留出了high_memory~0xFFFFFFFF之間的地址來映射I/O空間和固定的寄存器,而在X86平臺根據經驗設定了這個high_memory爲896MB。
l Linux內存分配
經過上面的介紹咱們對linux對內存的管理,以及地址的映射有了一個瞭解,下面咱們來分析linux是如何進行內存分配的。
經過上圖咱們能夠分析出內存的分配過程
1. 由malloc、fork等系統調用和kmalloc、vmalloc申請獲得虛擬內存。
2. 在咱們使用該內存的時候,產生請頁異常(kmalloc除外)
3. 從空閒的頁框分配物理內存,和虛擬地址創建映射。
注:kmalloc申請空間是不用通過請頁異常的,返回的虛擬地址已經對應了物理內存。Kmalloc能夠分配到連續的物理內存,vmalloc分配的是非連續的物理內存。