内核模块的原理以及其模块编写.doc
《内核模块的原理以及其模块编写.doc》由会员分享,可在线阅读,更多相关《内核模块的原理以及其模块编写.doc(4页珍藏版)》请在三一文库上搜索。
1、内核模块的原理以及其模块编写HelloWorld内核开始断断续续学习内核,大概半年了,多少开始对内核有点感悟了,但是对于这个庞然大物我显得很渺小,在枯燥的内核源码之中似乎没有一点点成功的喜悦,因此我选择学习内核模块编程,通过编写一些内核模块来体验那一点点小小的成就感吧!什么是内核模块内核模块是具有独立功能的程序。它可以被单独编译,但是不能单独运行,它的运行必须被链接到内核作为内核的一部分在内核空间中运行。最简单的内核模块#include /所有模块都必须包含的头文件#include /一些宏定义,例如这里的KERN_INFOint init_module(void) printk(KERN_I
2、NFO Hello world 1.n); /* * 返回非0表示模块初始化失败,无法载入 */ return 0; void cleanup_module(void) printk(KERN_INFO Goodbye world 1.n); /一个模块至少需要两个函数,一个初始化函数这里是init_module在载入内核的时候调用, /一个结束函数,这里是cleannup_module在从内核中注销的时候调用一个Makefile来编译这个内核模块obj-m += hello-1.oall: make -C /lib/modules/$(shell uname -r)/build M=$(PW
3、D) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean注意:本文所有环节都是基于Centos6.5下测试OK,你可能在有的书上看见Makefile是这样写的make -C /usr/src/linux-headers-$(shell uname -r) M=$(PWD) modules 其实/lib/modules/$(shell uname -r)/build 这个路径就是上面路径的一个软链接 rootlocalhost 2.6.32-431.el6.x86_64# ls -al build
4、lrwxrwxrwx. 1 root root 44 Mar 16 05:26 build - /usr/src/kernels/2.6.32-504.12.2.el6.x86_64/编写好makefile文件后,使用make进行编译,编译完就出现一个.ko的文件,这个就是内核模块,需要载入运行载入内核模块进行运行载入内核模块的方法有很多比如: modprobe 和 insmod前者会分析模块的依赖关系,并且会去指定路径查找内核模块载入,而后者需要指定内核模块的绝对路径进行载入并且不解决模块的依赖关系。这里我们使用insmod来载入内核模块,使用rmmod卸载内核模块 rootlocalhos
5、t kernel_module# insmod hello-1.ko使用dmes查看内核模块的输出Hello world 1.卸载内核模块 rootlocalhost kernel_module# rmmod hello-1 dmesg查看输出Goodbye world 1.内核模块编程和应用程序编程的异同内核模块编程是不能去使用标准库(比如malloc free等)和一些第三方的库内核模块编程是没有内存保护的,如果内存访问错误,就会出现oops错误内核模块编程是没有main函数的,只有一个初始化函数,和一个提出函数内核模块编程需要使用内核提供的头文件和API内核模块编程的标准输出是输出到文件
6、,而不是输出到屏幕内核模块编程的debug是不能使用gdb来进行调试的。内核模块进阶内核模块的编程不仅仅是上面的一个HelloWorld,内核模块编程还有一些更高级的写法,下面会一一介绍:去掉init_module/cleanup_module在上面的HelloWorld模块中,你会发现初始化函数和退出函数好像是固定的名称,那么有没有办法自己自定义名称呢其实是可以的,你可以自己自定义名称,然后进行注册即可(注册其实就是做了一个函数指针的赋值而已)下面是自定义名称的写法:/不需要固定内核模块的初始化函数的名字和结束的名字#include #include #include static int
7、hello_2_init(void) printk(KERN_INFO Hello,world 2n); return 0; static void hello_2_exit(void) printk(KERN_INFO Goodbye,world 2n); /这两个函数来注册模块初始化和模块结束module_init(hello_2_init); module_exit(hello_2_exit);_init/_initdata/_exit在有的内核模块编程的书籍或者介绍内核模块编程的博客中,你或许会发现有这样的一些特殊关键字_init ,initdata ,_exit等等,其实这些都是gc
8、c的扩展属性:_init宏最常用的地方是驱动模块初始化函数的定义处,其目的是将驱动模块的初始化函数放入名叫.init.text的输入段。当内核启动完毕后,这个段中的内存会被释放掉供其他使用。_initdata宏用于数据定义,目的是将数据放入名叫.init.data的输入段。其它几个宏也类似。模块描述信息可以使用modinfo去查看一个模块的模块信息,下面是自己编写的模块和系统自带的模块的两个模块信息的对比rootlocalhost kernel_module# modinfo hello-1.kofilename: hello-1.kosrcversion: 0D3956C127A907CC9
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 内核 模块 原理 及其 编写
链接地址:https://www.31doc.com/p-3389358.html