Skip to content

Instantly share code, notes, and snippets.

@slp
Created March 17, 2025 17:05
Show Gist options
  • Save slp/0850f3a010e088f9da296e08ce3b8146 to your computer and use it in GitHub Desktop.
Save slp/0850f3a010e088f9da296e08ce3b8146 to your computer and use it in GitHub Desktop.
libkrun: enable legacy UART
diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs
index e67af76..b56ed94 100644
--- a/src/vmm/src/builder.rs
+++ b/src/vmm/src/builder.rs
@@ -10,7 +10,7 @@ use std::fmt::{Display, Formatter};
use std::fs::File;
use std::io::{self, Read};
#[cfg(target_os = "linux")]
-use std::os::fd::AsRawFd;
+use std::os::fd::{RawFd, AsRawFd};
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
@@ -65,6 +65,7 @@ use linux_loader::loader::{self, KernelLoader};
use nix::unistd::isatty;
use polly::event_manager::{Error as EventManagerError, EventManager};
use utils::eventfd::EventFd;
+use utils::terminal::Terminal;
#[cfg(all(target_arch = "x86_64", not(feature = "efi"), not(feature = "tee")))]
use vm_memory::mmap::MmapRegion;
#[cfg(not(feature = "tee"))]
@@ -436,6 +437,36 @@ impl Display for StartMicrovmError {
}
}
+// Wrapper over io::Stdin that implements `Serial::ReadableFd` and `vmm::VmmEventsObserver`.
+pub struct SerialStdin(io::Stdin);
+impl SerialStdin {
+ /// Returns a `SerialStdin` wrapper over `io::stdin`.
+ pub fn get() -> Self {
+ let stdin = io::stdin();
+ stdin.lock().set_raw_mode().unwrap();
+ SerialStdin(stdin)
+ }
+
+ pub fn restore() {
+ let stdin = io::stdin();
+ stdin.lock().set_canon_mode().unwrap();
+ }
+}
+
+impl io::Read for SerialStdin {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ self.0.read(buf)
+ }
+}
+
+impl AsRawFd for SerialStdin {
+ fn as_raw_fd(&self) -> RawFd {
+ self.0.as_raw_fd()
+ }
+}
+
+impl devices::legacy::ReadableFd for SerialStdin {}
+
enum Payload {
#[cfg(all(target_arch = "x86_64", not(feature = "tee")))]
KernelMmap,
@@ -588,13 +619,13 @@ pub fn build_microvm(
// On x86_64 always create a serial device,
// while on aarch64 only create it if 'console=' is specified in the boot args.
- let serial_device = if cfg!(feature = "efi") {
+ let serial_device = if !cfg!(feature = "efi") {
Some(setup_serial_device(
event_manager,
- None,
- None,
+ Some(Box::new(SerialStdin::get())),
+ //None,
// Uncomment this to get EFI output when debugging EDK2.
- //Some(Box::new(io::stdout())),
+ Some(Box::new(io::stdout())),
)?)
} else {
None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment