kmalloc、vmalloc、malloc的区别
簡單的說:
?
詳細的解釋:
????? 對于提供了MMU(存儲管理器,輔助操作系統進行內存管理,提供虛實地址轉換等硬件支持)的處理器而言,Linux提供了復雜的存儲管理系統,使得進程所能訪問的內存達到4GB。
????? 進程的4GB內存空間被人為的分為兩個部分--用戶空間與內核空間。用戶空間地址分布從0到3GB(PAGE_OFFSET,在0x86中它等于0xC0000000),3GB到4GB為內核空間。
????? 內核空間中,從3G到vmalloc_start這段地址是物理內存映射區(qū)域(該區(qū)域中包含了內核鏡像、物理頁框表mem_map等等),比如我們使用 的 VMware虛擬系統內存是160M,那么3G~3G+160M這片內存就應該映射物理內存。在物理內存映射區(qū)之后,就是vmalloc區(qū)域。對于 160M的系統而言,vmalloc_start位置應在3G+160M附近(在物理內存映射區(qū)與vmalloc_start期間還存在一個8M的gap 來防止躍界),vmalloc_end的位置接近4G(最后位置系統會保留一片128k大小的區(qū)域用于專用頁面映射)
????? kmalloc和get_free_page申請的內存位于物理內存映射區(qū)域,而且在物理上也是連續(xù)的,它們與真實的物理地址只有一個固定的偏移,因此存在較簡單的轉換關系,virt_to_phys()可以實現內核虛擬地址轉化為物理地址:
?? #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
?? extern inline unsigned long virt_to_phys(volatile void * address)
?? {
?????? return __pa(address);
?? }
上面轉換過程是將虛擬地址減去3G(PAGE_OFFSET=0XC000000)。
與之對應的函數為phys_to_virt(),將內核物理地址轉化為虛擬地址:
?? #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
?? extern inline void * phys_to_virt(unsigned long address)
?? {
?????? return __va(address);
?? }
virt_to_phys()和phys_to_virt()都定義在include/asm-i386/io.h中。
而vmalloc申請的內存則位于vmalloc_start~vmalloc_end之間,與物理地址沒有簡單的轉換關系,雖然在邏輯上它們也是連續(xù)的,但是在物理上它們不要求連續(xù)。
我們用下面的程序來演示kmalloc、get_free_page和vmalloc的區(qū)別:
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
MODULE_LICENSE("GPL");
unsigned char *pagemem;
unsigned char *kmallocmem;
unsigned char *vmallocmem;
int __init mem_module_init(void)
{
//最好每次內存申請都檢查申請是否成功
//下面這段僅僅作為演示的代碼沒有檢查
pagemem = (unsigned char*)get_free_page(0);
printk("<1>pagemem addr=%x", pagemem);
kmallocmem = (unsigned char*)kmalloc(100, 0);
printk("<1>kmallocmem addr=%x", kmallocmem);
vmallocmem = (unsigned char*)vmalloc(1000000);
printk("<1>vmallocmem addr=%x", vmallocmem);
return 0;
}
void __exit mem_module_exit(void)
{
free_page(pagemem);
kfree(kmallocmem);
vfree(vmallocmem);
}
module_init(mem_module_init);
module_exit(mem_module_exit);
我們的系統上有160MB的內存空間,運行一次上述程序,發(fā)現pagemem的地址在0xc7997000(約3G+121M)、kmallocmem 地址在0xc9bc1380(約3G+155M)、vmallocmem的地址在0xcabeb000(約3G+171M)處,符合前文所述的內存布局。
總結
以上是生活随笔為你收集整理的kmalloc、vmalloc、malloc的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: misc_register、 regis
- 下一篇: DRAM、SRAM、SDRAM、DDRS