Linux模块构建与运行快速参考

本文简单描述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

用户空间工具, 加载模块到运行中的内核以及去除它们。