diff --git a/OSDK.toml b/OSDK.toml index 0f482345..7d972066 100644 --- a/OSDK.toml +++ b/OSDK.toml @@ -27,6 +27,7 @@ args = "$(./tools/qemu_args.sh test)" [scheme."microvm"] boot.method = "qemu-direct" +build.strip_elf = true qemu.args = "$(./tools/qemu_args.sh microvm)" [scheme."iommu"] diff --git a/docs/src/osdk/reference/commands/build.md b/docs/src/osdk/reference/commands/build.md index a3ba38bf..517a54d5 100644 --- a/docs/src/osdk/reference/commands/build.md +++ b/docs/src/osdk/reference/commands/build.md @@ -54,6 +54,8 @@ To display the GRUB menu if booting with GRUB Path of QEMU - `--qemu-args `: Extra arguments for running QEMU +- `--strip-elf`: +Whether to strip the built kernel ELF using `rust-strip` ## Examples diff --git a/docs/src/osdk/reference/manifest.md b/docs/src/osdk/reference/manifest.md index b246fcfc..15e4bc5d 100644 --- a/docs/src/osdk/reference/manifest.md +++ b/docs/src/osdk/reference/manifest.md @@ -43,6 +43,7 @@ supported_archs = ["x86_64"]# List of strings, that the arch the schema can appl [build] features = [] # List of strings, the same as Cargo profile = "dev" # String, the same as Cargo +strip_elf = false # Whether to strip the built kernel ELF using `rust-strip` [boot] method = "qemu-direct" # "grub-rescue-iso"/"qemu-direct"/"grub-qcow2" kcmd_args = [] # <1> diff --git a/osdk/src/cli.rs b/osdk/src/cli.rs index b457f812..74df138b 100644 --- a/osdk/src/cli.rs +++ b/osdk/src/cli.rs @@ -264,6 +264,12 @@ pub struct CommonArgs { global = true )] pub linux_x86_legacy_boot: bool, + #[arg( + long = "strip-elf", + help = "Strip the built kernel ELF file for a smaller size", + global = true + )] + pub strip_elf: bool, #[arg( long = "target-arch", value_name = "ARCH", diff --git a/osdk/src/commands/build/bin.rs b/osdk/src/commands/build/bin.rs index 6ac7ae7f..cb771393 100644 --- a/osdk/src/commands/build/bin.rs +++ b/osdk/src/commands/build/bin.rs @@ -68,8 +68,8 @@ pub fn make_install_bzimage( ) } -pub fn strip_elf_for_qemu(install_dir: impl AsRef, elf: &AsterBin) -> AsterBin { - let stripped_elf_path = { +pub fn make_elf_for_qemu(install_dir: impl AsRef, elf: &AsterBin, strip: bool) -> AsterBin { + let result_elf_path = { let elf_name = elf .path() .file_name() @@ -77,29 +77,34 @@ pub fn strip_elf_for_qemu(install_dir: impl AsRef, elf: &AsterBin) -> Aste .to_str() .unwrap() .to_string(); - install_dir.as_ref().join(elf_name + ".stripped.elf") + install_dir.as_ref().join(elf_name + ".qemu_elf") }; - // We use rust-strip to reduce the kernel image size. - let status = Command::new("rust-strip") - .arg(elf.path()) - .arg("-o") - .arg(stripped_elf_path.as_os_str()) - .status(); + if strip { + // We use rust-strip to reduce the kernel image size. + let status = Command::new("rust-strip") + .arg(elf.path()) + .arg("-o") + .arg(result_elf_path.as_os_str()) + .status(); - match status { - Ok(status) => { - if !status.success() { - panic!("Failed to strip kernel elf."); + match status { + Ok(status) => { + if !status.success() { + panic!("Failed to strip kernel elf."); + } } + Err(err) => match err.kind() { + std::io::ErrorKind::NotFound => panic!( + "`rust-strip` command not found. Please + try `cargo install cargo-binutils` and then rerun." + ), + _ => panic!("Strip kernel elf failed, err:{:#?}", err), + }, } - Err(err) => match err.kind() { - std::io::ErrorKind::NotFound => panic!( - "`rust-strip` command not found. Please - try `cargo install cargo-binutils` and then rerun." - ), - _ => panic!("Strip kernel elf failed, err:{:#?}", err), - }, + } else { + // Copy the ELF file. + std::fs::copy(elf.path(), &result_elf_path).unwrap(); } // Because QEMU denies a x86_64 multiboot ELF file (GRUB2 accept it, btw), @@ -110,7 +115,7 @@ pub fn strip_elf_for_qemu(install_dir: impl AsRef, elf: &AsterBin) -> Aste let mut file = OpenOptions::new() .read(true) .write(true) - .open(&stripped_elf_path) + .open(&result_elf_path) .unwrap(); let bytes: [u8; 2] = [0x03, 0x00]; @@ -120,7 +125,7 @@ pub fn strip_elf_for_qemu(install_dir: impl AsRef, elf: &AsterBin) -> Aste file.flush().unwrap(); AsterBin::new( - &stripped_elf_path, + &result_elf_path, AsterBinType::Elf(AsterElfMeta { has_linux_header: false, has_pvh_header: false, @@ -128,7 +133,7 @@ pub fn strip_elf_for_qemu(install_dir: impl AsRef, elf: &AsterBin) -> Aste has_multiboot2_header: true, }), elf.version().clone(), - true, + strip, ) } diff --git a/osdk/src/commands/build/mod.rs b/osdk/src/commands/build/mod.rs index 08e13f88..9c585645 100644 --- a/osdk/src/commands/build/mod.rs +++ b/osdk/src/commands/build/mod.rs @@ -10,7 +10,7 @@ use std::{ time::{Duration, SystemTime}, }; -use bin::strip_elf_for_qemu; +use bin::make_elf_for_qemu; use super::util::{cargo, profile_name_adapter, COMMON_CARGO_ARGS, DEFAULT_TARGET_RELPATH}; use crate::{ @@ -169,10 +169,11 @@ pub fn do_build( action, ); bundle.consume_vm_image(bootdev_image); + bundle.consume_aster_bin(aster_elf); } BootMethod::QemuDirect => { - let stripped_elf = strip_elf_for_qemu(&osdk_output_directory, &aster_elf); - bundle.consume_aster_bin(stripped_elf); + let qemu_elf = make_elf_for_qemu(&osdk_output_directory, &aster_elf, build.strip_elf); + bundle.consume_aster_bin(qemu_elf); } BootMethod::GrubQcow2 => { todo!() diff --git a/osdk/src/config/scheme/action.rs b/osdk/src/config/scheme/action.rs index e58a7413..efd9e7ab 100644 --- a/osdk/src/config/scheme/action.rs +++ b/osdk/src/config/scheme/action.rs @@ -13,6 +13,7 @@ pub enum ActionChoice { #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct BuildScheme { pub profile: Option, + #[serde(default)] pub features: Vec, #[serde(default)] pub no_default_features: bool, @@ -20,11 +21,14 @@ pub struct BuildScheme { /// [Linux legacy x86 32-bit boot protocol](https://www.kernel.org/doc/html/v5.6/x86/boot.html) #[serde(default)] pub linux_x86_legacy_boot: bool, + #[serde(default)] + pub strip_elf: bool, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Build { pub profile: String, + #[serde(default)] pub features: Vec, #[serde(default)] pub no_default_features: bool, @@ -32,6 +36,8 @@ pub struct Build { pub override_configs: Vec, #[serde(default)] pub linux_x86_legacy_boot: bool, + #[serde(default)] + pub strip_elf: bool, } impl Default for Build { @@ -42,6 +48,7 @@ impl Default for Build { no_default_features: false, override_configs: Vec::new(), linux_x86_legacy_boot: false, + strip_elf: false, } } } @@ -61,6 +68,9 @@ impl Build { if common_args.linux_x86_legacy_boot { self.linux_x86_legacy_boot = true; } + if common_args.strip_elf { + self.strip_elf = true; + } } } @@ -74,10 +84,13 @@ impl BuildScheme { features.extend(self.features.clone()); features }; - // no_default_features is not inherited + // `no_default_features` is not inherited if parent.linux_x86_legacy_boot { self.linux_x86_legacy_boot = true; } + if parent.strip_elf { + self.strip_elf = true; + } } pub fn finalize(self) -> Build { @@ -87,6 +100,7 @@ impl BuildScheme { no_default_features: self.no_default_features, override_configs: Vec::new(), linux_x86_legacy_boot: self.linux_x86_legacy_boot, + strip_elf: self.strip_elf, } } }