看了看模块编程,忽然神情恍惚,不知道写些什么,以下是立波梦话,如有雷同,纯属巧合。
- #include<linux/init.h>
- #include <linux/module.h>
- MODULE_LICENSE("Dual BSD/GPL");
- static int __init hello_init(void)
- {
- printk(KERN_ALERT "hello tmaclub");
- return 0;
- }
- static void __exit hello_exit(void)
- {
- printk(KERN_ALERT "goodbye tmaclub");
- }
- module_init(hello_init);
- module_exit(hello_exit);
#include
#include
init.h module.h在内核源码树的include/linux/目录下面,是生成内核模块所必须的,具体的init.h提供了初始化和清除函数;module.h包含了可装载模块需要的大量符号和函数定义。
MODULE_LICENSE("Dual BSD/GPL");
声明许可证,以免内核产生抱怨,具体可以了解linux的copyleft。
module_init(hello_init);
module_exit(hello_exit);
当我们装载和下载内核模块式,这两个函数被调用,进而可以调用我们的初始化和清除函数。
printk有点类似我们用户空间的printf,但是在内核里不可调用和依赖c库。有个很大的不同便是在使用printk是需要指定优先级,例如我们使用了KERN_ALERT.
printk的优先级如下,在内核目录下inxlude/linux/kernel.h下有记录:
- #define KERN_EMERG "<0>" /* system is unusable */
- #define KERN_ALERT "<1>" /* action must be taken immediately */
- #define KERN_CRIT "<2>" /* critical conditions */
- #define KERN_ERR "<3>" /* error conditions */
- #define KERN_WARNING "<4>" /* warning conditions */
- #define KERN_NOTICE "<5>" /* normal but significant condition */
- #define KERN_INFO "<6>" /* informational */
- #define KERN_DEBUG "<7>" /* debug-level messages */
__init __exit 标识使得当初始化和清除之后,腾出所占用的内存空间,属于一种优化选项。
说说makefile吧,在ldd中讲到其实只用obj := hello.o,但是这样在执行make命令时,需要加几个命令行参数。其中,-C用于制定内核makefile的路径,-M用于制定要编译的文件路径,都可以使用相对路径。当然,如果make工具如此天真,必然不可成大器。我们可以把这些参数写道makefile文件里,具体的不说了,我相信每个介绍驱动的书籍都有,呵呵,理解-C,-M命令,问题迎刃而解。
还有什么呢??linux内核一大利器:内核符号表;内核传参;这两项内容很重要,以后要经常用到。其中,内核符号表有点类似我们经常使用的动态链接库,例如我们在编写驱动过程中使用的很多接口就是内核通过内核符号表导出的。ldd中对这两项有非常深入的解释,我会写个小程序随后贴出。
在程序调试过程中,发现一个小问题,就是在加载模块式,printk在终端不输出(并不是打印日志级别低,这个我清楚),最后发现:我们使用的终端(xwindow)应该是伪终端,可以按ctrl+alt+Fx切换到相应的控制台下,便可实现printk的打印。当然在伪终端下,我们也可以采用dmesg命令看到内核的输出。
阅读(1695) | 评论(0) | 转发(0) |