1.  模块的加载和测试

Linux内核模块是为了解决单体内核的不足而提出来的一种技术,所以,它必须要能够动态的加载和删除。当我们获得hello.ko的内核模块之后,我们就可像内核中加载了,但是在加载之前,我们必须注意一个非常重要的问题:

我们解释Makefile的时候说明,我们的内核模块是为$(KERNELDIR)这个内核服务的,所以我们不能将编译好的内核模块胡乱的加载到一个运行的内核里面,否则就会出现牛头不对马嘴的笑话。这也是我们众多学员容易犯下的错误之一,经常拿为虚拟机里RHEL5编译的内核模块往ARM开发板上加载,或者反之。所以,请大家在试验前一定要用file hello.ko查看一下这个内核模块是ARM版本的还是X86版本。同样的, 即使是同样一个版本,如果对内核的配置不一样,也可能会导致不能加载的情况,所以,如果出现加载不进的情况,请首先检查内核模块的file属性,然后检查是否是内核配置不匹配倒置的,总之,运行的内核一定要和编译内核模块的时候指定的内核是一致的。

加载内核使用的命令是insmod,例如

#insmod hello.ko

只有Linuxroot用户才有权限向内核中添加模块,请大家思考一下为什么?

    如果没有出现出错信息,就表明加载成功,可以通过lsmod查看当前运行的内核中加载的模块情况。属性分别表示模块的大小,以及被几个模块使用,分别是那些模块。

可能当前的系统里面动态加载的模块过多,此时你可以用lsmod |grep hello来查找。

    rmmod这个命令可以让我们从内核中动态的卸载模块,如下:

    #rmmod hello      #注意这里不需要ko,而且可在任何目录下操作,2.6支持带有ko

    如果我们在模块的初始化函数和清除函数中有打印信息的话,可能会在控制台上显示出来,或者通过dmesg可以查看到自开机以来所有的缓冲的打印信息。

    那么在insmodrmmod的时候到底发生了什么呢?

    这里实际上包含两个重要的过程,我们知道内核模块是kernel object,也就是说它仅仅是目标代码,没有经过链接。所以在insmod的第一个过程是解析内核模块外部符号。这类似于一个链接的过程,如果有不能解析的符号,就会报unsolved symbol,此时模块加载会失败。

    外部符号被正确的解析后,就开始加载内核模块,就会调用在module_init()中声明的初始化函数,只有当初始化函数返回非负值,模块才能正确的被加载。

    对于rmmod也有两个过程, 首先检查是否有模块依赖于此模块,也就是说只有当lsmod查看到此模块used一栏的值为0时,模块才能被安全的卸载。卸载的时候调用module_exit()中声明的清除函数,释放占有的资源。

Logo

更多推荐