虛擬記憶體---
linux作業系統採用虛擬記憶體管理技術,使得每個進程都有獨立的進程地址空間,該空間是大小為3G,使用者看到和接觸的都是虛擬位址,無法看到實際的物理地址。利用這種虛擬位址不但能起到保護作業系統的作用,而且更重要的是使用者程式可使用比實際實體記憶體更大的地址空間。
linux將4G的虛擬位址空間劃分為兩個部分------使用者空間和核心空間。使用者空間從0----0xbfffffff,核心空間從3G----4G。使用者進程通常情況下只能訪問使用者空間的虛擬位址,不能訪問核心空間。例外情況是使用者進程通過系統調用訪問核心空間。
進程空間----
使用者空間對應進程,所以每當進程切換,使用者空間就會跟著變化。
每個進程的使用者空間都是完全獨立,互不相干的。把同一個程式同時運行10次,會看到10個進程使用的線性地址一摸一樣。cat /proc/<pid>maps
建立進程fork(),程式載入execve(),動態記憶體分配malloc()等進程相關操作都需要分配記憶體給進程。這時進程申請和獲得的不是物理地址,僅僅是虛擬位址。
實際的實體記憶體只有當進程真的去訪問新擷取的虛擬位址時,才會由請頁機制產生缺頁異常,從而進入分配實際頁框的程式。該異常是虛擬記憶體機制賴以存在的基本保證------它會告訴核心去為進程分配物理頁,並建立對應的頁表,這之後虛擬位址才實實在在的映射到了物理地址上。
在應用程式中,常用malloc函數進行動態記憶體分配,而在linux核心中,通常使用kmalloc來動態分配記憶體。
#include <linux/slab.h>
void *kmalloc(size_t size,int flags)
size--要分配的記憶體大小
flags--分配標誌,它控制kmalloc的行為。
最
常用的標誌是GFP_KERNEL。它的意思是該記憶體配置是由運行在核心態的進程調用的。也就是說,調用它的函數屬於某個進程的。當空閑記憶體太少
時,kmalloc函數會使當前進程進入睡眠,等待閒置頁出現。如果kmalloc是在進程上下文之外調用,比如在中斷處理,任務隊列處理,和核心定時
器處理中。這些情況屬於中斷上下文,不能進入睡眠,這時應該使用優先權GFP_ATOMIC
GFP_ATOMIC--在進程上下文之外的代碼中分配記憶體,從不睡眠。
GFP_KERNEL--進程上下文中的分配,可能睡眠。(16M---896M)
__GFP_DMA-----表示分配能夠DMA的記憶體區(物理地址在16M以下的頁幀)
__GFP_HIGHMEM----表示分配的記憶體位於高端記憶體(896M以上)
原文:http://blog.csdn.net/lidaqiang99/article/details/6624946