diff --git a/Cargo.lock b/Cargo.lock index e4a7cb58..98f8dfed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,6 +90,21 @@ dependencies = [ "spinning_top", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.13" @@ -210,6 +225,12 @@ dependencies = [ "rustversion", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "bytemuck" version = "1.14.3" @@ -252,6 +273,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + [[package]] name = "clap" version = "4.5.2" @@ -307,6 +342,12 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + [[package]] name = "crossbeam-queue" version = "0.3.11" @@ -467,6 +508,18 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "fatfs" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05669f8e7e2d7badc545c513710f0eba09c2fbef683eb859fd79c46c355048e0" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "chrono", + "log", +] + [[package]] name = "fdt-rs" version = "0.4.5" @@ -516,6 +569,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fscommon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "315ce685aca5ddcc5a3e7e436ef47d4a5d0064462849b6f0f628c28140103531" +dependencies = [ + "log", +] + [[package]] name = "funty" version = "2.0.0" @@ -631,6 +693,29 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.5.0" @@ -684,6 +769,15 @@ dependencies = [ "libc", ] +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "kernel-arch" version = "0.1.0" @@ -1599,6 +1693,60 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.52", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + [[package]] name = "which" version = "6.0.0" @@ -1643,6 +1791,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -1757,6 +1914,8 @@ dependencies = [ "clap", "dependency-graph", "env_logger", + "fatfs", + "fscommon", "git2", "log", "qemu", diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 1e532f72..cf8c75c6 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -19,3 +19,5 @@ env_logger = "0.11.2" log = "0.4.21" dependency-graph = "0.1.5" semver = { version = "1.0.22", features = ["serde"] } +fatfs = "0.3.6" +fscommon = "0.1.1" diff --git a/xtask/src/build/x86_64.rs b/xtask/src/build/x86_64.rs index 00e56783..77555cb3 100644 --- a/xtask/src/build/x86_64.rs +++ b/xtask/src/build/x86_64.rs @@ -1,4 +1,10 @@ -use std::path::PathBuf; +use std::{ + fs::{self, File, OpenOptions}, + io::{self, BufReader, BufWriter}, + path::{Path, PathBuf}, +}; + +use fscommon::BufStream; use crate::{build::cargo::CargoBuilder, env::BuildEnv, error::Error, util}; @@ -15,6 +21,26 @@ fn build_yboot(env: &BuildEnv) -> Result { Ok(YbootBuilt(binary)) } +fn copy_into_fat( + dir: &fatfs::Dir<'_, BufStream>, + src: impl AsRef, + dst: impl AsRef, +) -> Result<(), Error> { + let src = src.as_ref(); + let dst = dst.as_ref(); + + log::debug!("{} -> {}", src.display(), dst); + let mut dst = dir.create_file(dst)?; + let mut src = BufReader::new(File::open(src)?); + + dst.truncate()?; + let mut dst = BufWriter::new(dst); + + io::copy(&mut src, &mut dst)?; + + Ok(()) +} + fn build_uefi_image( env: &BuildEnv, yboot: YbootBuilt, @@ -24,61 +50,37 @@ fn build_uefi_image( log::info!("Building x86-64 UEFI image"); let image_path = env.kernel_output_dir.join("image.fat32"); - util::run_external_command( - "dd", - [ - "if=/dev/zero", - &format!("of={}", image_path.display()), - "bs=1M", - "count=256", - ], - false, - )?; - util::run_external_command( - "mkfs.vfat", - ["-F32".as_ref(), image_path.as_os_str()], - false, - )?; - util::run_external_command( - "mmd", - ["-i".as_ref(), image_path.as_os_str(), "::EFI".as_ref()], - false, - )?; - util::run_external_command( - "mmd", - ["-i".as_ref(), image_path.as_os_str(), "::EFI/Boot".as_ref()], - false, - )?; - util::run_external_command( - "mcopy", - [ - "-i".as_ref(), - image_path.as_os_str(), - yboot.0.as_os_str(), - "::EFI/Boot/BootX64.efi".as_ref(), - ], - false, - )?; - util::run_external_command( - "mcopy", - [ - "-i".as_ref(), - image_path.as_os_str(), - kernel.0 .0.as_os_str(), - "::kernel.elf".as_ref(), - ], - false, - )?; - util::run_external_command( - "mcopy", - [ - "-i".as_ref(), - image_path.as_os_str(), - initrd.0.as_os_str(), - "::initrd.img".as_ref(), - ], - false, - )?; + if !image_path.exists() { + util::run_external_command( + "dd", + [ + "if=/dev/zero", + &format!("of={}", image_path.display()), + "bs=1M", + "count=256", + ], + false, + )?; + util::run_external_command( + "mkfs.vfat", + ["-F32".as_ref(), image_path.as_os_str()], + false, + )?; + } + + let image_file = OpenOptions::new() + .read(true) + .write(true) + .open(&image_path)?; + let buf_stream = fscommon::BufStream::new(image_file); + let fs = fatfs::FileSystem::new(buf_stream, fatfs::FsOptions::new())?; + + let root_dir = fs.root_dir(); + + let boot_dir = root_dir.create_dir("EFI")?.create_dir("Boot")?; + copy_into_fat(&boot_dir, &yboot.0, "BootX64.efi")?; + copy_into_fat(&root_dir, &kernel.0 .0, "kernel.elf")?; + copy_into_fat(&root_dir, &initrd.0, "initrd.img")?; Ok(ImageBuilt(image_path)) }