diff --git a/src/bin/mkfs.rs b/src/bin/mkfs.rs
index 3abdd70bb92bb9bfdbf89232c2bb8e149e4a7230..327aeb61e388076e48919346590aca81ea3c531c 100644
--- a/src/bin/mkfs.rs
+++ b/src/bin/mkfs.rs
@@ -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();
-
-        //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 mut args = env::args().skip(1);
+
+    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);
+        }
     }
 }
diff --git a/src/filesystem.rs b/src/filesystem.rs
index 41516ef698687a84c9e87a56b4a5c3236df661ce..fa2bd246be9285a683ce91d9893763bb85d1a889 100644
--- a/src/filesystem.rs
+++ b/src/filesystem.rs
@@ -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> {
+    pub fn create(disk: D, ctime: u64, ctime_nsec: u32) -> Result<Self> {
+        Self::create_reserved(disk, &[], ctime, ctime_nsec)
+    }
+
+    /// 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 >= 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);
+        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 {