第17章、设备与模块
17.1设备类型
1.块设备(blkdev):
寻址以块为单位,通常支持重定位操作。通过称为“块设备节点”的特殊文件来访问。
2.字符设备(cdev):
不可寻址,仅提供数据的流式访问。通过称为“字符设备节点”的特殊文件来访问。
3.网络设备(ethernet devices):
提供了对网络的访问。它不是通过设备节点来访问,而是通过套接字API这样的特殊接口来访问。
17.2 模块
17.2.1 Hello,World
(1)hello_init()函数是模块的入口点。
模块的所有初始化函数必须符合下面的形式:
Int my_init(void);
它可被标记为static类型。
(2)hello_exit()函数是模块的出口函数。
Exit函数负责对init函数以及在模块生命周期过程中所做的一切事情进行撤销工作,基本上就是清理工作。
模块的所有初始化函数必须符合下面的形式:
void my_exit(void);
它也可被标记为static类型。
17.2.2构建模块
构建模块的第一步是决定在哪里管理模块源码。
(1)放在内核源代码树中
(2)放在内核代码外
17.2.3安装模块
Make modules_install 构建命令用来安装编译的模块到合适的目录下,通常需要以root权限运行。
17.2.4产生模块依赖性
Linux模块之间存在依赖性。
17.2.5载入模块
载入模块最简单的方式是通过insmod命令,它做的就是请求内核载入模块。
Insmod module.ko(这里module.ko是要载入的模块名称)
卸载模块可以使用rmmod命令。
Rmmod module
17.2.6管理配置选项
配置选项的第一行定义了该选项所代表的配置目标;
第二行声明编译选项类型;
第三行指定了该选项的默认选项。
17.2.7模块参数
(1)定义一个模块参数可以通过宏module_param()完成:
Module_param(name,type,perm);
(2)必须在使用该宏前定义变量
(3)通常,需要用一个charp类型来定义模块参数(一个字符串)
17.2.8导出符号表
在内核中,导出内核函数需要使用特殊的指令:EXPORT_SYMBOL()和EXPORT_SYMBOL_GPL().
导出的内核函数可以被模块调用,而未导出的函数模块则无法被调用。
导出符号,只需要在声明函数后,紧跟上EXPORT_SYMBOL()指令。
17.3 设备模型