diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2022-12-16 17:06:11 +0100 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2022-12-16 17:06:11 +0100 |
commit | b71c34a7b9dcbb2e5a7d4db0f5f8f5517527cfe8 (patch) | |
tree | dbc260bcfd5d97da2877f6aa974e66cf923c94f1 | |
parent | 0c5eb6fcd840bdec82ff89e04f4ac18f1c06bd71 (diff) |
initial boot partition
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/main.rs | 86 |
2 files changed, 86 insertions, 2 deletions
@@ -6,4 +6,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1.0.66" clap = { version = "4.0.29", features = ["derive"] } +nix = { version = "0.26.1", features = ["ioctl"] } diff --git a/src/main.rs b/src/main.rs index 6992905..7052363 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,8 @@ +use anyhow::bail; use clap::Parser; +use std::fs::File; +use std::io::Write; +use std::os::unix::io::AsRawFd; #[derive(Debug, Parser)] #[command(author = "The Rustkrazy Authors", version = "v0.1.0", about = "Generate a rustkrazy image.", long_about = None)] @@ -8,8 +12,86 @@ struct Args { overwrite: String, } -fn main() { +#[cfg(target_os = "linux")] +fn device_size(file: &std::fs::File, path: String) -> anyhow::Result<u64> { + use nix::ioctl_read; + + const BLKGETSIZE64_CODE: u8 = 0x12; + const BLKGETSIZE64_SEQ: u8 = 114; + ioctl_read!(ioctl_blkgetsize64, BLKGETSIZE64_CODE, BLKGETSIZE64_SEQ, u64); + + let fd = file.as_raw_fd(); + + let mut dev_size = 0; + let dev_size_ptr = &mut dev_size as *mut u64; + + unsafe { + match ioctl_blkgetsize64(fd, dev_size_ptr) { + Ok(_) => {} + Err(_) => bail!("{} does not seem to be a device", path), + } + } + + Ok(dev_size) +} + +fn write_mbr_partition_table(file: &mut std::fs::File, dev_size: u64) -> anyhow::Result<()> { + const NOPART: &[u8] = &[0; 16]; + const BOOTABLE: &[u8] = &[0x80]; + const INVALID_CHS: &[u8] = &[0xFF, 0xFF, 0xFE]; // Causes sector values to be used + const FAT: &[u8] = &[0xc]; + const SIGNATURE: &[u8] = &[0x55, 0xAA]; + + #[allow(non_upper_case_globals)] + const KiB: u32 = 1024; + #[allow(non_upper_case_globals)] + const MiB: u32 = 1024 * KiB; + + file.write_all(&[0; 446])?; // Boot code + + // Partition 1 + file.write_all(BOOTABLE)?; + file.write_all(INVALID_CHS)?; + file.write_all(FAT)?; + file.write_all(INVALID_CHS)?; + file.write_all(&2048_u32.to_le_bytes())?; // Start at sector 2048 + file.write_all(&(256 * MiB / 512).to_le_bytes())?; // 256 MiB in size + + // Partition 2 (unused) + file.write_all(NOPART)?; + + // Partition 3 (unused) + file.write_all(NOPART)?; + + // Partition 4 (unused) + file.write_all(NOPART)?; + + file.write_all(SIGNATURE)?; + + Ok(()) +} + +fn partition(file: &mut std::fs::File, dev_size: u64) -> anyhow::Result<()> { + write_mbr_partition_table(file, dev_size)?; + + Ok(()) +} + +fn partition_device(overwrite: String) -> anyhow::Result<()> { + let mut file = File::create(overwrite.clone())?; + + let dev_size = device_size(&file, overwrite)?; + println!("Destination holds {} bytes", dev_size); + + partition(&mut file, dev_size)?; + + Ok(()) +} + +fn main() -> anyhow::Result<()> { let args = Args::parse(); - println!("overwriting {}", args.overwrite); + partition_device(args.overwrite)?; + + Ok(()) } |