本文简单描述Linux模块构建中相关函数、宏、头文件等,供后续快速查看。参考自《Linux设备驱动程序(第三版)》第二章。
头文件
#include <linux/sched.h>
最重要的头文件中的一个。这个文件包含驱动程序使用的大多数内核 API 的定义, 包括睡眠函数和许多变量声明。
#include <linux/module.h>
必需的头文件. 它必须在一个模块源码中包含。
#include <linux/version.h>
包含所构造内核版本信息的头文件。
宏
LINUX_VERSION_CODE
整型宏, 在处理版本依赖的预处理条件语句下非常有用。
EXPORT_SYMBOL (symbol);
EXPORT_SYMBOL_GPL (symbol);
用来导出单个符号到内核的宏。第二个宏将导出的符号的使用限于GPL许可证下的模块。
MODULE_AUTHOR(author);
MODULE_DESCRIPTION(description);
MODULE_VERSION(version_string);
MODULE_DEVICE_TABLE(table_info);
MODULE_ALIAS(alternate_name);
在目标文件中添加关于模块的文档信息。
#include <linux/init.h>
module_init(init_function);
module_exit(exit_function);
宏定义, 声明一个模块的初始化和清除函数。
#include <linux/moduleparam.h>
module_param(variable, type, perm);
用来创建模块参数的宏, 用户可以在模块加载时( 或者对内建代码引导时)调整这些参数的值。类型可以是 bool, charp, int, invbool, short, ushort, uint, ulong, 或者 intarray。
标记
__init
__initdata
__exit
__exitdata
仅用于模块初始化或清除阶段的函数( __init 和 __exit )和数据 (__initdata 和 __exitdata)标记。标记为初始化的项目会在初始化结束后丢弃;而退出项目在内核未被配置为可卸载模块的情况下被丢弃。内核通过将相应的目标对象放置在可执行文件的特殊ELF断种而让这些标记起作用。
模块构建
obj-m
Makefile中使用的符号, 用来确定在当前目录中应构建哪些模块。
vermagic.o
内核源码目录中的一个目标文件, 它描述模块的构造环境。
模块目录
/sys/module
/proc/modules
/sys/module 是sysfs 目录层次结构中包括当前已加载模块的目录。 /proc/moudles 是早期用法, 只在单个文件中包括这些信息,其中包括了模块名称, 每个模块占用的内存总量以及使用计数等。每一行滞后还追加有额外的字符串,用来指定模块的当前活动标志。
内核函数
#include <linux/kernel.h>
int printk(const char * fmt, …);
在内核中打印信息不能使用printf,需要使用printk。
模块变量
struct task_struct *current;
当前进程。
current->pid
current->comm
进程 ID 和 当前进程的命令名。
模块工具
insmod
modprobe
rmmod
用户空间工具, 加载模块到运行中的内核以及去除它们。