当我尝试让客户机 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