linux
kamlloc函數原型:
#include<linux/slab.h>
Void *kmalloc(size_t size, int flags);
1.使用GFP_KERNEL容許kmalloc在分配空閑記憶體時候如果記憶體不足容許把當前進程睡眠以等待。因此這時分配函數必須是可重新進入的。如果在進程上下文之外如:中斷處理常式、tasklet以及核心定時器中這種情況下current進程不該睡眠,驅動程式該使用GFP_ATOMIC.
2.GFP_ATOMIC用來從中斷處理和進程上下文之外的其他代碼中分配記憶體. 從不睡眠.
kmalloc 能夠處理的最小分配是 32 或者 64 位元組, 依賴系統的體系所使用的頁大小.
kmalloc 能夠分配的記憶體塊的大小有一個上限.kmalloc最多隻能開闢大小為32XPAGE_SIZE的記憶體,一般的PAGE_SIZE=4kB,也就是128kB的大小的記憶體。如果大於這個,應該用vmalloc,或者用get_free_pages直接申請頁
kmalloc和get_free_page申請的記憶體位於實體記憶體映射地區,而且在物理上也是連續的,它們與真實的物理地址只有一個固定的位移,因此存在較簡單的轉換關係,virt_to_phys()可以實現核心虛擬位址轉化為物理地址:將虛擬位址減去3G(PAGE_OFFSET=0XC000000)
kmalloc和vmalloc的區別
• vmalloc()與 kmalloc()都可用於分配記憶體
• kmalloc()分配的記憶體處於3GB~high_memory之 間,這段核心空間與實體記憶體的映射一一對應,vmalloc()分配的記憶體在 VMALLOC_START~4GB之間,這段非連續內 存區映射到實體記憶體也可能是非連續的
• 在核心空間中調用kmalloc()分配連續物理空間,而調用vmalloc()分配非物理連續空間。vfree
• 把kmalloc()所分配核心空間中的地址稱為核心邏輯地址, 把vmalloc()分配的核心空間中的地址稱 為核心虛擬位址
• vmalloc()在分配過程中須更新核心頁表
winodws
windows在記憶體使用量上進行了嚴格的控制,如果不遵守level,就可能造成系統不穩定,並且這種bug很難調試。所有開發時必須對分配非常瞭解。相對linux界限較為明顯,其實大同小異。不同的中斷層級調用的分頁/非分頁是不一樣的,如這段話:中斷處理常式、tasklet以及核心定時器中這種情況下current進程不該睡眠,驅動程式該使用GFP_ATOMIC.
kmalloc 類似於 win非分頁,雖然一個參數,但是有本質的差別
vmalloc 類似於 win分頁
linux的 vmalloc()和window的分頁記憶體有相似之處(個人認為),vmalloc是從實體記憶體之後開始進行映射的,隨時可能被缺頁中斷。
核心空間中,從3G到vmalloc_start這段地址是實體記憶體映射地區(該地區中包含了核心鏡像、物理頁框表mem_map等等),比如我們使用
的 VMware虛擬系統記憶體是160M,那麼3G~3G+160M這片記憶體就應該映射實體記憶體。在實體記憶體映射區之後,就是vmalloc地區。對於 160M的系統而言,vmalloc_start位置應在3G+160M附近(在實體記憶體映射區與vmalloc_start期間還存在一個8M的gap 來防止躍界),vmalloc_end的位置接近4G(最後位置系統會保留一片128k大小的地區用於專用頁面映射)