mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 12:56:48 +00:00
Make stripping ELF optional for QEMU direct boot
This commit is contained in:
parent
32b1fb3723
commit
f420286920
@ -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"]
|
||||
|
@ -54,6 +54,8 @@ To display the GRUB menu if booting with GRUB
|
||||
Path of QEMU
|
||||
- `--qemu-args <ARGS>`:
|
||||
Extra arguments for running QEMU
|
||||
- `--strip-elf`:
|
||||
Whether to strip the built kernel ELF using `rust-strip`
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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",
|
||||
|
@ -68,8 +68,8 @@ pub fn make_install_bzimage(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn strip_elf_for_qemu(install_dir: impl AsRef<Path>, elf: &AsterBin) -> AsterBin {
|
||||
let stripped_elf_path = {
|
||||
pub fn make_elf_for_qemu(install_dir: impl AsRef<Path>, 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<Path>, 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<Path>, 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<Path>, 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<Path>, elf: &AsterBin) -> Aste
|
||||
has_multiboot2_header: true,
|
||||
}),
|
||||
elf.version().clone(),
|
||||
true,
|
||||
strip,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -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!()
|
||||
|
@ -13,6 +13,7 @@ pub enum ActionChoice {
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct BuildScheme {
|
||||
pub profile: Option<String>,
|
||||
#[serde(default)]
|
||||
pub features: Vec<String>,
|
||||
#[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<String>,
|
||||
#[serde(default)]
|
||||
pub no_default_features: bool,
|
||||
@ -32,6 +36,8 @@ pub struct Build {
|
||||
pub override_configs: Vec<String>,
|
||||
#[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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user