[經典]Linux核心中get_free_page、kmalloc和vmalloc函數的區別(樣本Module)

來源:互聯網
上載者:User

  對於提供了MMU(儲存管理器,輔助作業系統進行記憶體管理,提供虛真實位址轉換等硬體支援)的處理器而言,Linux提供了複雜的儲存管理系統,使得進程所能訪問的記憶體達到4GB。

  進程的4GB記憶體空間被人為的分為兩個部分--使用者空間與核心空間。使用者空間地址分布從0到3GB(PAGE_OFFSET,在0x86中它等於0xC0000000),3GB到4GB為核心空間。如所示:

  核心空間中,從3G到vmalloc_start這段地址是實體記憶體映射地區(該地區中包含了核心鏡像、物理頁框表mem_map等等),比如我們使用 的 VMware虛擬系統記憶體是160M,那麼3G~3G+160M這片記憶體就應該映射實體記憶體。在實體記憶體映射區之後,就是vmalloc地區。對於 160M的系統而言,vmalloc_start位置應在3G+160M附近(在實體記憶體映射區與vmalloc_start期間還存在一個8M的gap 來防止躍界),vmalloc_end的位置接近4G(最後位置系統會保留一片128k大小的地區用於專用頁面映射),如:

  kmalloc和get_free_page申請的記憶體位於實體記憶體映射地區,而且在物理上也是連續的,它們與真實的物理地址只有一個固定的位移,因此存在較簡單的轉換關係,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之間,與物理地址沒有簡單的轉換關係,雖然在邏輯上它們也是連續的,但是在物理上它們不要求連續。

  我們用下面的程式來示範kmalloc、get_free_page和vmalloc的區別:

  #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的記憶體空間,運行一次上述程式,發現pagemem的地址在0xc7997000(約3G+121M)、kmallocmem 地址在0xc9bc1380(約3G+155M)、vmallocmem的地址在0xcabeb000(約3G+171M)處,符合前文所述的記憶體布局。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.