From d74e79de9538329eafee46e13175c01cc68bd73d Mon Sep 17 00:00:00 2001 From: pjht Date: Tue, 19 Mar 2024 09:23:37 -0500 Subject: [PATCH] Initial commit --- Tupfile | 6 ++++++ initrd_maker.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 Tupfile create mode 100644 initrd_maker.rs diff --git a/Tupfile b/Tupfile new file mode 100644 index 0000000..8a8058f --- /dev/null +++ b/Tupfile @@ -0,0 +1,6 @@ +.gitignore + +export RUSTUP_HOME +RUSTC_FLAGS = -C debuginfo=0 -C opt-level=3 --edition 2021 + +: initrd_maker.rs |> rustc $(RUSTC_FLAGS) -o %o %f |> %B diff --git a/initrd_maker.rs b/initrd_maker.rs new file mode 100644 index 0000000..bd3b1cc --- /dev/null +++ b/initrd_maker.rs @@ -0,0 +1,50 @@ +use std::{ + env::args, + fs::File, + io::{self, Write}, + path::Path, +}; + +const BLOCK_SIZE: u32 = 512; +const MAX_NAME_LEN: u32 = BLOCK_SIZE - 4 - 4 - 2 - 1; + +fn main() { + let mut archive = File::create("initrd").expect("Could not open initrd"); + for file_path in args().skip(1) { + let file_path = Path::new(&file_path); + let file_name = file_path.file_name().unwrap(); + let file_name_len = u32::try_from(file_name.len()).unwrap(); + assert!( + file_name_len <= MAX_NAME_LEN, + "File {:?} has name longer than {} bytes", + file_name, + MAX_NAME_LEN + ); + let mut file = File::open(file_path).expect("File did not exist"); + let length = u32::try_from(file.metadata().expect("Could not get file metadata").len()) + .expect("File size greater than 4 GiB"); + let file_num_blocks = (length / BLOCK_SIZE) + if length % BLOCK_SIZE == 0 { 0 } else { 1 }; + let mut header_block = Vec::new(); + header_block.extend_from_slice(&length.to_be_bytes()); + header_block.extend_from_slice(&file_num_blocks.to_be_bytes()); + header_block.extend_from_slice(&file_name_len.to_be_bytes()); + header_block.extend_from_slice(file_name.to_str().unwrap().as_bytes()); + header_block.push(0); + header_block.resize(BLOCK_SIZE as usize, 0); + archive + .write_all(&header_block) + .expect("Could not write to initrd"); + #[allow(clippy::cast_possible_truncation)] + let bytes_written = io::copy(&mut file, &mut archive) + .expect("Could not read from file/write to initrd") as u32; + if (bytes_written % BLOCK_SIZE) != 0 { + let bytes_padding = (BLOCK_SIZE) - (bytes_written % BLOCK_SIZE); + archive + .write_all(&vec![0; bytes_padding as usize]) + .expect("Could not write to initrd"); + } + } + archive + .write_all(&[0; BLOCK_SIZE as usize]) + .expect("Could not write to initrd"); +}