最近对LInux驱动程序有点感兴趣,找了本LINUX DEVICE DRVERS,读了前面的内核概述,就在机子上试了试书中的Hello World的程序。结果编译失败,才发现这本书有点老(学校图书馆借的,没辙,奖学金也不发,凑合看吧),里面写的是2.0内核模块框架。
网上查了查,终于知道了2.6内核模块的框架。再此记录下来。
hello.c
#include < linux / module.h >
MODULE_LICENSE( " GPL " ) /* 模块使用的协议 据说是2.6中必须有 */
/* 自己定义的模块初始化函数*/
static int hello_init( void ) {
printk(KERN_ALERT"hello");
return 0;
}
/* 自己定义的模块清除函数 */
static void hello_cleanup( void ) {
printk(KERN_ALERT"googbye hello");
}
/* 注册初始化函数 */
module_init(hello_init);
/* 注册清除函数 */
module_exit(hello_cleanup);
与2.0内核相比,初始化和清除函数的注册方法不一样了,2.0中是内核定义好的函数名称int init_module(void);和void cleanup_module(void); 2.6中则可以自定义函数了,由module_init和module_exit注册。
下面就是编译模块了,2.0都是一个命令搞定,2.6在网上查多是要写个Makefile,我觉得搞懂Makefile命令行也能搞定。有时间再说了。
Makefile
KERNEL_DIR ? = / lib / modules /$( shell uname -r )/ build
PWD : = $( shell pwd )
default:
$( MAKE ) -C $( KERNEL_DIR ) M =$( PWD ) modules
KERNEL_DIR那个目录其实就是指向内核源码。
PWD得到你当前内核的模块目录,猜测是交给内核源码的Makefile去编译我们的内核。
以前学过大概的Makefile,看来又要复习复习Makefile了。。。。动不动就忘。。。。。
下面也贴出2.0内核的框架吧。做好人要做到底。
#include < linux / module.h >
int init_module( void ) {
printk("<1>Hello");
return 0;
}
void cleanup_module( void ) {
printk("<1>goodbye hello");
}
gcc - c hello.c
忘记了还要测试一下。
使用root用户
insmod hello.ko
rmmod hello.ko
我的结果显示在/var/log/syslog当中了。估计和printk中的消息级别有关,还有就是syslog的配置有关了,这个就以后再研究了。睡觉了。。。。。(幸苦了半天也是总结前人的东西啊。。。以后要写出自己独有的)
还要提一下,在插入代码的时候没有c代码的格式,只能用c#,有点过分。