From 8743124b689e5947f5bee105bc3132ca1348bfc1 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Mon, 2 Dec 2024 12:32:22 +0200 Subject: [PATCH] xtask: qemu -drive option --- lib/qemu/src/device.rs | 29 ++++++++++++++++++++++++++++- xtask/src/main.rs | 8 +++++++- xtask/src/qemu.rs | 25 +++++++++++++++++++------ 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/lib/qemu/src/device.rs b/lib/qemu/src/device.rs index 099d3cdf..cf1623a4 100644 --- a/lib/qemu/src/device.rs +++ b/lib/qemu/src/device.rs @@ -1,4 +1,4 @@ -use std::process::Command; +use std::{path::PathBuf, process::Command}; use crate::IntoArgs; @@ -7,6 +7,12 @@ pub enum QemuNic { VirtioPci { mac: Option }, } +#[derive(Debug)] +pub enum QemuDrive { + Nvme, + Sata, +} + #[derive(Debug)] pub enum QemuDevice { NetworkTap { @@ -14,6 +20,11 @@ pub enum QemuDevice { script: Option, ifname: Option, }, + Drive { + ty: QemuDrive, + file: PathBuf, + serial: Option, + }, } #[derive(Debug)] @@ -61,6 +72,22 @@ impl IntoArgs for QemuDevice { nic.add_args(command); } + Self::Drive { ty, file, serial } => { + command.arg("-drive"); + command.arg(format!("file={},if=none,id=drive0", file.display())); + + command.arg("-device"); + let mut val = match ty { + QemuDrive::Nvme => "nvme".to_owned(), + _ => todo!(), + }; + if let Some(serial) = serial { + val.push_str(",serial="); + val.push_str(serial); + } + val.push_str(",drive=drive0"); + command.arg(val); + } } } } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 2f8e853c..7cc79f1a 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -74,6 +74,8 @@ enum SubArgs { help = "Override the default QEMU binary for the target" )] qemu: Option, + #[clap(short, long, help = "Disk image to use for persistent data")] + disk: Option, #[clap(help = "Extra arguments for QEMU")] extra_args: Vec, }, @@ -122,7 +124,11 @@ fn run(args: Args) -> Result<(), Error> { SubArgs::Test => build::test_all(env), SubArgs::Clean { toolchain } => build::clean_all(&env, toolchain), // SubArgs::GitStatus => util::git_status_all(&env), - SubArgs::Qemu { qemu, extra_args } => qemu::run(env, qemu, extra_args), + SubArgs::Qemu { + qemu, + disk, + extra_args, + } => qemu::run(env, qemu, disk, extra_args), SubArgs::Toolchain { branch } => { let branch = branch.as_ref().unwrap_or(&env.config.toolchain.branch); build::build_toolchain(&env, branch) diff --git a/xtask/src/qemu.rs b/xtask/src/qemu.rs index f8f8eb0a..5b56d3e6 100644 --- a/xtask/src/qemu.rs +++ b/xtask/src/qemu.rs @@ -5,7 +5,7 @@ use std::{ use qemu::{ aarch64, - device::{QemuDevice, QemuNic, QemuSerialTarget}, + device::{QemuDevice, QemuDrive, QemuNic, QemuSerialTarget}, i386, x86_64, Qemu, }; @@ -162,9 +162,9 @@ fn run_x86_64( qemu.override_qemu(qemu_bin); } qemu.with_serial(QemuSerialTarget::MonStdio) - // .with_cpu(x86_64::Cpu::Host { - // enable_kvm: config.machine.x86_64.enable_kvm, - // }) + .with_cpu(x86_64::Cpu::Host { + enable_kvm: config.machine.x86_64.enable_kvm, + }) .with_smp(config.machine.smp) .with_machine(x86_64::Machine::Q35) .with_boot_slot('a') @@ -220,6 +220,7 @@ fn load_qemu_config>(path: P) -> Result { fn add_devices_from_config( devices: &mut Vec, + disk: Option<&PathBuf>, config: &QemuConfig, ) -> Result<(), Error> { if config.network.enable { @@ -231,10 +232,22 @@ fn add_devices_from_config( ifname: Some(config.network.interface_name.clone()), }); } + if let Some(disk) = disk { + devices.push(QemuDevice::Drive { + ty: QemuDrive::Nvme, + file: disk.clone(), + serial: Some("deadbeef".into()), + }); + } Ok(()) } -pub fn run(env: BuildEnv, qemu: Option, extra_args: Vec) -> Result<(), Error> { +pub fn run( + env: BuildEnv, + qemu: Option, + disk: Option, + extra_args: Vec, +) -> Result<(), Error> { let config = load_qemu_config(env.workspace_root.join("qemu.toml"))?; let kernel_output_dir = env.kernel_output_dir.clone(); @@ -243,7 +256,7 @@ pub fn run(env: BuildEnv, qemu: Option, extra_args: Vec) -> Res let built = build::build_all(env)?; let mut devices = vec![]; - add_devices_from_config(&mut devices, &config)?; + add_devices_from_config(&mut devices, disk.as_ref(), &config)?; let mut command = match built { AllBuilt::AArch64(KernelProcessed(KernelBuilt(kernel)), InitrdGenerated(initrd)) => {