kernel version 2.6.29
核心函式常常需要臨時分配一塊任意大小的實體地址連續的記憶體空間. 所以先介紹核心中兩個分配實體地址連續的記憶體空間的api.
kmalloc
由於採用了slub作為預設記憶體分配器, 所以 kmalloc 工作於 slub 分配器之上。核心初始化時,建立一組共 13 個通用物件的緩衝區。kmalloc_caches 陣列存放了這些緩衝區的 kmem_cache 資料結構(kmalloc_sizes.h)。由於 kmem_cache 資料結構是通過 kmalloc 來分配的,故而只能用靜態分配的 kmem_cache 結構陣列來描述通用物件的緩衝區。其中 kmalloc_caches[0] 代表的緩衝區專門分配 kmem_cache_node 結構。kmalloc_caches[1] 緩衝區物件大小為64,kmalloc_caches[2] 緩衝區物件大小為192,其餘第 i(3-12)號緩衝區物件大小為 2^i。如果請求分配超過物理頁面大小(4096)的物件,直接呼叫頁框分配器__get_free_pages.
__get_free_pages
__get_free_pages 採用的記憶體分配方式為buddy演算法. 所以一般分配的資料大小為故是2 ^ order個頁面大小. 核心中定義了乙個巨集 max_order, 表示一次請求能分配的最大物理頁數不能 >= max_order, 也就是最大可以分配到的記憶體塊. 2.6.29.6 中max_order為 11 即最大分配大小為 ( 2 ^ 10 ) * 4096 = 4m.
如果我們需要在核心中分配4m以上的連續物理記憶體,怎麼辦,當前核心對應的方法還有兩個:
1> 使用static或全域性變數陣列, 直接定義變數大小為所需資料大小.
例:
static char buffer[ 512 * 1024 * 1024 ];
定義512m大小陣列. 不過此方法應用到模組中話, 會導致載入模組速度奇慢.
2> 使用alloc_bootmem系列api在start_kernel呼叫mem_init()之前申請所需的連續大記憶體. 或新增一核心引數根據需要來調整資料緩衝大小. 不過此段記憶體也就永久保留, 除非直接引用所分配的記憶體位址. 例:
以下定義一核心引數pf_buf_len=nn[kmg],可定製分配的記憶體大小. 並export位址與長度資訊.
unsigned long long pf_buf_len = 0x0; export_symbol( pf_buf_len ); void *pf_buf_addr = null; export_symbol( pf_buf_addr ); static int __init pf_buf_len_setup(char *str) //printk( kern_info "pf_buf_len: allocating %llu bytes/n", size ); // 分配記憶體 pbuff = alloc_bootmem( size ); if ( likely( null != pbuff ) ) printk( kern_err "pf_buf_len: allocated %llu bytes fail./n", size ); out: return 1; } __setup( "pf_buf_len=", pf_buf_len_setup);
參考:
linux slab 分配器剖析
linux slub 分配器詳解
注:
還有一核心引數memmap=nn[kmg]$ss[kmg] 可以將ss位置起始一段大小為nn的記憶體保留,並不會將其對映到位址空間內. 一般在檢測bad ram時有用,可以直接跳過bad ram實體地址空間段進行對映. 驅動中也可以直接使用其實體地址,常用的驅動是framebuffer驅動 driver/video/sgivwfb.c
linux核心中分配4M以上大記憶體的方法
在核心中,kmalloc能夠分配的最大連續記憶體為2的 max order 1 次方個page 參見alloc pages函式,if unlikely order max order return null page的大小一般是4k bytes,max order預設定義為11,所以如果不修改核心,...
Linux核心中分配4M以上大記憶體的方法
在linux核心中,kmalloc能夠分配的最大連續記憶體為2的 max order 1 次方個page 參見alloc pages函式,if unlikely order max order return null page的大小一般是4k bytes,max order預設定義為11,所以如果不...
在核心中獲取pmem裝置的虛擬位址
pmem的配置可以參考沒有的選項可以不選。不要少選了,不然沒有pmem裝置滴。配置完之後,想要在核心中獲取pmem的虛擬位址,就先來個系統呼叫吧。我的核心是4.4.4。所以在arch x86 entry syscall 64.tbl中新增編號,順序新增即可。然後在include linux sysc...