Ubuntu 是否明确规定在启动时不使用 printf 进行输出?可以吗?

Ubuntu 是否明确规定在启动时不使用 printf 进行输出?可以吗?

当我尝试让客户机 Ubuntu 操作系统在 QEMU VM 中显示启动消息(如 [ 2.34567890123] ... 和 [ OK ] ....)时,我遇到了这个问题。这里我有一个 QEMU VM,主机和客户机都是 Ubuntu 20.04。为了在主机的控制台(即启动 qemu 的命令行)中显示客户的启动消息,我设置了客户机/etc/default/grub文件的一些行,如下所示:

GRUB_TIMEOUT_STYLE=menu
GRUB_TIMEOUT=5
GRUB_TERMINAL_OUTPUT=console
GRUB_CMDLINE_LINUX_DEFAULT=nomodeset

然后我使用以下命令启动客户机:

qemu-system-x86_64 -hda ubuntu.qcow -m 2000 -nographic -serial none

GRUB 通过串行或 VGA 文本模式输出其 TUI。-nographic禁用 VGA 输出并-serial none禁用串行控制台,因此我看不到任何 GRUB TUI。控制台中仅显示 QEMU 监视器。根据-nographic(这里),在这种情况下,“QEMU 是一个简单的命令行应用程序”。与普通的 C/C++ 程序一样,QEMU 监视器使用printf(或其他函数,但请允许我使用此名称作为权宜之计)来显示其版本、提示和其他消息。5 秒后,Ubuntu 客户操作系统正在启动。但是,我看不到控制台中打印的任何启动消息。我之前的实验表明 Ubuntu 不使用串行控制台,而是使用 VGA 文本模式进行输出。出于这个原因,我猜测,如果 Ubuntu 可以使用相同的printf函数来输出其启动消息,QEMU 应该能够在控制台中显示它们(与 QEMU 监视器多路复用),就像处理 QEMU 监视器的输出一样。根据控制台只有 QEMU 监视器的输出的观察,我的问题是:

Ubuntu 是否不将printf其用作启动时的输出(明确或默认),可能是出于性能考虑?如果这是默认行为,我可以使用什么启动选项来强制 Ubuntu 使用printf输出其启动消息(或 QEMU 监视器使用的任何输出方法),而不是 VGA 文本模式?顺便说一句,我在 Google 上搜索过,但没有找到任何关于 Ubuntu 启动选项的在线文档nomodeset,所以我不知道是否有任何 Ubuntu 启动选项可以指定这一点。如果您知道,请与我分享其链接。这需要大量工作,所以我不能肯定地说我上面提到了所有内容。如果我在问题中遗漏了某些内容,请告诉我,我会进行修改。谢谢。

答案1

经过两天的调查,我想我终于找到了问题的关键。

printf将输出发送为 VGA 文本模式(复制到文本模式的内存缓冲区)和串行端口。xv6在许多 OS 课程中都使用了一个证据。的 Makefileqemu-nox中的目标指定了。如果我们添加,xv6 将仅显示 QEMU 监视器。xv6-nographic-serial none(qemu)

GRUB 和 ubuntu shell(这里的 shell 指的是启动完成)都使用了printf该功能。但是,区别在于:GRUB 使用串口,​​而 ubuntu 默认禁用串口。这就是为什么在 下-nographic,GRUB 可以显示,而 ubuntu shell 不显示。这也解释了为什么-curses两者都可以显示。

QEMU 监视器printf也使用正常。但是,它在已启用串行的主机中运行,因此它可以在主机的控制台中输出。客户机 ubuntu 在 iso 映像中禁用串行,因此它不会在 下打印任何内容-nographic

Ubuntu 启动阶段仅使用 VGA 文本模式。即使启用了串行,也没有串行。因此,启动(以及关机)消息无法在 下显示,-nographic但可以在 下显示。我认为这是出于性能考虑,因为直接写入内存(文本模式缓冲区)比执行串行操作-curses更快。printf

相关内容