一、Linux記憶體結構分為:node(節點),zone(地區),page(頁框描述符)
node ----{ zone-----{ page
……
{ zone-----{page
二、映射高端記憶體的方法:
永久映射(permanent kernel mapping)和暫時映射(temporary kernel mapping),以及不連續記憶體申請(noncontiguous memory )
1)永久映射:
使用核心中專門儲存的一個頁表來實現,相當於是建立頁表映射,因為涉及到操作頁表有可能休眠
void *kmap(struct page * page);
用法:
struct page * page = alloc_pages(GFP_HIGHMEM,1);
int * vaddr = kmap(page);
2)臨時映射:
使用核心中專門儲存的一個頁表項(page table entry)來實現,相當於是建立頁表映射,不會導致休眠
void *kmap_atomic(struct page * page);
用法:
struct page * page = alloc_pages(GFP_HIGHMEM,1);
int * vaddr = kmap_atomic(page);
三、記憶體地區管理
zone和buddy演算法解決了申請頁框時的問題:硬體限制和記憶體片段。
而在實際的核心編程中最常碰到的是各種不同size資料結構mem request的申請和釋放,要解決這種類型記憶體請求的效率和記憶體片段問題,
就需要用到cache和slab,原因有:
1)相同size記憶體的申請和釋放相當常見,為了避免核心疲於應付這些工作,核心提供了一個方法:基於cache來建立slab系統,每個slab
對應相應的記憶體單元size,申請到來時及時滿足,釋放時進行軟體回收,這樣就避免了頻繁做頁框動作。
2)為瞭解決記憶體片段問題,
四、非連續記憶體區的管理
非連續記憶體區是指線性地址連續,物理地址不連續的vmalloc地區,該地區用於映射超過896MB的實體記憶體頁框,
通常只適用於X86架構,ARM等嵌入式架構很少會用到這麼大的記憶體量,因此在ARM架構下kmap,永久核心映射,
固定核心映射都用不到。
其實vmalloc的實現方法就是通過alloc_pages來申請數個頁框,當然這些頁框位於HIGHMEM,來滿足申請的記憶體大小,
然後修改頁表,建立VMALLOC段線性地址到這些頁表的映射。