Use virtio-console for the serial devices
A VM is now provided with two
serial devices. One is the uart device which is used as the output
device for the cases where virtio-console device driver is not
available. In the case of Microdroid, it's used by bootloader (u-boot)
and by the kernel as earlycon. The other is the virtio-serial device. It
is used as the console for the kernel.
This CL has two X86 specific hacks though.
1. The PCI addresses of the boot devices were adjusted. This is because
we have added one more PCI device (the virtio-serial device) and crosvm
for x86_64 puts serial devices prior to the block devices and they all
share the same bus ID. As a result, the block device addresses are all
shifted by 1.
2. The kernel command line embedded in boot.img now has `console=none`.
This is to prevent u-boot from automatically adding `console=ttyS0`. If
we let u-boot do that, then we will have console=ttyS0 together with
console=hvc0. Then each kernel message is printed twice; once to ttyS0
and once again to hvc0.
Bug: 200914564
Test: run a VM
Change-Id: I4349c4d70ac76c1b4ddc77bbff6c9b697b2f1f4e
diff --git a/virtualizationservice/src/crosvm.rs b/virtualizationservice/src/crosvm.rs
index 38e5bf3..4844657 100644
--- a/virtualizationservice/src/crosvm.rs
+++ b/virtualizationservice/src/crosvm.rs
@@ -238,12 +238,25 @@
command.arg("--mem").arg(memory_mib.to_string());
}
- if let Some(log_fd) = config.log_fd {
+ // Setup the serial devices.
+ // 1. uart device: used as the output device by bootloaders and as early console by linux
+ // 2. virtio-console device: used as the console device
+ //
+ // When log_fd is not specified, the devices are attached to sink, which means what's written
+ // there is discarded.
+ //
+ // Warning: Adding more serial devices requires you to shift the PCI device ID of the boot
+ // disks in bootconfig.x86_64. This is because x86 crosvm puts serial devices and the block
+ // devices in the same PCI bus and serial devices comes before the block devices. Arm crosvm
+ // doesn't have the issue.
+ let backend = if let Some(log_fd) = config.log_fd {
command.stdout(log_fd);
+ "stdout"
} else {
- // Ignore console output.
- command.arg("--serial=type=sink");
- }
+ "sink"
+ };
+ command.arg(format!("--serial=type={},hardware=serial", backend));
+ command.arg(format!("--serial=type={},hardware=virtio-console", backend));
// Keep track of what file descriptors should be mapped to the crosvm process.
let mut preserved_fds = config.indirect_files.iter().map(|file| file.as_raw_fd()).collect();