xtask: qemu -drive option

This commit is contained in:
Mark Poliakov 2024-12-02 12:32:22 +02:00
parent 4fcd392ee5
commit 8743124b68
3 changed files with 54 additions and 8 deletions

View File

@ -1,4 +1,4 @@
use std::process::Command; use std::{path::PathBuf, process::Command};
use crate::IntoArgs; use crate::IntoArgs;
@ -7,6 +7,12 @@ pub enum QemuNic {
VirtioPci { mac: Option<String> }, VirtioPci { mac: Option<String> },
} }
#[derive(Debug)]
pub enum QemuDrive {
Nvme,
Sata,
}
#[derive(Debug)] #[derive(Debug)]
pub enum QemuDevice { pub enum QemuDevice {
NetworkTap { NetworkTap {
@ -14,6 +20,11 @@ pub enum QemuDevice {
script: Option<String>, script: Option<String>,
ifname: Option<String>, ifname: Option<String>,
}, },
Drive {
ty: QemuDrive,
file: PathBuf,
serial: Option<String>,
},
} }
#[derive(Debug)] #[derive(Debug)]
@ -61,6 +72,22 @@ impl IntoArgs for QemuDevice {
nic.add_args(command); 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);
}
} }
} }
} }

View File

@ -74,6 +74,8 @@ enum SubArgs {
help = "Override the default QEMU binary for the target" help = "Override the default QEMU binary for the target"
)] )]
qemu: Option<PathBuf>, qemu: Option<PathBuf>,
#[clap(short, long, help = "Disk image to use for persistent data")]
disk: Option<PathBuf>,
#[clap(help = "Extra arguments for QEMU")] #[clap(help = "Extra arguments for QEMU")]
extra_args: Vec<String>, extra_args: Vec<String>,
}, },
@ -122,7 +124,11 @@ fn run(args: Args) -> Result<(), Error> {
SubArgs::Test => build::test_all(env), SubArgs::Test => build::test_all(env),
SubArgs::Clean { toolchain } => build::clean_all(&env, toolchain), SubArgs::Clean { toolchain } => build::clean_all(&env, toolchain),
// SubArgs::GitStatus => util::git_status_all(&env), // 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 } => { SubArgs::Toolchain { branch } => {
let branch = branch.as_ref().unwrap_or(&env.config.toolchain.branch); let branch = branch.as_ref().unwrap_or(&env.config.toolchain.branch);
build::build_toolchain(&env, branch) build::build_toolchain(&env, branch)

View File

@ -5,7 +5,7 @@ use std::{
use qemu::{ use qemu::{
aarch64, aarch64,
device::{QemuDevice, QemuNic, QemuSerialTarget}, device::{QemuDevice, QemuDrive, QemuNic, QemuSerialTarget},
i386, x86_64, Qemu, i386, x86_64, Qemu,
}; };
@ -162,9 +162,9 @@ fn run_x86_64(
qemu.override_qemu(qemu_bin); qemu.override_qemu(qemu_bin);
} }
qemu.with_serial(QemuSerialTarget::MonStdio) qemu.with_serial(QemuSerialTarget::MonStdio)
// .with_cpu(x86_64::Cpu::Host { .with_cpu(x86_64::Cpu::Host {
// enable_kvm: config.machine.x86_64.enable_kvm, enable_kvm: config.machine.x86_64.enable_kvm,
// }) })
.with_smp(config.machine.smp) .with_smp(config.machine.smp)
.with_machine(x86_64::Machine::Q35) .with_machine(x86_64::Machine::Q35)
.with_boot_slot('a') .with_boot_slot('a')
@ -220,6 +220,7 @@ fn load_qemu_config<P: AsRef<Path>>(path: P) -> Result<QemuConfig, Error> {
fn add_devices_from_config( fn add_devices_from_config(
devices: &mut Vec<QemuDevice>, devices: &mut Vec<QemuDevice>,
disk: Option<&PathBuf>,
config: &QemuConfig, config: &QemuConfig,
) -> Result<(), Error> { ) -> Result<(), Error> {
if config.network.enable { if config.network.enable {
@ -231,10 +232,22 @@ fn add_devices_from_config(
ifname: Some(config.network.interface_name.clone()), 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(()) Ok(())
} }
pub fn run(env: BuildEnv, qemu: Option<PathBuf>, extra_args: Vec<String>) -> Result<(), Error> { pub fn run(
env: BuildEnv,
qemu: Option<PathBuf>,
disk: Option<PathBuf>,
extra_args: Vec<String>,
) -> Result<(), Error> {
let config = load_qemu_config(env.workspace_root.join("qemu.toml"))?; let config = load_qemu_config(env.workspace_root.join("qemu.toml"))?;
let kernel_output_dir = env.kernel_output_dir.clone(); let kernel_output_dir = env.kernel_output_dir.clone();
@ -243,7 +256,7 @@ pub fn run(env: BuildEnv, qemu: Option<PathBuf>, extra_args: Vec<String>) -> Res
let built = build::build_all(env)?; let built = build::build_all(env)?;
let mut devices = vec![]; 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 { let mut command = match built {
AllBuilt::AArch64(KernelProcessed(KernelBuilt(kernel)), InitrdGenerated(initrd)) => { AllBuilt::AArch64(KernelProcessed(KernelBuilt(kernel)), InitrdGenerated(initrd)) => {