昨天咱们开始了内核的分析,网上有不少人是用用源码直接分析,这样形成的问题是,你们以为很枯燥很难理解,从某种意义上来讲linux系统自己就是由一个个模块构成的,因此我会结合内核模块的设计,去分析内核,从而达到对linux内核的理解。git
今天咱们会分析到如下内容:github
1. Linux内核模块简介vim
2. 简单内核模块实现数组
1. 何为内核模块工具
在上一篇博文中咱们先经过内核配置,在配置的过程当中咱们对内核的组件进行了选择(固然这个选择决定了咱们内核的大小),而后才生成了咱们最终的内核,那么咱们若是想添加组件,怎么办?学习
最笨的方法是对内核进行从新配置,而后在从新编译。这样的话岂不是说我加一个组件就得从新编译内核,这显然不是很科学的方法,其实咱们的linux内核提供在运行时可进行扩展的特性,这意味着当系统启动并运行时,咱们能够向内核添加或移除部分功能。ui
咱们在运行时添加到内核中的代码就被成为动态可加载内核模块,咱们简称为内核模块。spa
2. 内核模块的相关操做
a) 加载内核模块:insmod
b) 卸载内核模块:rmmod
c) 查看内核模块:lsmod
3. 模块声明
a) MODULE_LICENSE(“GPL”):内核能够识别的许可证有GPL(任意版本GNU通用公共许可证)、GPL v2等
b) MODULE_AUTHOR(“做者”):声明做者信息能够不用
c) MODULE_VERSION(“版本”):声明版本信息也能够不用
d) MODULE_DESCRIPTION(“功能描述”):声明模块功能,可不用
4. 模块参数
咱们能够在加载内核模块的时候向其传递参数,以让同一代码达到不一样的效果。固然咱们的参数必须用module_param宏来声明具体以下:
1 module_param(name,type,perm)
a) name:变量名
b) type:数据类型内核支持模块参数类型有:bool、invbool(bool的发转,true变为false,false变为true)、charp(char类型指针值)、int、long、short、uint、ulong、ushort、
c) perm:常见的访问许可值一般为S_IRUGO和S_IWUSR。一般状况下将他们按位或
同时咱们也能够用下面的宏声明数组:
5. 模块符号导出
当一个模块要使用另外一个模块的函数(变量)的时候,要使用EXPORT_SYMBOL(符号名)或者EXPORT_SYMBOL_GPL(符号名)来申明。
注:EXPORT_SYMBOL_GPL()只适用于遵循GPL协议的模块
l 简单内核模块实现
想必你们都记得咱们在学习某种语言的时候,写的第一个程序大部分都是输出hello world,因此我接下来用咱们刚才介绍的内核模块去完成hello world。
1. 内核模块编写
经过上面部份内容的介绍,要完成第一内核模块不是很难,下面是本身的代码。
1 #include<linux/init.h> 2 #include<linux/module.h> 3 MODULE_LICENSE("GPL"); 4 staticint hello_init(void) 5 { 6 printk("<0> hello world\n"); 7 return0; 8 } 9 staticvoid hello_exit(void) 10 { 11 printk("<0> goodbye\n"); 12 } 13 module_init(hello_init);//该宏在模块的目标代码中增长一个特殊的段,用于说明内核初始化函数所在的位置 14 module_exit(hello_exit);//跟上面的宏对立
2. Makefile编写
Makefile的编写也比较简单,要注意的地方代码中已经说明。
1 obj-m := hello.o 2 DIRS :=/smbshare/linux-2.6.39///此处路径为内核源码路径,该内核源码必需要通过编译,否则会报错 3 all: 4 make -C $(DIRS) M=$(PWD) modules 5 clean: 6 rm -Rf*.o *.ko *.mod.c *.order *.symvers
通过了上面两个步骤,咱们而后编译加载而后卸载咱们的模块进行试验。
编译:
加载:
查看:
卸载:
3. Printk函数简介
printk函数为内核打印函数,其和printf函数功能相似,不过比printf多了打印权限一共有8个级别,printk的日志级别定义以下(在include/linux/kernel.h中):
1 #define KERN_EMERG 0 //紧急事件消息,系统崩溃以前提示,表示系统不可用 2 #define KERN_ALERT 1 //报告消息,表示必须当即采起措施 3 #define KERN_CRIT 2 //临界条件,一般涉及严重的硬件或软件操做失败 4 #define KERN_ERR 3 //错误条件,驱动程序经常使用KERN_ERR来报告硬件的错误 5 #define KERN_WARNING 4 //警告条件,对可能出现问题的状况进行警告 6 #define KERN_NOTICE 5 //正常但又重要的条件,用于提醒 7 #define KERN_INFO 6 //提示信息,如驱动程序启动时,打印硬件信息 8 #define KERN_DEBUG 7 //调试级别的消息
今天的内容比较简单,只是对内核模块有了一个初步的了解,因此我今天在给你们推荐一个比较好用的工具,叫作exvim其将好多vim的工具进行了集成,我的感受十分方便,就是换电脑什么的也不怕本身的配置丢失了。贴一张本身使用的图,你们有兴趣的能够去http://exvim.github.io/ 了解。