Allow a bootloader to be written during redoxfs-mkfs

This commit is contained in:
Jeremy Soller
2017-09-27 20:27:38 -06:00
parent 90dc177d75
commit cbdfba7b94
2 changed files with 66 additions and 24 deletions
+39 -16
View File
@@ -2,34 +2,57 @@
extern crate redoxfs;
use std::{env, process, time};
use std::{env, fs, process, time};
use std::io::Read;
use redoxfs::{FileSystem, DiskFile};
fn main() {
let mut args = env::args();
if let Some(path) = args.nth(1) {
let ctime = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap();
let mut args = env::args().skip(1);
//Open an existing image
match DiskFile::open(&path) {
Ok(disk) => match FileSystem::create(disk, ctime.as_secs(), ctime.subsec_nanos()) {
Ok(filesystem) => {
println!("redoxfs-mkfs: created filesystem on {}, size {} MB", path, filesystem.header.1.size/1024/1024);
},
let disk_path = if let Some(path) = args.next() {
path
} else {
println!("redoxfs-mkfs: no disk image provided");
println!("redoxfs-mkfs DISK [BOOTLOADER]");
process::exit(1);
};
let bootloader_path_opt = args.next();
let disk = match DiskFile::open(&disk_path) {
Ok(disk) => disk,
Err(err) => {
println!("redoxfs-mkfs: failed to open image {}: {}", disk_path, err);
process::exit(1);
}
};
let mut bootloader = vec![];
if let Some(bootloader_path) = bootloader_path_opt {
match fs::File::open(&bootloader_path) {
Ok(mut file) => match file.read_to_end(&mut bootloader) {
Ok(_) => (),
Err(err) => {
println!("redoxfs-mkfs: failed to create filesystem on {}: {}", path, err);
println!("redoxfs-mkfs: failed to read bootloader {}: {}", bootloader_path, err);
process::exit(1);
}
},
Err(err) => {
println!("redoxfs-mkfs: failed to open image {}: {}", path, err);
println!("redoxfs-mkfs: failed to open bootloader {}: {}", bootloader_path, err);
process::exit(1);
}
}
} else {
println!("redoxfs-mkfs: no disk image provided");
println!("redoxfs-mkfs [disk]");
process::exit(1);
};
let ctime = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap();
match FileSystem::create_reserved(disk, &bootloader, ctime.as_secs(), ctime.subsec_nanos()) {
Ok(filesystem) => {
println!("redoxfs-mkfs: created filesystem on {}, reserved {} blocks, size {} MB", disk_path, filesystem.block, filesystem.header.1.size/1000/1000);
},
Err(err) => {
println!("redoxfs-mkfs: failed to create filesystem on {}: {}", disk_path, err);
process::exit(1);
}
}
}
+27 -8
View File
@@ -37,23 +37,42 @@ impl<D: Disk> FileSystem<D> {
}
/// Create a file system on a disk
pub fn create(mut disk: D, ctime: u64, ctime_nsec: u32) -> Result<Self> {
let size = disk.size()?;
pub fn create(disk: D, ctime: u64, ctime_nsec: u32) -> Result<Self> {
Self::create_reserved(disk, &[], ctime, ctime_nsec)
}
if size >= 4 * 512 {
let mut free = (2, Node::new(Node::MODE_FILE, "free", 0, ctime, ctime_nsec));
free.1.extents[0] = Extent::new(4, size - 4 * 512);
/// Create a file system on a disk, with reserved data at the beginning
/// Reserved data will be zero padded up to the nearest block
pub fn create_reserved(mut disk: D, reserved: &[u8], ctime: u64, ctime_nsec: u32) -> Result<Self> {
let size = disk.size()?;
let block_offset = (reserved.len() as u64 + 511)/512;
if size >= (block_offset + 4) * 512 {
let mut free = (block_offset + 2, Node::new(Node::MODE_FILE, "free", 0, ctime, ctime_nsec));
free.1.extents[0] = Extent::new(block_offset + 4, size - (block_offset + 4) * 512);
disk.write_at(free.0, &free.1)?;
let root = (1, Node::new(Node::MODE_DIR | 0o755, "root", 0, ctime, ctime_nsec));
let root = (block_offset + 1, Node::new(Node::MODE_DIR | 0o755, "root", 0, ctime, ctime_nsec));
disk.write_at(root.0, &root.1)?;
let header = (0, Header::new(size, root.0, free.0));
let header = (block_offset + 0, Header::new(size, root.0, free.0));
disk.write_at(header.0, &header.1)?;
for block in 0..block_offset as usize {
let mut data = [0; 512];
let mut i = 0;
while i < data.len() && block * 512 + i < reserved.len() {
data[i] = reserved[block * 512 + i];
i += 1;
}
disk.write_at(block as u64, &data)?;
}
Ok(FileSystem {
disk: disk,
block: 0,
block: block_offset,
header: header
})
} else {