1. 创建第一个内核模块
任务目标
在Android内核开发环境中,编写一个最小可加载的内核模块(.ko文件),实现模块加载时的初始化和卸载时的清理功能,并通过dmesg验证模块加载/卸载时打印的内核日志。
环境与依赖
- 已编译的Android内核源码树,版本建议与目标设备内核一致(例如kernel 4.19/5.10/5.15)
- 交叉编译工具链(如
aarch64-linux-android-或clang) - Android设备已解锁并启用root权限,或使用模拟器(goldfish/x86_64内核)
- 内核配置需开启模块支持:
CONFIG_MODULES=y
核心代码
创建文件hello_module.c,实现模块的加载与卸载回调:
Makefile
在相同目录下创建Makefile,指向已编译的内核源码树:
若使用clang编译,将CC替换为clang并增加LLVM=1参数。
编译与推送
- 执行
make,生成hello_module.ko文件。 - 连接设备并确保adb可用:
adb root,然后adb remount(或使用adb push到/data/local/tmp)。 - 推送模块:
adb push hello_module.ko /data/local/tmp/
加载与验证
- 进入设备shell:
adb shell - 加载模块:
insmod /data/local/tmp/hello_module.ko - 查看内核日志:
dmesg | grep hello_module,应看到输出:[hello_module] 模块已加载,初始化成功 - 卸载模块:
rmmod hello_module - 再次查看日志:
dmesg | grep hello_module,应看到:[hello_module] 模块已卸载,清理完成
通过判定标准
insmod命令无错误返回,且dmesg中出现加载成功的日志行。rmmod命令无错误返回,且dmesg中出现卸载成功的日志行。- 若设备使用SELinux enforcing模式,需确认内核允许模块加载(通常需要
adb root后执行setenforce 0,或使用userdebug版本)。
常见问题
- insmod失败提示“Exec format error”:交叉编译架构与设备不匹配,检查ARCH和CROSS_COMPILE设置。
- 提示“Operation not permitted”:设备未root或SELinux阻止,执行
adb root并尝试setenforce 0。 - dmesg无输出:确认printk级别未被屏蔽,可尝试
echo 8 > /proc/sys/kernel/printk提高日志级别。