先上基礎(chǔ),下圖是Linux的內(nèi)存映射模型
每一個(gè)進(jìn)程都有自己的進(jìn)程空間,進(jìn)程空間的0-3G是用戶空間,3G-4G是內(nèi)核空間
每個(gè)進(jìn)程的用戶空間不在同一個(gè)物理內(nèi)存頁(yè),但是所有的進(jìn)程的內(nèi)核空間對(duì)應(yīng)同樣的物理地址
vmalloc分配的地址可以高端內(nèi)存,也可以是低端內(nèi)存
0-896MB的物理地址是線性映射到物理映射區(qū)的。
內(nèi)核參數(shù)和系統(tǒng)頁(yè)表都在TEXT_OFFSET保存,除了進(jìn)程除了訪問(wèn)自身的用戶空間對(duì)應(yīng)的DRAM內(nèi)存頁(yè)外,都要經(jīng)過(guò)內(nèi)核空間,也就是都要切換到內(nèi)核態(tài)
內(nèi)存動(dòng)態(tài)申請(qǐng)
和應(yīng)用層一樣,內(nèi)核程序也需要?jiǎng)討B(tài)的分配內(nèi)存,不同的是,內(nèi)核進(jìn)程可以控制分配的內(nèi)存是在用戶空間還是內(nèi)核空間,前者可以用于給用戶空間的堆區(qū)分配內(nèi)存,eg,用戶進(jìn)程的用戶空間的malloc最終就會(huì)通過(guò)系統(tǒng)調(diào)用回調(diào)內(nèi)核空間的內(nèi)存分配函數(shù),此時(shí)該內(nèi)存分配函數(shù)就屬于該用戶進(jìn)程,可以給在該用戶進(jìn)程的堆區(qū)分配空間并返回,最終使得一個(gè)用會(huì)進(jìn)程在自己的用戶空間獲得內(nèi)存分配;后者只在內(nèi)核空間分配,所以用戶進(jìn)程不能直接訪問(wèn)該空間,所以多用在滿足內(nèi)核程序自身的內(nèi)存需求,下面是Linux內(nèi)核空間申請(qǐng)內(nèi)存常用API:
kmalloc - kfree
kmalloc申請(qǐng)的內(nèi)存在物理內(nèi)存上是連續(xù)的,他們與真實(shí)的物理地址只有一個(gè)固定的偏移,因此存在簡(jiǎn)單的轉(zhuǎn)換關(guān)系。這個(gè)API 多用來(lái)申請(qǐng)不到一個(gè)page大小的內(nèi)存。kmalloc的底層需要調(diào)用__get_free_pages,參數(shù)中表示內(nèi)存類(lèi)型的gtp_t flags正是這個(gè)函數(shù)的縮寫(xiě),常用的內(nèi)存類(lèi)型有GFP_USER,GFP_KERNEL,GFP_ATOMIC幾種。