Table of Contents
Kernel Modules Versus Applications
Error Handling During Initialization
Module Driver Sample
模块化是Linux kernel driver的立身之本,几乎所有的device driver都是module driver,在kernel启动的时候动态加载。直接拿书里的例子看:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
上面的这个sample code只是简单展示module driver在安装卸载时会调用的函数。
无论多么复杂的device driver,都是这个骨架,module driver的init和exit,就是driver和kernel接触的第一次和最后一次。module driver在init做完以后,其实就不干活了,躺在那里睡大觉。那么什么时候干活呢?driver的运行是基于event-driven模型的,就是说要有event过来,driver才会有事情做。
这很合理,我写了一个USB 设备的驱动,比如键盘,如果没有人使用键盘,那键盘驱动干啥活。虽然如此,在init的时候,driver也有很多事情可以做,主要是初始化相关的,比如注册设备,设置中断ISR,初始化设备等等。等初始化做完以后,device和driver的信息kernel就会记录下来,一旦有人使用了你的设备,驱动就会被调用。
如果driver被卸载,那么driver自己就要把init中申请的资源按序释放,这个非常重要,因为module driver的一大好处就是动态的加载和卸载,不用重启系统。如果init/exit没有做好,那driver很有可能出问题,甚至把kernel搞死。
来一张module driver被insmod以后在kernel中的描述图:
Kernel Modules Versus Applications
kernel mode driver和应用程序有很大的不同:
1. kernel mode driver无一例外都是事件驱动的,依赖于user mode或者kernel mode事件来触发操作,应用程序有的是,有的不是。
2. 应用程序的资源可以晚一点释放,甚至在退出时也不主动释放,因为OS会在进程结束的时候自动回收进程占用过得资源。而kenrel mode driver则必须在退出时谨慎的释放所有占用的资源。
3. 应用程序可以调用别的库中的函数,比如调用libc库中实现的函数;而module driver只能调用kernel中export出来的函数。(有些module driver可以主动export一些function出来给别的module用)
4. kernel 中没有float运算的支持,只能通过软件的方式来做。
5. 错误处理不同。应用程序出错,最多应用程序被kill,对系统和别的应用程序没有影响;如果kernel driver出了问题,至少当前的process挂了,严重点就是kernel panic,整个系统死掉,只能重启。
说到第五点,就要讨论user space和kernel space了。
User Space and Kernel Space
学过操作系统的人应该都了解,应用程序都运行在u