1 Makefile文件格式
2.4内核下,直接设置好内核源文件路径(gcc的-I选项设置)就可以编译module代码,但2.6内核需要先make linux+make modules+make modules_install,之后在/lib/modules/内核发行号/下就有内核代码树,然后编写如下的Makefile即可编译(文件名必须是Makefile而不能是makefile)
obj-m :=driver.o #要输出的驱动名
KDIR=/lib/modules/$(shell uname -r)/build #build其实是一个符号连接,指向内核代码树位置
PWD=$(shell pwd) #当前path
modules:
$(MAKE) -C $(KDIR) M=$(PWD) modules #这行我没看懂什么意思,以后有时间再慢慢看
clean:
$(RM) *.o *.ko *.symvers *.mod.c #删除所有临时文件和输出文件
2 MOD_INC_USE_COUNT和MOD_DEC_USE_COUNT的使用
2.4内核下module.h已经有这两个宏,2.6已经没有了(FC3,其他核没去看),需要自己定义如下:
#dfine MOD_INC_USE_COUNT try_module_get(THIS_MODULE)
#define MOD_DEC_USE_COUNT module_put(THIS_MODULE)
3 在内核代码中替换掉printk()
在有些内核中,printk()无法实现在console输出信息(运行了klogd,syslogd或者printk()优先级太低),可以使用以下方法直接输出到console中:
current代表当前进程的一个指针(struct task_struct*),在2.4下包含struct tty_struct *tty指针,调用tty->write()即可实现输出信息到console中,但在2.6内核中,current没有包含tty指针,而是包含一个struct signal*signal指针,该指针包含tty指针,代码如下:
void print_string_2_tty(char*str)
{
#if LINUX_IS_V2.4
struct tty_struct *ts=current->tty;
#else
struct tty_struct *ts=current->signal->tty;
#endif
if(tty&&tty->driver)
{
tty->driver->write(ts,0,str,strlen(str));
}
}