Allow a bootloader to be written during redoxfs-mkfs
This commit is contained in:
+39
-16
@@ -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
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user