我是内核模块编程的初学者,所以这可能会变得有些愚蠢。
我正在关注本指南。我正在尝试制作一个跨多个文件的模块。(来自指南)。
各个文件是:
#include <linux/kernel.h>
#include <linux/module.h>
int init_module(void)
{
printk(KERN_INFO "Hello, world - this is the kernel speaking");
return 0;
}
和,
#include <linux/kernel.h>
#include <linux/module.h>
void cleanup_module()
{
printk(KERN_INFO "Short is the life of a kernel module");
}
这是我的 makefile。
obj-m += hello-1.o
obj-m += startstop.o
startstop-objs := start.o stop.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
(hello-1
来自之前的练习)
模块编译成功。顶部的图像显示了 的完整输出make
。编译后,我插入模块[Jan21 07:25]
,然后将其移除[ +10.624728]
。然后我连接 USB 鼠标以证明这一点。我$ dmesg -wH
在右侧终端窗口上运行。
输出符合预期,但时间不同。
hello world ...
当我移除模块时就会显示输出at +10.624...
。Short is the life ...
当我插入 USB 鼠标时就会显示输出。- 然而,该
new device
消息却准时显示。
我最初的猜测是这里可能存在某种缓冲机制,所以我尝试将优先级提高到最高printk()
,KERN_ALERT
但没有任何效果。此外,为什么在鼠标连接时消息会从缓冲区中清除?为什么鼠标输出没有缓冲?我真的可以继续进行下去,但我想知道幕后发生了什么。
PS:请忽略奇怪的用户名
答案1
内核环形缓冲区是行缓冲的,这意味着它只有在遇到换行符时才会刷新。\n
在字符串末尾添加printk
:
printk(KERN_INFO "Hello, world - this is the kernel speaking\n");
您还可以考虑使用 printk 格式化宏,因为我相信这些比直接指定更好KERN_INFO
:
pr_info("Hello, world - this is the kernel speaking\n");
如果您想将两个单独的内核消息放在同一行,您可以使用:
pr_info("Hello, world - ");
pr_cont("this is the kernel speaking\n");
其效果与原始行相同。