170 lines
4.7 KiB
Rust
170 lines
4.7 KiB
Rust
use std::{env, fs, os::unix::ffi::OsStrExt, path::PathBuf, process::Command};
|
|
|
|
use gpt::{mbr::ProtectiveMBR, GptConfig};
|
|
|
|
const ROOT_DISK_SIZE_MB: usize = 256;
|
|
|
|
fn main() {
|
|
println!("cargo:rerun-if-changed=sysroot");
|
|
println!("cargo:rerun-if-changed=build.rs");
|
|
println!("cargo:rerun-if-changed=initrd_file_list");
|
|
println!("cargo:rerun-if-changed=bootloader-x86_64-uefi.efi");
|
|
println!("cargo:rerun-if-changed=boot.json");
|
|
|
|
// set by cargo, build scripts should use this directory for output files
|
|
let out_dir = std::env::var_os("OUT_DIR").unwrap();
|
|
|
|
std::fs::write("out_dir_path", out_dir.as_os_str().as_bytes()).unwrap();
|
|
|
|
let mut initrd_path = out_dir.clone();
|
|
initrd_path.push("/initrd.tar");
|
|
Command::new("bash")
|
|
.arg("-c")
|
|
.arg(format!(
|
|
"cd sysroot; tar cvf {:?} $(cat ../initrd_file_list)",
|
|
initrd_path
|
|
))
|
|
.output()
|
|
.unwrap();
|
|
|
|
let kernel = PathBuf::from(env::var_os("CARGO_BIN_FILE_KERNEL_kernel").unwrap());
|
|
|
|
let mut disk_path = out_dir.clone();
|
|
disk_path.push("/root.img");
|
|
|
|
Command::new("dd")
|
|
.arg("if=/dev/zero")
|
|
.arg(format!("of={}", disk_path.to_str().unwrap()))
|
|
.arg("bs=1M")
|
|
.arg(format!("count={}", ROOT_DISK_SIZE_MB))
|
|
.output()
|
|
.unwrap();
|
|
|
|
let mut disk = GptConfig::new().writable(true).create(&disk_path).unwrap();
|
|
|
|
ProtectiveMBR::new()
|
|
.overwrite_lba0(disk.device_mut())
|
|
.unwrap();
|
|
|
|
let boot_part_id = disk
|
|
.add_partition("boot", 32 * 1024 * 1024, gpt::partition_types::EFI, 0, None)
|
|
.unwrap();
|
|
let root_part_id = disk
|
|
.add_partition(
|
|
"root",
|
|
disk.find_free_sectors()[1].1 * disk.logical_block_size().as_u64(),
|
|
gpt::partition_types::LINUX_FS,
|
|
0,
|
|
None,
|
|
)
|
|
.unwrap();
|
|
|
|
disk.write_inplace().unwrap();
|
|
|
|
let boot_part = &disk.partitions()[&boot_part_id];
|
|
let root_part = &disk.partitions()[&root_part_id];
|
|
|
|
Command::new("dd")
|
|
.arg(format!("if={}", disk_path.to_str().unwrap()))
|
|
.arg("of=tmp_ext2.img")
|
|
.arg(format!("bs={}", disk.logical_block_size().as_u64()))
|
|
.arg(format!("skip={}", root_part.first_lba))
|
|
.arg(format!("count={}", root_part.sectors_len().unwrap()))
|
|
.output()
|
|
.unwrap();
|
|
|
|
Command::new("mkfs.ext2")
|
|
.arg("-O")
|
|
.arg("^resize_inode")
|
|
.arg("-d")
|
|
.arg("sysroot")
|
|
.arg("tmp_ext2.img")
|
|
.output()
|
|
.unwrap();
|
|
|
|
Command::new("dd")
|
|
.arg("if=tmp_ext2.img")
|
|
.arg(format!("of={}", disk_path.to_str().unwrap()))
|
|
.arg(format!("bs={}", disk.logical_block_size().as_u64()))
|
|
.arg(format!("seek={}", root_part.first_lba))
|
|
.arg("conv=notrunc")
|
|
.output()
|
|
.unwrap();
|
|
|
|
fs::remove_file("tmp_ext2.img").unwrap();
|
|
|
|
Command::new("dd")
|
|
.arg(format!("if={}", disk_path.to_str().unwrap()))
|
|
.arg("of=tmp_esp.img")
|
|
.arg(format!("bs={}", disk.logical_block_size().as_u64()))
|
|
.arg(format!("skip={}", boot_part.first_lba))
|
|
.arg(format!("count={}", boot_part.sectors_len().unwrap()))
|
|
.output()
|
|
.unwrap();
|
|
|
|
Command::new("mkfs.fat")
|
|
.arg("-g")
|
|
.arg("64/32")
|
|
.arg("-i")
|
|
.arg("12345678")
|
|
.arg("-n")
|
|
.arg("kernel-bd3a")
|
|
.arg("tmp_esp.img")
|
|
.output()
|
|
.unwrap();
|
|
|
|
Command::new("mmd")
|
|
.arg("-i")
|
|
.arg("tmp_esp.img")
|
|
.arg("efi")
|
|
.output()
|
|
.unwrap();
|
|
Command::new("mmd")
|
|
.arg("-i")
|
|
.arg("tmp_esp.img")
|
|
.arg("efi/boot")
|
|
.output()
|
|
.unwrap();
|
|
Command::new("mcopy")
|
|
.arg("-i")
|
|
.arg("tmp_esp.img")
|
|
.arg("bootloader-x86_64-uefi.efi")
|
|
.arg("::efi/boot/bootx64.efi")
|
|
.output()
|
|
.unwrap();
|
|
Command::new("mcopy")
|
|
.arg("-i")
|
|
.arg("tmp_esp.img")
|
|
.arg(&kernel)
|
|
.arg("::kernel-x86_64")
|
|
.output()
|
|
.unwrap();
|
|
Command::new("mcopy")
|
|
.arg("-i")
|
|
.arg("tmp_esp.img")
|
|
.arg(&initrd_path)
|
|
.arg("::ramdisk")
|
|
.output()
|
|
.unwrap();
|
|
Command::new("mcopy")
|
|
.arg("-i")
|
|
.arg("tmp_esp.img")
|
|
.arg("boot.json")
|
|
.arg("::")
|
|
.output()
|
|
.unwrap();
|
|
|
|
Command::new("dd")
|
|
.arg("if=tmp_esp.img")
|
|
.arg(format!("of={}", disk_path.to_str().unwrap()))
|
|
.arg(format!("bs={}", disk.logical_block_size().as_u64()))
|
|
.arg(format!("seek={}", boot_part.first_lba))
|
|
.arg("conv=notrunc")
|
|
.output()
|
|
.unwrap();
|
|
|
|
fs::remove_file("tmp_esp.img").unwrap();
|
|
|
|
println!("cargo:rustc-env=DISK_PATH={}", disk_path.to_string_lossy());
|
|
}
|