From ada6cfc973f195cd37119d3804666a0fc574b229 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 10 Mar 2024 19:28:09 +0100 Subject: [PATCH] Allow embedding bootstrap code into the initfs blob This may in the future allow booting using non-redox specific bootloaders. --- tests/archive_and_read.rs | 1 + tools/src/archive_common.rs | 30 ++++++++++++++++++++++-------- tools/src/bin/archive.rs | 8 ++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/tests/archive_and_read.rs b/tests/archive_and_read.rs index d26df6c71a..ac4f87caaf 100644 --- a/tests/archive_and_read.rs +++ b/tests/archive_and_read.rs @@ -14,6 +14,7 @@ fn archive_and_read() -> Result<()> { let args = self::archive::Args { destination_path: Path::new("out.img"), source: Path::new("data"), + bootstrap_code: None, max_size: self::archive::DEFAULT_MAX_SIZE, }; self::archive::archive(&args).context("failed to archive")?; diff --git a/tools/src/archive_common.rs b/tools/src/archive_common.rs index a340aeecad..5030396169 100644 --- a/tools/src/archive_common.rs +++ b/tools/src/archive_common.rs @@ -355,8 +355,16 @@ pub struct Args<'a> { pub destination_path: &'a Path, pub max_size: u64, pub source: &'a Path, + pub bootstrap_code: Option<&'a Path>, } -pub fn archive(&Args { destination_path, max_size, source }: &Args) -> Result<()> { +pub fn archive( + &Args { + destination_path, + max_size, + source, + bootstrap_code, + }: &Args, +) -> Result<()> { let previous_extension = destination_path.extension().map_or("", |ext| { ext.to_str() .expect("expected destination path to be valid UTF-8") @@ -407,15 +415,21 @@ pub fn archive(&Args { destination_path, max_size, source }: &Args) -> Result<() log::debug!("there are {} inodes", state.inode_count); // NOTE: The header is always stored at offset zero. - let header_offset = bump_alloc( - &mut state, - std::mem::size_of::() - .try_into() - .expect("expected header size to fit"), - "allocate header", - )?; + let header_offset = bump_alloc(&mut state, 4096, "allocate header")?; assert_eq!(header_offset, 0); + if let Some(bootstrap_code) = bootstrap_code { + allocate_and_write_file( + &mut state, + &File::open(bootstrap_code).with_context(|| { + anyhow!( + "failed to open bootstrap code file `{}`", + bootstrap_code.to_string_lossy(), + ) + })?, + )?; + }; + let inode_table_length = { let inode_entry_size: u64 = std::mem::size_of::() .try_into() diff --git a/tools/src/bin/archive.rs b/tools/src/bin/archive.rs index 6fc48c66b4..5258f75ee3 100644 --- a/tools/src/bin/archive.rs +++ b/tools/src/bin/archive.rs @@ -24,6 +24,11 @@ fn main() -> Result<()> { .required(true) .help("Specify the source directory to build the image from."), ) + .arg( + Arg::new("BOOTSTRAP_CODE") + .required(false) + .help("Specify the bootstrap ELF file to include in the image.") + ) .arg( Arg::new("OUTPUT") .required(true) @@ -47,12 +52,15 @@ fn main() -> Result<()> { .get_one::("SOURCE") .expect("expected the required arg SOURCE to exist"); + let bootstrap_code = matches.get_one::("BOOTSTRAP_CODE"); + let destination = matches .get_one::("OUTPUT") .expect("expected the required arg OUTPUT to exist"); let args = Args { source: Path::new(source), + bootstrap_code: bootstrap_code.map(|bootstrap_code| Path::new(bootstrap_code)), destination_path: Path::new(destination), max_size, };