内核日志未更新求助:加载hello.ko/hello2.ko时日志异常
问题排查与解决
核心问题分析
你的两个内核模块出现异常的原因有两个:
1. printk输出未及时刷新
printk依赖内核缓冲机制处理输出,你的字符串末尾未添加换行符\n,导致加载hello.ko时,"hello world"仅停留在内核日志缓冲区,没有立即输出到日志系统。直到加载hello2.ko时,缓冲区被触发刷新,才把之前的内容一并输出。
2. 模块全局符号冲突
两个模块的初始化函数(init_module_new)和清理函数(cleanup_function_new)完全同名。内核模块加载时会将符号注册到全局符号表,同名符号会引发冲突:加载第二个模块时,内核错误绑定到第一个模块已注册的符号上,执行的是hello.ko的初始化函数,因此输出"hello world"而非预期的"hello world2"。
修复步骤
步骤1:给printk添加换行符
修改两个模块中printk的字符串,末尾加上\n,确保日志及时输出:
- hello.ko的初始化函数:
清理函数:printk(KERN_ALERT "hello world\n");printk(KERN_ALERT "good bye\n"); - hello2.ko的初始化函数:
清理函数:printk(KERN_ALERT "hello world2\n");printk(KERN_ALERT "good bye2\n");
步骤2:修改函数名避免符号冲突
为两个模块的函数设置唯一名称,避免全局符号表冲突:
- hello.ko修改后代码:
#include <linux/kernel.h> #include <linux/module.h> int hello_init(void) { printk(KERN_ALERT "hello world\n"); return 0; } void hello_exit(void) { printk(KERN_ALERT "good bye\n"); return; } MODULE_LICENSE("GPL"); module_init(hello_init); module_exit(hello_exit); - hello2.ko修改后代码:
#include <linux/kernel.h> #include <linux/module.h> int hello2_init(void) { printk(KERN_ALERT "hello world2\n"); return 0; } void hello2_exit(void) { printk(KERN_ALERT "good bye2\n"); return; } MODULE_LICENSE("GPL"); module_init(hello2_init); module_exit(hello2_exit);
步骤3:重新编译测试
- 分别重新编译两个模块,确保编译过程无符号冲突警告。
- 加载hello.ko后,执行
dmesg | tail查看日志,此时应能看到"hello world"的输出。 - 再加载hello2.ko,再次查看日志,应能看到"hello world2"的输出。
内容的提问来源于stack exchange,提问作者abhishek KUMAR
相关产品推荐
相关产品推荐

