启用 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()
添加一些调试打印,以找出正在注册的驱动程序,然后在您的配置中禁用它。
通常 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()
添加一些调试打印,以找出正在注册的驱动程序,然后在您的配置中禁用它。