我正在尝试通过 Linux 设备驱动程序自学 Linux 内核开发,目前正在阅读有关调试的章节。从我读到的所有内容来看, printk() 消息应该发送到“控制台”,据我所知,它通常由设备“/dev/console”表示。
问题是当我使用 xconsole 实用程序监视 /dev/console 时,我无法显示任何 pritnk 语句。我的消息确实出现在系统日志中,并且当我使用 dmesg 时可以看到我的消息。所以我问这个并不是为了实用目的,而是为了填补我自己对Linux系统理解的空白。
我将 printk 消息设置为最高日志级别 (KERNEL_EMERG),只是为了确保它们不会被过滤。我使用了dmesg -E
所谓的“启用控制台日志记录”,但没有任何效果。
我正在运行 Kubuntu 20,带有自定义内核 5.4.55。启用内核调试配置选项。这是我的 /proc/cmdline 文件:
BOOT_IMAGE=/boot/vmlinuz-5.4.55 root=UUID=3978ed71-51b0-4505-83b9-58401946ed0f ro console=tty0 vt.handoff=7
这是我的 /proc/sys/kernel/printk :
4 4 1 7
这是我的内核配置:
感谢您的帮助
编辑
除了@user433151的答案之外,我发现 printk() 消息仅出现在当前活动的虚拟终端上,即使在启动期间明确设置了控制台也是如此。例如,console=tty2
仅使用启动似乎会影响 /dev/console“指向”tty2 的事实,它不会使 tty2 成为内核消息的“目标”控制台。看来内核消息的默认“目标”控制台始终是 tty0,因此为了让 printk 消息出现在 tty2 上,在写入 printk 消息时 tty2 必须是当前活动的虚拟终端。我的部分困惑来自于在 tty1 上运行我的模块,然后切换到 tty2 却发现我的 printk 语句没有出现。我的解决方案是启动 tty2 中的模块,或使用 ioctl(TIOCL_SETKMSGREDIRECT) 重定向消息
答案1
xconsole
(1)只能获取用户态程序写入的内容/dev/console
,但是不是写入任何终端的任何内核消息/dev/console
都是种类的别名为(2)。
printk 内核消息只能发送到
一个Linux虚拟终端喜欢
/dev/tty0
(但是不是到任何伪终端或终端仿真器)(3)。 “虚拟终端”是那些“黑色”非 GUI 终端,您可以在运行 Linux 的 PC 上使用 Ctrl-Alt-Fx 进行切换。一个串行控制台,例如
/dev/ttyS0
(但是不是到任何串行 USB 控制台或类似控制台)。dmesg 缓冲区,由系统记录器(无论是 rsyslog 还是某些 systemd 的东西)或 dmesg 等程序从其中选取。
(1) xconsole
其工作原理是创建一个伪终端,并使用ioctl(TIOCCONS)
任何用户态写入重定向到该终端/dev/console
。
(2)Linux没有接口来获取哪个终端/dev/console
指的是哪个终端;获取该信息的唯一方法是实时调试内核;-)
(3) /dev/tty0
是当前“聚焦”虚拟终端的别名。您可以使用 重定向内核消息到另一个虚拟终端ioctl(TIOCL_SETKMSGREDIRECT)
。