printk 在内部究竟是如何工作的?

gpu*_*guy 10 debugging kernel linux-kernel

我知道printf需要操作系统的帮助才能完成其工作。

我也知道printf在 Linux 源代码中不起作用,因为没有库。所以我们必须printk进行调试。

printk当操作系统仍在启动时如何工作?

slm*_*slm 11

此参考文献似乎回答了您的问题,标题为:Linux Kernel Development Second Edition

摘抄

打印()

内核打印函数 的printk()行为与 C 库printf()函数几乎相同。事实上,在整本书中,我们没有利用任何真正的差异。对于大多数意图,这很好;printk()只是内核格式化打印函数的名称。然而,它确实有一些差异。

printk() 的鲁棒性

printk()很快被认为理所当然的一个特性是它的健壮性。该printk()函数几乎可以随时从内核中的任何位置调用。它可以从中断或进程上下文中调用。它可以在持有锁时调用。它可以在多个处理器上同时调用,但不需要调用者持有锁。

这是一个有弹性的功能。这很重要,因为 的有用性printk()取决于它始终存在且始终有效的事实。

printk() 的非稳健性

printk()的坚固性的盔甲中确实存在一个裂缝。在内核启动过程中的某个点之前,在控制台初始化之前,它是不可用的。事实上,如果控制台没有初始化,输出应该去哪里?

这通常不是问题,除非您在启动过程的早期调试问题(例如,setup_arch()执行特定于体系结构的初始化)。这种调试一开始就是一个挑战,没有任何类型的打印方法只会使问题更加复杂。

有一些希望,但不是很大。核心架构黑客使用可以正常工作的硬件(例如串行端口)与外界进行通信。相信我,这对大多数人来说并不好玩。一些受支持的架构确实实现了一个合理的解决方案,但是其他架构(包括 i386)有可用的补丁,也可以节省一天的时间。

解决方案是一个printk()可以在引导过程的早期输出到控制台的变体:early_printk(). 行为与 相同printk(),只是更改了名称及其早期工作的能力。然而,这不是一个可移植的解决方案,因为并非所有支持的体系结构都实现了这种方法。不过,如果确实如此,它可能会成为你最好的朋友。

除非您需要在启动过程的早期写入控制台,否则您可以依靠它printk()始终工作。