1,Linux內核內存管理基礎:
1》Linux系統5種地址類型:用戶空間虛擬地址,物理地址,總線地址,內核邏輯地址,內核虛擬地址;
內核邏輯地址就是內核虛擬地址,內核邏輯地址通過kmalloc(標誌GFP_KERNEL)分配,內核虛擬地址不一定是內核邏輯地址;
內核邏輯地址和物理地址是線性關係,之間相差固定的值;
內核邏輯地址位寬和cpu地址總線位寬一致,所以邏輯地址能夠映射的物理內存大小有限,在32位架構上不到1G;
2》物理層:物理地址,頁幀,低端內存,高端內存
物理地址——cpu地址總線向存儲控制器傳輸的地址;
頁幀——物理內存空間通常被劃分爲大小相同的頁的方式來管理,每一個頁面稱爲頁幀,通常一個頁幀爲4K,頁幀是內存地址映射的基本單位;
低端內存——內核邏輯地址構成低端內存,內核邏輯地址構成內核邏輯內存空間即就是內核常規內存空間,即就是低端內存;
高端內存——由於內核邏輯地址位寬和cpu地址總線位寬一致,所以內核邏輯地址的尋址空間有限,滿足不了大內存的需求,所以就出現了高端內存,
高端內存映射內核真正的虛擬地址空間;
低端內存與高端內存的真正區別:
能夠映射到內核邏輯地址空間的內存爲低端內存,內核本身的數據必須存放在低端內存中;
不能夠映射到內核邏輯地址空間的內存爲高端內存,爲用戶空間進程預留內存空間;
3》數據結構:
struct page: 由於內核邏輯地址方式滿足不了大內存即高端內存的映射需求,由於高端內存不能夠映射到內核邏輯地址空間;所以就出現了內核內存管理子系統最重要的數據結構之一struct page,該數據結構記錄了內核需要的每一個物理頁幀的所有的信息,用get_free_pages()來獲取空閒的page(物理頁幀);
struct vm_area_struct :虛擬內存數據結構,內核內存管理子系統用該重量級數據結構表示每一個虛擬內存區域;
成員屬性:unsigned long vm_start;unsigned long vm_end;unsigned long vm_pgoff;int prot,int flags,struct vm_operations_struct v_ops;
struct vm_area_struct:對虛擬內存進行操作;
成員屬性:int (*open)(struct file *,struct vm_area_struct *);
int (*close)(struct file *,struct vm_area_struct *);
int (*fault)(struct vm_area_struct *,struct vm_mf *);
struct mm_struct :內存映射數據結構,記錄了每一個用戶空間進程的所有的內存信息,把上述數據結構都映射到一塊,統一組織管理,每一個用戶空間進程task_struct 實例對象都有一個mm_struct實例對象;
4》內存映射操作——系統調用mmap():
a,api:用戶空間api:int mmap(void *addr,unsigned long len,unsigned long loff,int prot,int flags,unsigned long fd);
驅動模塊函數:int mmap(struct file *filp,struct vm_area_struct *vma);
b,設備內存映射到用戶虛擬內存空間:
兩種實現方式:
c,用戶空間虛擬地址直接映射到RAM上,本質上是用戶空間虛擬地址直接映射到內核虛擬地址空間,包含兩部分:用戶空間虛擬地址映射到內核邏輯地址空間映射的物理內存上,用戶空間虛擬地址映射到內核真正的虛擬地址映射的內存上;
一》用戶空間虛擬地址直接映射到內核邏輯地址空間對應的內存空間上:
二》用戶空間虛擬地址直接映射到內核真正的虛擬地址空間對應的內存上: