启用 early_printk 后 Printk 行为发生变化

Printk behaviour change with early_printk enabled

通常 printk 不会打印 console_init 之前的任何消息,而 start_kernel 中存在。但是启用 early_printk 后,printk 会在控制台初始化之前开始打印消息。现在 printk 的这种行为如何改变,因为我仍在使用 printk 函数来打印调试消息而不是 early_printk 函数。这个映射是怎么做的?

这不是真正的映射。当启用 early_printk 时,与以前一样使用相同的 printk(),只是在这种情况下注册新的引导控制台,并且 printk() 在早期引导阶段使用它。

看看arch/arm/kernel/early_printk.c。你可以看到:

  • 正在使用 register_console() 功能注册新控制台
  • 该控制台具有 CON_BOOT 标志,因此一旦注册了真实控制台,它就会自动取消注册
  • 打印通过 early_write() 函数进行,该函数又使用 printch() 函数,该函数分别为每个平台实现

Where in kernel source the early_console is disabled after kernel console initialization?

register_console()函数中完成:

if (bcon &&
    ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) &&
    !keep_bootcon) {
        /* We need to iterate through all boot consoles, to make
         * sure we print everything out, before we unregister them.
         */
         for_each_console(bcon)
             if (bcon->flags & CON_BOOT)
                 unregister_console(bcon);
}

上面代码中的 unregister_console() 函数禁用了所有引导控制台(当注册真实控制台时)。

And where is the real console getting registered?

真实控制台使用相同的注册方法——register_console()功能。例如:

  • 从我的开发板的 defconfig 文件 (arch/arm/configs/omap2plus_defconfig) 我可以看到我的开发板正在使用 CONFIG_SERIAL_8250 作为真正的控制台
  • 我们可以搜索register_console()在我的串行驱动程序中执行的位置;它是在 univ8250_console_init() 函数
  • 中完成的

Is there any way to keep boot consoles up after console initialization and disable real console?

仅当注册了真实控制台时,引导控制台才会自动注销。按照这个逻辑,您只需要禁用真正的控制台以保持启动控制台的完整性。

因此,您需要做的是找出在您的情况下,哪个驱动程序用于真正的控制台。您可以查看您的 .config 文件或您的电路板的 *_defconfig 文件。一旦找到它,只需在配置中禁用该驱动程序并重建内核。

如果在这样做之后您一直观察到一些真实控制台的注册,您需要向 register_console() 添加一些调试打印,以找出正在注册的驱动程序,然后在您的配置中禁用它。