(Linux) printk() 消息是否應該發送到 /dev/console?如果是這樣,他們為什麼不出現?
我正在嘗試通過使用 Linux 設備驅動程序來自學 Linux 核心開發,而我目前正在討論關於調試的章節。從我讀過的所有內容來看,printk() 消息應該發送到“控制台”,據我所知,它通常由設備“/dev/console”表示。
問題是當我使用 xconsole 實用程序監視 /dev/console 時,我的任何 pritnk 語句都無法出現。我的消息確實出現在系統日誌中,當我使用 dmesg 時我可以看到我的消息。所以我問這個不是出於實際目的,而是為了填補我自己在理解 Linux 系統方面的空白。
我將我的 printk 消息設置為最高日誌級別 (KERNEL_EMERG),以確保它們沒有被過濾。我使用
dmesg -E
了所謂的“啟用控制台日誌記錄”,但沒有任何效果。我正在執行帶有自定義核心 5.4.55 的 Kubuntu 20。啟用核心調試配置選項。這是我的 /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 上,tty2 必須是在寫入 printk 消息時目前活動的虛擬終端。我的部分困惑來自於在 tty1 上執行我的模組,然後切換到 tty2 卻發現我的 printk 語句沒有出現。我的解決方案是在 tty2 中啟動模組,或者使用 ioctl(TIOCL_SETKMSGREDIRECT) 重定向消息
xconsole
(1)只能獲取使用者級程序寫入的內容/dev/console
,而不是寫入任何終端的任何核心消息是**(2)**/dev/console
的一種別名。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)
。