要想实现一个独立于Linux内核的磁盘高速缓存,就需要确定磁盘高速缓存的数据放到什么地方,因为在Linux中申请大块内存的不确定性和不稳定性,我们使用在开机时预留大块内存的方式,独立管理这块被保留的内存存放磁盘缓存数据;
在开机时预留大块内存,需要修改Linux内核的源代码文件(init/main.c),在内存初始化之前预留出一部分内存,我使用的内核版本是3.8.13,下面是需要修改的code:
char *iet_mem_virt;
unsigned int iet_mem_size=0x1000000;
unsigned long iet_mem_goal=0;
EXPORT_SYMBOL_GPL(iet_mem_size);
EXPORT_SYMBOL_GPL(iet_mem_virt);
EXPORT_SYMBOL_GPL(iet_mem_goal);
asmlinkage void __init start_kernel(void)
{
/*
* These use large bootmem allocations and must precede
* kmem_cache_init()
*/
setup_log_buf(0);
pidhash_init();
vfs_caches_init_early();
sort_main_extable();
trap_init();
/* rserve memory region for disk cache */
iet_mem_virt= alloc_bootmem(iet_mem_size);
mm_init();
/*
* Set up the scheduler prior starting any interrupts (such as the
* timer interrupt). Full topology setup happens at smp_init()
* time - but meanwhile we still have a functioning scheduler.
*/
sched_init();
}
alloc_bootmem(size)函数,在内存初始化之前,预留出size个字节的物理内存,返回虚拟内存的指针。
然后重新编译内核,内核编译步骤我在这里不再赘述,自己百度一下。在使用重启编译的内核启动之后执行下面的命令:
lab@lab-OptiPlex-7010:~$ cat /proc/kallsyms |grep iet_mem
0000000000000000 r __ksymtab_iet_mem_goal
0000000000000000 r __ksymtab_iet_mem_size
0000000000000000 r __ksymtab_iet_mem_virt
0000000000000000 r __kcrctab_iet_mem_goal
0000000000000000 r __kcrctab_iet_mem_size
0000000000000000 r __kcrctab_iet_mem_virt
0000000000000000 r __kstrtab_iet_mem_goal
0000000000000000 r __kstrtab_iet_mem_virt
0000000000000000 r __kstrtab_iet_mem_size
0000000000000000 D iet_mem_size
0000000000000000 B iet_mem_goal
0000000000000000 B iet_mem_virt
lab@lab-OptiPlex-7010:~$ 如果可以执行的命令和上面一致,说明我们的准备工作成功了,我们以后在内核模块的编写中可以直接使用这三个symbol了,其中最重要的是iet_mem_virt, 它指向我们预留的16MB内存,OK,下课!
Linux内核预留内存技巧
本文介绍了一种在Linux内核启动过程中预留大块内存的方法,用于实现独立于内核的磁盘高速缓存。通过修改内核源代码,在内存初始化前预留指定大小的物理内存,并介绍了预留内存的具体步骤。
17万+

被折叠的 条评论
为什么被折叠?



