
本文概述
内核模块(Kernel Module)是嵌入式Linux工程师的基本功,也是面试必考题。面试官想听的不是背一个hello模块模板,而是你懂不懂模块机制的本质——它和内置驱动有什么区别、模块生命周期(加载/初始化/退出/卸载)、module_init与module_exit、编译方式(in-tree/out-of-tree)、insmod与modprobe的依赖处理,以及调试手段(dmesg、sysfs、/proc)。本文从“模块是动态加载的驱动单元”讲起,给出模块骨架与Makefile写法,再讲加载卸载、依赖、符号导出与常见坑,强调内核版本、头文件路径和编译环境决定具体写法。
核心要点
内核模块是可在运行时加载/卸载的驱动单元,与编译进内核的驱动各有适用场景
模块生命周期:module_init→probe/初始化→module_exit,对应加载和卸载
out-of-tree模块用Makefile+Kbuild编译,依赖目标内核的构建环境与头文件
insmod直接加载指定模块,modprobe处理模块依赖与配置(.ko路径、依赖关系)
dmesg、/proc、sysfs是模块调试与验证的主要途径
模块并发、引用计数、符号导出(EXPORT_SYMBOL)是写模块必须处理的工程细节
面试官考察点
考察点拆解
面试官问内核模块,重点考察:第一,你懂不懂模块机制的原理,而不是只会抄hello.c;第二,你会不会写Makefile做out-of-tree编译,并理解为什么要对着目标内核的Kbuild;第三,你懂不懂加载卸载、依赖、符号导出这些机制,遇到insmod失败能不能定位;第四,你有没有在真实板子上编译和调试过,而不是只在电脑上跑。
追问方向:module_init和module_exit干什么、insmod和modprobe区别、模块和内置驱动的取舍、模块参数、符号导出、insmod报错怎么排查。
回答思路
答题主线
建议按“模块本质 → 骨架代码 → 编译 → 加载与依赖 → 调试与坑”来答,先讲清为什么用模块,再落到怎么写。
先讲模块的本质:运行时加载/卸载,和内置驱动的区别。
讲骨架:module_init/module_exit、license、作者信息。
讲编译:Makefile + Kbuild,out-of-tree。
讲加载:insmod/modprobe、依赖、dmesg、符号。
参考回答
我先讲内核模块的本质,再落到怎么写。
第一,内核模块是什么。内核模块是可以在系统运行时动态加载和卸载的驱动或功能单元。相比直接编译进内核(built-in),模块的好处是:开发调试时不用反复编译整个内核、可以按需加载省内存、便于分发。缺点是启动时若未加载需要额外管理加载过程。做驱动开发时,模块是调试驱动的主要方式。
第二,模块骨架。一个基本模块包含:
module_init(func):指定加载时执行的初始化函数,一般在里面注册设备、分配资源、创建proc/sysfs节点;
module_exit(func):指定卸载时执行的清理函数,释放资源、注销设备;
MODULE_LICENSE:声明许可证,缺了会有taint警告;
可选MODULE_AUTHOR/MODULE_DESCRIPTION等元信息。
初始化函数里可以调用注册接口(如register_chrdev、platform_driver_register)把驱动挂到内核。
第三,编译。out-of-tree模块用Makefile调用内核Kbuild:
obj-m += mymod.o all: make -C $(KDIR) M=$(PWD) modules
其中KDIR要指向目标板对应内核的源码或构建目录,头文件、配置和模块版本要和运行内核匹配,否则insmod会报version magic不匹配。所以编译环境必须对准目标内核,不能随便在宿主机编一个就以为能用。
第四,加载与依赖。
insmod mymod.ko:直接加载指定模块文件,不处理依赖,适合单个模块;
modprobe mymod:按模块名加载,会处理依赖、参数和配置文件,推荐用于有依赖的场景。
模块间依赖通过符号引用体现:一个模块用了另一个模块EXPORT_SYMBOL导出的符号,加载时就要先加载被依赖的模块。加载结果用dmesg查看,卸载用rmmod。
第五,调试与坑。常见问题:
insmod失败:先看dmesg报错(版本不匹配、符号找不到、资源冲突、注册失败),逐一排查;
引用计数:设备被占用时rmmod会失败,说明模块还在被引用;
并发与锁:模块内并发访问要用锁保护,卸载时可能有竞态,需要正确同步。
调试时我会在init/exit加printk(用dev_info/pr_info)输出关键步骤,配合dmesg定位到哪一步失败。

扫码关注





























