二 Linux设备驱动程序——建立和运行模块( 三 )


所有的模块参数都应该在源文件中给定一个默认值 。
1、模块支持的模块参数:
模块中的钩子可让我们自定义类型
2、访问许可值:
使用中定义的值
大多数情况下不应该让模块参数是可写的
3、例程
hello.c
#include #include #include MODULE_LICENSE("Dual BSD/GPL");static char *hello_str = "hello";static int hello_cnt = 2;module_param(hello_str, charp, S_IRUGO);module_param(hello_cnt, int, S_IRUGO);static int hello_init(void){printk(KERN_ALERT "Hello, world\n");printk("%s, %d\n", hello_str, hello_cnt);return 0;}static void hello_exit(void){printk(KERN_ALERT "Goodbye, cruel world\n");}module_init(hello_init);module_exit(hello_exit);
加载 hello 模块驱动,并查看打印信息
sudo insmod hello.kosudo dmesg
模块加载后可以在 /sys//模块名/ 目录下查看参数
cd /sys/module/hello/parameters/lscat hello_cntcat hello_str
九、在用户空间做
用户空间驱动的好处在于:
用户空间的设备驱动的方法有几个缺点,最重要的是:
十、快速参考
rmmod
用户空间工具,加载模块到运行中的内核以及去除它们 。
#
();
();
指定模块的初始化和清理函数的宏定义 。
函数( 和 )和数据( 和 )的标记,只用在模块初始化或者清理时间 。
#
最重要的头文件中的一个,这个文件包含很多驱动使用的内核 API 的定义,包括睡眠函数和许多变量声明 。
*;
当前进程 。
->pid
->comm
进程 ID 和 当前进程的命令名 。
obj-m
一个符号,内核建立系统用来决定当前目录下的哪个模块应当被建立 。
/sys/
/proc/
/sys/ 是一个 sysfs 目录层次,包含当前加载模块的信息 。/proc/ 是旧式的,那种信息的单个文件版本 。其中的条目包含了模块名,每个模块占用的内存数量,以及使用计数,另外的字串追加到每行的末尾来指定标志,对这个模块当前是活动的 。
.o
来自内核源码目录的目标文件,描述一个模块为之建立的环境 。
#
必需的头文件,它必须在一个模块源码中包含 。
#
头文件,包含在建立的内核版本信息 。
整型宏定义,对 #ifdef 版本依赖有用 。
();
();
宏定义,用来输出一个符号给内核 。第 2 种形式输出没有版本信息,第 3 种限制输出给 GPL 许可的模块 。
();
();
();
();
();
放置文档在目标文件的模块中 。
();
();
宏定义,声明一个模块的初始化和清理函数 。
#
(, type, perm);
宏定义,创建模块参数,可以被用户在模块加载时调整(或者在启动时间,对于内嵌代码) 。类型可以是 bool,charp,int,,short,,uint,ulong 或者。
#
int (const char * fmt, …);
内核代码的类似物 。