LDD读书实验笔记——构造和运行模块

来源:互联网 发布:c语言编菜单 编辑:程序博客网 时间:2024/05/16 09:03

本章主要是介绍性的东西为主,可写的东西不多,其中做了两个实验——hello world和带参数的模块,算是为驱动学习最简单的两个模块了。


这章的知识体系较散乱,也就胡乱记些了


版本依赖和平台依赖上,并不是很理解,但感觉也不是很重要,记得vermagic.o与这两者息息相关即可。

     不过在此节提及一个观点/忠告:尽量把条件编译放到尽量低层的宏和函数中去。


内核符号表,包含内核全部的变量和函数地址,是实现模块叠层的必要技术。一个模块可向外部导出符号。不是很理解,符号是指变量和函数吗?

    modprobe:若欲insmod的模块有依赖的模块未insmod,则自动将所有依赖的模块均insmod上。


__init和__exit标记,用于优化内核,被标记后的__init,在执行完后,就立即从内存中丢弃;而__exit则会被放在特殊的ELF段中。


初始化的思想:尽可能使模块运行起来,并尽可能的提供设备的功能。即任何非致命错误都不能让模块退出。关于退出时,资源释放的问题和应用程序无异。


最后关于用户空间编写驱动程序的优点:开发调试方便,对于内核运行也安全的多;缺点:依赖特权用户,运行速度慢,无法处理一些关键设备。


hello world的实验:

hello world调试过程中, 起初一直怀疑LDD书中的那个Makefile并不是完整的(是指编译上就不完整),但实际上make的-C选项会告诉编译器在-C后面的这个目录中查找内核代码树的顶层Makefile—其中有完整的变量定义和规则定义。

最后编译时出现了linux/bounds.h:没有那个文件或目录,最后参考这篇文章得以解决。


hellop的实验:

对于带参数的模块,系统不会对参数的内容做出任何检查,和应用程序一样,都是靠程序员自已完成的。但系统会检查声明的参数名称以及对输入格式有严格要求,例如:howmany = 10是错误的,等号两侧不可以有空格,否则系统无法解析参数。

另外,值得注意的是,参数除了整数和字符串,还可以是数组。


#include <linux/init.h>#include <linux/module.h>MODULE_LICENSE("Dual BSD/GPL");static char *whom;static int howmany;module_param( howmany, int, S_IRUGO );module_param( whom, charp, S_IRUGO );static int __inithello_init( ){    int     i;        for( i=0; i<howmany; ++i )        printk( KERN_ALERT "hello %s!~~\n", whom );    return 0;}static void __exithello_exit( ){    printk( KERN_ALERT "goodbye, cruel world\n");}module_init( hello_init );module_exit( hello_exit );