深入浅出Flashcache(三)
前文简单介绍了block device和device mapper。有了这两个基础,再来看flashcache的代码,就容易理解多了。Flashcache是一个内核模块,要更清晰的理解代码,还需要了解一下内核模块编写的一些基础知识。好吧,虽然对于内核编程我完全是个门外汉,这里还是需要现学现卖下。所以这一篇还是不会切入正题,已经熟悉Linux内核模块的同学请忽略并耐心等待。
Linux内核支持动态的加载模块(Loadable Kernel Module,LKM)以完成某些特定的功能,模块编程需要按照一定的格式以便可以和内核交互。
5. 内核符号表
内核模块之间的交互需要通过特定的共享变量和函数,这些都需要输出到内核符号表。在模块编程中使用EXPORT_SYMBOL来进行定义。在内核中则使用了kernel_symbol结构来保存符号表信息。
# 内核编程基本上都需要包含如下三个头文件。 #include#include #include #内核符号表结构体 struct kernel_symbol { unsigned long value; #函数地址 const char *name; #函数名 }; # 导出符号的宏定义 #define EXPORT_SYMBOL(sym) __EXPORT_SYMBOL(sym, "") #define __EXPORT_SYMBOL(sym, sec) \\ extern typeof(sym) sym; \\ __CRC_SYMBOL(sym, sec) \\ static const char __kstrtab_##sym[] \\ __attribute__((section("__ksymtab_strings"), aligned(1))) \\ = MODULE_SYMBOL_PREFIX #sym; \\ static const struct kernel_symbol __ksymtab_##sym \\ __used \\ __attribute__((section("__ksymtab" sec), unused)) \\ = { (unsigned long)&sym, __kstrtab_##sym }
输出的符号表可以在/proc/kallsyms查看到。
6. 模块入口/退出函数
一般的c程序的入口函数是main,但模块的入口函数是module_init,退出函数则是module_exit。当内核启动或者执行insmod时执行module_init定义的函数,到内核关闭或者rmmod时执行module_exit定义的函数。
#define module_init(x) __initcall(x); #define module_exit(x) __exitcall(x);
当然,还有一些宏定义了模块的一些信息,如
7. 内存分配
内核中不能使用用户空间的malloc()和free()来分配/回收内存。而需要使用内核空间的内存分配/回收工作,常用的有kmalloc/kfree,基于slab内存分配算法:
void *kmalloc(size_t size, gfp_t flags) void kfree(const void *objp)
对于slab内存分配器,这里不再详细展开。通过/proc/slabinfo或者slabtop可以查看slab内存分配的一些情况。
另外,在内核中也不能使用用户态的printf来输出信息,而需要使用内核态的printk。
8. 模块工具
8.1 insmod
Linux模块编译好以后一般是.ko文件,通过执行insmod可以将编译好的模块加载到内核中。在装载内核模块时,用户可以向模块传递一些参数:
sudo insmod mod_name var=key
8.2 rmmod
rmmod则用来卸载已经加载到内核的模块
rmmod mod_name
8.3 lsmod
lsmod可以列出已经加载到内核中的模块
lsmod Module Size Used by nf_conntrack_ipv6 8785 1 aes_i586 7244 2 aes_generic 26755 1 aes_i586 ipt_MASQUERADE 1315 0 xt_state 930 2 ...
也可以通过/proc/modules来获取内核模块列表。
8.4 modinfo
查看某个模块的信息
$ modinfo raid0 filename: /lib/modules/2.6.36-ningoo/kernel/drivers/md/raid0.ko alias: md-level-0 alias: md-raid0 alias: md-personality-2 description: RAID0 (striping) personality for MD license: GPL srcversion: 2CFE19548162CD6E80EE58B depends: vermagic: 2.6.36-ningoo SMP mod_unload modversions CORE2
8.5 modprobe
modprobe是一个比较强大的工具,既可以列出已经安装的模块信息,也可以用来加载/卸载模块,并且能够处理同时将依赖的模块自动进行加载。
modprobe -l sudo modprobe -r mod_name sudo modprobe mod_name
/etc/modprobe.conf和/etc/modprobe.d/保存了一些modprobe可能用到的配置。
未完待续
参考:
[1] 2.6内核模块编程实例指导
[2] 小白学Linux之内核模块编程
建议继续学习:
- Ubuntu工作机使用FlashCache技术加速 (阅读:5343)
- 深入浅出Flashcache(一) (阅读:2428)
- 深入浅出Flashcache(五) (阅读:1906)
- 深入浅出Flashcache(二) (阅读:1871)
- 深入浅出Flashcache(四) (阅读:1869)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:NinGoo 来源: NinGoo.net
- 标签: Flashcache
- 发布时间:2012-02-05 23:28:42
- [70] Twitter/微博客的学习摘要
- [66] 如何拿下简短的域名
- [65] IOS安全–浅谈关于IOS加固的几种方法
- [64] find命令的一点注意事项
- [63] android 开发入门
- [63] Go Reflect 性能
- [61] 流程管理与用户研究
- [59] 图书馆的世界纪录
- [59] 读书笔记-壹百度:百度十年千倍的29条法则
- [59] Oracle MTS模式下 进程地址与会话信