build: better fat32 image handling

This commit is contained in:
Mark Poliakov 2024-04-12 12:23:21 +03:00
parent becbf2aea1
commit 62f6cab7d6
3 changed files with 219 additions and 56 deletions

159
Cargo.lock generated
View File

@ -90,6 +90,21 @@ dependencies = [
"spinning_top", "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]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.13" version = "0.6.13"
@ -210,6 +225,12 @@ dependencies = [
"rustversion", "rustversion",
] ]
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.14.3" version = "1.14.3"
@ -252,6 +273,20 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 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]] [[package]]
name = "clap" name = "clap"
version = "4.5.2" version = "4.5.2"
@ -307,6 +342,12 @@ dependencies = [
"rustc-std-workspace-core", "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]] [[package]]
name = "crossbeam-queue" name = "crossbeam-queue"
version = "0.3.11" version = "0.3.11"
@ -467,6 +508,18 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 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]] [[package]]
name = "fdt-rs" name = "fdt-rs"
version = "0.4.5" version = "0.4.5"
@ -516,6 +569,15 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "fscommon"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "315ce685aca5ddcc5a3e7e436ef47d4a5d0064462849b6f0f628c28140103531"
dependencies = [
"log",
]
[[package]] [[package]]
name = "funty" name = "funty"
version = "2.0.0" version = "2.0.0"
@ -631,6 +693,29 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 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]] [[package]]
name = "idna" name = "idna"
version = "0.5.0" version = "0.5.0"
@ -684,6 +769,15 @@ dependencies = [
"libc", "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]] [[package]]
name = "kernel-arch" name = "kernel-arch"
version = "0.1.0" 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" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 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]] [[package]]
name = "which" name = "which"
version = "6.0.0" version = "6.0.0"
@ -1643,6 +1791,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.52.0" version = "0.52.0"
@ -1757,6 +1914,8 @@ dependencies = [
"clap", "clap",
"dependency-graph", "dependency-graph",
"env_logger", "env_logger",
"fatfs",
"fscommon",
"git2", "git2",
"log", "log",
"qemu", "qemu",

View File

@ -19,3 +19,5 @@ env_logger = "0.11.2"
log = "0.4.21" log = "0.4.21"
dependency-graph = "0.1.5" dependency-graph = "0.1.5"
semver = { version = "1.0.22", features = ["serde"] } semver = { version = "1.0.22", features = ["serde"] }
fatfs = "0.3.6"
fscommon = "0.1.1"

View File

@ -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}; use crate::{build::cargo::CargoBuilder, env::BuildEnv, error::Error, util};
@ -15,6 +21,26 @@ fn build_yboot(env: &BuildEnv) -> Result<YbootBuilt, Error> {
Ok(YbootBuilt(binary)) Ok(YbootBuilt(binary))
} }
fn copy_into_fat(
dir: &fatfs::Dir<'_, BufStream<File>>,
src: impl AsRef<Path>,
dst: impl AsRef<str>,
) -> 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( fn build_uefi_image(
env: &BuildEnv, env: &BuildEnv,
yboot: YbootBuilt, yboot: YbootBuilt,
@ -24,6 +50,7 @@ fn build_uefi_image(
log::info!("Building x86-64 UEFI image"); log::info!("Building x86-64 UEFI image");
let image_path = env.kernel_output_dir.join("image.fat32"); let image_path = env.kernel_output_dir.join("image.fat32");
if !image_path.exists() {
util::run_external_command( util::run_external_command(
"dd", "dd",
[ [
@ -39,46 +66,21 @@ fn build_uefi_image(
["-F32".as_ref(), image_path.as_os_str()], ["-F32".as_ref(), image_path.as_os_str()],
false, false,
)?; )?;
util::run_external_command( }
"mmd",
["-i".as_ref(), image_path.as_os_str(), "::EFI".as_ref()], let image_file = OpenOptions::new()
false, .read(true)
)?; .write(true)
util::run_external_command( .open(&image_path)?;
"mmd", let buf_stream = fscommon::BufStream::new(image_file);
["-i".as_ref(), image_path.as_os_str(), "::EFI/Boot".as_ref()], let fs = fatfs::FileSystem::new(buf_stream, fatfs::FsOptions::new())?;
false,
)?; let root_dir = fs.root_dir();
util::run_external_command(
"mcopy", let boot_dir = root_dir.create_dir("EFI")?.create_dir("Boot")?;
[ copy_into_fat(&boot_dir, &yboot.0, "BootX64.efi")?;
"-i".as_ref(), copy_into_fat(&root_dir, &kernel.0 .0, "kernel.elf")?;
image_path.as_os_str(), copy_into_fat(&root_dir, &initrd.0, "initrd.img")?;
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,
)?;
Ok(ImageBuilt(image_path)) Ok(ImageBuilt(image_path))
} }