printk ()
Die Kernel-Druckfunktion printk()
verhält sich fast identisch mit der C-Bibliotheksfunktion printf()
. In der Tat haben wir in diesem Buch keine wirklichen Unterschiede ausgenutzt. Für die meisten Absichten ist dies in Ordnung; printk()
ist einfach der Name der formatierten Druckfunktion des Kernels. Es gibt jedoch einige Unterschiede.
Die Robustheit von printk ()
Eine Eigenschaft, die printk()
schnell als selbstverständlich angesehen wird, ist ihre Robustheit. Die printk()
Funktion kann jederzeit von nahezu jedem Ort im Kernel aufgerufen werden. Es kann aus dem Interrupt- oder Prozesskontext aufgerufen werden. Es kann aufgerufen werden, während eine Sperre gehalten wird. Es kann auf mehreren Prozessoren gleichzeitig aufgerufen werden, erfordert jedoch nicht, dass der Anrufer eine Sperre hält.
Es ist eine belastbare Funktion. Dies ist wichtig, da der Nutzen von printk()
der Tatsache beruht, dass es immer da ist und immer funktioniert.
Die Nichtrobustheit von printk ()
Es gibt einen Riss in der Rüstung der printk()
Robustheit. Es ist vor einem bestimmten Punkt im Kernel-Startvorgang vor der Konsoleninitialisierung unbrauchbar. Wenn die Konsole nicht initialisiert ist, wohin soll die Ausgabe gehen?
Dies ist normalerweise kein Problem, es sei denn, Sie debuggen Probleme sehr früh im Startvorgang (z. B. in setup_arch()
, das eine architekturspezifische Initialisierung durchführt). Ein solches Debuggen ist zunächst eine Herausforderung, und das Fehlen jeglicher Druckmethode verschärft das Problem nur.
Es gibt einige Hoffnung, aber nicht viel. Hardcore-Architektur-Hacker verwenden die Hardware, die funktioniert (z. B. eine serielle Schnittstelle), um mit der Außenwelt zu kommunizieren. Vertrauen Sie mir, das macht den meisten Menschen keinen Spaß. Einige unterstützte Architekturen implementieren jedoch eine vernünftige Lösung, andere (einschließlich i386) verfügen über Patches, die ebenfalls den Tag retten.
Die Lösung ist eine printk()
Variante, die sehr früh im Startvorgang auf der Konsole ausgegeben werden kann : early_printk()
. Das Verhalten ist das gleiche wie printk()
, nur der Name und seine Fähigkeit, früher zu arbeiten, werden geändert. Dies ist jedoch keine tragbare Lösung, da nicht in allen unterstützten Architekturen eine solche Methode implementiert ist. Es könnte jedoch dein bester Freund werden, wenn es das tut.
Wenn Sie nicht sehr früh im Startvorgang auf die Konsole schreiben müssen, können Sie sich darauf verlassen, dass Sie printk()
immer arbeiten.