printk() ist für den Kernel, was printf() für den Userspace ist. Zeilen, die von printk() geschrieben wurden, können mit dem Befehl dmesg angezeigt werden. Abhängig davon, wie wichtig die Meldung ist, die Sie drucken müssen, können Sie zwischen acht Meldungen auf Protokollebene wählen, die zusammen mit ihrer Bedeutung in include/linux/kern_levels.h definiert sind.
Die Syntax von printk ist:
printk ("log level" "message", <arguments>);
Im Folgenden finden Sie eine Liste der Kernel-Protokollebenen. Jede dieser Ebenen entspricht einer Zahl in einer Zeichenfolge, deren Priorität umgekehrt proportional zum Wert der Zahl ist. 0 ist beispielsweise höherprior:
#define KERN_EMERG "<0>" /* system is unusable*/ #define KERN_ALERT "<1>" /* action must be taken immediately*/ #define KERN_CRIT "<2>" /* critical conditions*/ #define KERN_ERR "<3>" /* error conditions*/ #define KERN_WARNING "<4>" /* warning conditions*/ #define KERN_NOTICE "<5>" /* normal but significant condition*/ #define KERN_INFO "<6>" /* informational*/ #define KERN_DEBUG "<7>" /* debug-level messages*/
Wir können sehen, dass jede Protokollebene einer Zahl entspricht und je niedriger die Zahl, desto wichtiger die Nachricht. Die Ebenen sind nützlich, um zu entscheiden, was dem Benutzer auf der Konsole angezeigt werden soll und was nicht.
Jede Konsole hat eine Protokollebene, die als Konsolenprotokollebene bezeichnet wird, und jede Meldung mit einer Protokollebenennummer, die kleiner als die Konsolenprotokollebene ist, wird auf der Konsole angezeigt, und andere Nachrichten, die eine Protokollebenennummer haben, die höher oder gleich der Konsolenprotokollebene ist, werden protokolliert im Kernel-Log, das mit dem Befehl „dmesg“ eingesehen werden kann.
Den Loglevel der Konsole finden Sie in der Datei /proc/sys/kernel/printk.
$ cat /proc/sys/kernel/printk 4 4 1 7
Die erste Zahl in der Ausgabe ist die Konsolenprotokollebene, die zweite die Standardprotokollebene, die dritte die minimale Protokollebene und die vierte die maximale Protokollebene.
Loglevel 4 entspricht KERN_WARNING. Somit werden alle Meldungen mit Loglevel 3,2,1 und 0 auf dem Bildschirm angezeigt sowie protokolliert und die Meldungen mit Loglevel 4,5,6,7 werden nur protokolliert und können mit „dmesg“ eingesehen werden.
Die Protokollebene der Konsole kann geändert werden, indem in den proc-Eintrag geschrieben wird:
$ echo "6" > /proc/sys/kernel/printk $ cat /proc/sys/kernel/printk 6 4 1 7
Jetzt ist die Konsolenprotokollebene auf 6 gesetzt, was KERN_INFO ist. Wir können die Protokollierung mit dem folgenden Modul testen.
# vi hello.c: #include<linux/kernel.h> #include<linux/module.h> #include<linux/init.h> static int hello_init(void) { printk(KERN_WARNING "Hello, world \n "); return 0; } static void hello_exit(void) { printk(KERN_INFO "Goodbye, world \n"); } module_init(hello_init); module_exit(hello_exit);
Der in der Init-Funktion aufgerufene printk verwendet KERN_WARNING, der Log-Level und kleiner als 6 ist, was der Konsolen-Log-Level ist und daher auf dem Bildschirm zu sehen sein sollte.
Der in der Exit-Funktion verwendete printk ist KERN_INFO, der Log-Level 6 ist, derselbe wie der Konsolen-Log-Level, und daher nicht auf dem Bildschirm sichtbar sein sollte.
Hinweis :Wir können die Funktion des Codes nur testen, indem wir uns in einen Textmodus einloggen, da keine der Nachrichten auf einem GUI-Terminal angezeigt werden.Makefile:
ifneq ($(KERNELRELEASE),) obj-m := hello.o else KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: make -C $(KERNELDIR) M=$(PWD) modules clean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean endif
Kompilieren und einfügen:
$ make $ insmod hello.ko [5377.966743] Hello world
Wir können sehen, wie die Hallo Welt auf dem Bildschirm gedruckt wird.
$ rmmmod hello $ dmesg| tail -2 [5424.190552] Good bye world
Die Auf Wiedersehen-Weltnachricht wird protokolliert, aber nicht auf dem Bildschirm gedruckt, kann aber in den Protokollen eingesehen werden. Daher können wir mit printk und den Konsolenprotokollebenen die für den Benutzer sichtbaren Kernelmeldungen kontrollieren.
Abschließende Gedanken
Der Kernel verwendet die printk-Funktion, die syntaktisch dem printf-Funktionsaufruf aus Standard-C-Bibliotheken sehr ähnlich ist, mit dem Zusatz eines optionalen Log-Levels. Die erlaubten Formate sind in den Kernelquellen unter Documentation/printk-formats.txt dokumentiert.
Die verfügbaren Protokollebenen in printk sind in der folgenden Tabelle dargestellt:
Typ | Symbol | Beschreibung |
---|---|---|
Notfall | KERN_EMERG | System ist instabil und droht abzustürzen |
Warnung | KERN_ALERT | Sofortiges Handeln ist erforderlich |
Kritisch | KERN_CRIT | Kritischer Software- oder Hardwarefehler |
Fehler | KERN_ERR | Fehlerbedingung |
Warnung | KERN_WARNUNG | Nichts Ernstes, könnte aber auf ein Problem hinweisen |
Hinweis | KERN_NOTICE | Nichts Ernstes, aber Benutzer sollten es beachten |
Informationen | KERN_INFO | Systeminformationen |
Debuggen | KERN_DEBUG | Debug-Meldungen |
Wenn keine Protokollebene angegeben ist, wird die in der Kernelkonfiguration konfigurierte Standardprotokollnachricht verwendet. Standardmäßig ist dies KERN_WARNING.