Linux-Kernel

(Linux) printk() 消息是否應該發送到 /dev/console?如果是這樣,他們為什麼不出現?

  • September 18, 2020

我正在嘗試通過使用 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

這是我的核心配置:

https://pastebin.com/ijAS6tVa

謝謝您的幫助

編輯

除了@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 核心消息只能轉到

  1. 一個 linux虛擬終端,例如/dev/tty0(但不是任何偽終端或終端仿真器)(3)。“虛擬終端”是那些“黑色”的非 gui 終端,您可以在執行 Linux 的 PC 上使用 Ctrl-Alt-Fx 進行切換。
  2. 類似的串列控制台/dev/ttyS0(但不是任何 USB 串列控制台或類似控制台)。
  3. dmesg 緩衝區,系統記錄器(無論是 rsyslog 還是一些 systemd 東西)或 dmesg 之類的程序從那裡選擇它們。

(1) xconsole通過創建一個偽終端,並使用ioctl(TIOCCONS)任何使用者空間寫入重定向到/dev/console.

(2) Linux沒有介面獲取到哪個終端/dev/console指代;獲取該資訊的唯一方法是實時調試核心;-)

(3) /dev/tty0是目前“聚焦”虛擬終端的別名。您可以使用 .將核心消息重定向到另一個虛擬終端ioctl(TIOCL_SETKMSGREDIRECT)

引用自:https://unix.stackexchange.com/questions/609738