Score:0

Does Ubuntu expressly not use printf for output at boot? Can it?

ng flag

This question occurs to me when I am trying to have the guest Ubuntu OS display boot messages in QEMU VM (like [ 2.34567890123] ... and [ OK ] ....). Here I have a QEMU VM, both the host and guest being Ubuntu 20.04. To display guest's boot messages in host's console (i.e., command line that starts qemu), I set some lines of the guest's /etc/default/grub file as follows:

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

Then I start the guest using the following command:

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

GRUB outputs its TUI by either serial or VGA text mode. -nographic disables the VGA output and -serial none disables the serial console, so I cannot see any GRUB TUI. Only the QEMU monitor displays in the console. According to the documentation of -nographic (here), "QEMU is a simple command line application" in this situation. Like normal C/C++ program, QEMU monitor uses printf (or other function, but please allow me to use this name as an expedient) to display its versions, prompts and other messages. After 5 seconds, Ubuntu guest OS is booting. However, I can not see any boot messages printed in the console. My previous experiments shows that Ubuntu does not use serial console, Instead, it uses VGA text mode for output. For this reason, I am guessing, if Ubuntu can use the same printf function to output its boot messages, QEMU should be able to display them in console (muxed with QEMU monitor), just like how QEMU monitor's outputs are treated. Based on the observation that the console has only the output of QEMU monitor, my question is:

Does Ubuntu not use printf for output at boot, expressly or by default, perhaps due to performance consideration? If it's a default behavior, what boot option can I use to force Ubuntu to use printf to output its boot message (or any output method that QEMU moniter uses), as opposed to VGA text mode? As a side note, I googled but did not find any online documentation on Ubuntu boot options like nomodeset, so I don't know if there is any Ubuntu boot option that can specify this. Please share its link with me if you know it. It's a lot of work so I can't say for sure I have mentioned everything above. If I missed mentioning something in the question, please let me know and I will edit. Thanks.

Sadaharu Wakisaka avatar
pl flag
Welcome to AskUbuntu, `echo` is a normal command to print something on the display, `printf` is originally a command for a printer and needs to be include function by a shell. I think `bash` has it and `sh` Bourne Shell doesn't.
muru avatar
us flag
Some of the messages you talk about would actually be printed by the kernel, and typically one uses [`printk`](https://en.wikipedia.org/wiki/Printk) in the kernel. GRUB comes even before the kernel, who knows what it uses to display text? After all, programs using "`printf`" are typically relying on something else to do the actual rendering of the output, and in the case of GRUB and the kernel, there is no something else.
muru avatar
us flag
I think instead of this rather convoluted [XY problem](https://meta.stackexchange.com/q/66377/270345), you should just ask how to achieve what you want, which seems to be: "How do I make QEMU show a guest VM's console output in a terminal?"
in flag
There is no such thing as an `printf` which the kernel can just call. The kernel is the one responsible for redirecting those printf's to where they should go, be it VGA, serial, or somewhere else. So there is no way, a `printf` in your guest could magically appear on the host, unless your guest sends those messages to somewhere your host sees them.
Score:0
ng flag

After two days' investigation, I think I finally find out the key to the question.

printf sends out output both as VGA text mode (copy to memory buffer for text mode) and to serial port. An evidence is xv6 used in many OS courses. The qemu-nox target in xv6's Makefile specifies -nographic. If we add -serial none, xv6 will only display QEMU monitor (qemu).

Both GRUB and ubuntu shell (by shell I mean booting is completed) uses printf function. However, the difference is: GRUB uses serial but ubuntu disables serial by default. That's why under -nographic, GRUB can show but ubuntu shell can't. This also explains why -curses can display both of them.

QEMU monitor uses normal printf too. However, It runs in host which has already enabled serial, so it can output in the host's console. The guest ubuntu disables serial in iso image, so it does not print out anything under -nographic.

Ubuntu boot phase only uses VGA text mode. No serial even if it is enabled. So boot (as well as shutdown) messages cannot be displayed under -nographic but can be displayed under -curses. I think it is due to performance consideration because direct writing memory (text mode buffer) is faster than printf which in addition does serial operations.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.