diff --git a/src/main.rs b/src/main.rs
index 963823f32746c10e8418c6bacee0f77ae737ad14..01d1fb6632ffcd69a0307217d5e49f306eac2c56 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -48,6 +48,8 @@ pub static mut AREAS: [OsMemoryEntry; 512] = [OsMemoryEntry {
 
 pub static mut KERNEL_64BIT: bool = false;
 
+pub static mut LIVE_OPT: Option<(u64, &'static [u8])> = None;
+
 struct SliceWriter<'a> {
     slice: &'a mut [u8],
     i: usize,
@@ -383,38 +385,6 @@ fn main<
         panic!("Failed to allocate memory for stack");
     }
 
-    let (kernel, kernel_entry) = {
-        let kernel = load_to_memory(os, &mut fs, "boot", "kernel", Filetype::Elf);
-        let (kernel_entry, kernel_64bit) = elf_entry(kernel);
-        unsafe { KERNEL_64BIT = kernel_64bit; }
-        (kernel, kernel_entry)
-    };
-
-    let (bootstrap_size, bootstrap_base, bootstrap_entry, initfs_offset, initfs_len) = {
-        let initfs_slice = load_to_memory(os, &mut fs, "boot", "initfs", Filetype::Other);
-        let bootstrap_slice = load_to_memory(os, &mut fs, "boot", "bootstrap", Filetype::Elf);
-        let bootstrap_len = (bootstrap_slice.len()+4095)/4096*4096;
-        let initfs_len = (initfs_slice.len()+4095)/4096*4096;
-        let (bootstrap_entry, bootstrap_64bit) = elf_entry(bootstrap_slice);
-        unsafe { assert_eq!(KERNEL_64BIT, bootstrap_64bit); }
-
-        let memory = unsafe {
-            let total_size = initfs_len + bootstrap_len;
-            let ptr = os.alloc_zeroed_page_aligned(total_size);
-            assert!(!ptr.is_null(), "failed to allocate bootstrap+initfs memory");
-            core::slice::from_raw_parts_mut(ptr, total_size)
-        };
-        memory[..bootstrap_slice.len()].copy_from_slice(bootstrap_slice);
-        memory[bootstrap_len..bootstrap_len + initfs_slice.len()].copy_from_slice(initfs_slice);
-
-        (memory.len() as u64, memory.as_mut_ptr() as u64, bootstrap_entry, bootstrap_len, initfs_len)
-    };
-
-    let page_phys = unsafe {
-        paging_create(os, kernel.as_ptr() as u64, kernel.len() as u64)
-    }.expect("Failed to set up paging");
-    //TODO: properly reserve page table allocations so kernel does not re-use them
-
     let live_opt = if cfg!(feature = "live") {
         let size = fs.header.size();
 
@@ -439,12 +409,53 @@ fn main<
         }
         println!("\rlive: {}/{} MiB", i / MIBI as u64, size / MIBI as u64);
 
+        println!("Switching to live disk");
+        unsafe {
+            LIVE_OPT = Some((
+                fs.block,
+                slice::from_raw_parts_mut(ptr, size as usize)
+            ));
+        }
+
         Some(live)
     } else {
         None
     };
     //TODO: properly reserve live disk so kernel does not re-use it
 
+    let (kernel, kernel_entry) = {
+        let kernel = load_to_memory(os, &mut fs, "boot", "kernel", Filetype::Elf);
+        let (kernel_entry, kernel_64bit) = elf_entry(kernel);
+        unsafe { KERNEL_64BIT = kernel_64bit; }
+        (kernel, kernel_entry)
+    };
+
+    let (bootstrap_size, bootstrap_base, bootstrap_entry, initfs_offset, initfs_len) = {
+        let bootstrap_slice = load_to_memory(os, &mut fs, "boot", "bootstrap", Filetype::Elf);
+        let bootstrap_len = (bootstrap_slice.len()+4095)/4096*4096;
+        let (bootstrap_entry, bootstrap_64bit) = elf_entry(bootstrap_slice);
+        unsafe { assert_eq!(KERNEL_64BIT, bootstrap_64bit); }
+
+        let initfs_slice = load_to_memory(os, &mut fs, "boot", "initfs", Filetype::Other);
+        let initfs_len = (initfs_slice.len()+4095)/4096*4096;
+
+        let memory = unsafe {
+            let total_size = initfs_len + bootstrap_len;
+            let ptr = os.alloc_zeroed_page_aligned(total_size);
+            assert!(!ptr.is_null(), "failed to allocate bootstrap+initfs memory");
+            core::slice::from_raw_parts_mut(ptr, total_size)
+        };
+        memory[..bootstrap_slice.len()].copy_from_slice(bootstrap_slice);
+        memory[bootstrap_len..bootstrap_len + initfs_slice.len()].copy_from_slice(initfs_slice);
+
+        (memory.len() as u64, memory.as_mut_ptr() as u64, bootstrap_entry, bootstrap_len, initfs_len)
+    };
+
+    let page_phys = unsafe {
+        paging_create(os, kernel.as_ptr() as u64, kernel.len() as u64)
+    }.expect("Failed to set up paging");
+    //TODO: properly reserve page table allocations so kernel does not re-use them
+
     let mut env_size = 4 * KIBI;
     let env_base = os.alloc_zeroed_page_aligned(env_size);
     if env_base.is_null() {
diff --git a/src/os/bios/disk.rs b/src/os/bios/disk.rs
index 1eb4c96af70095efe0556bd0e78a9db63896918a..0551ef10bcdce8c4382d7d716a4bd68558038497 100644
--- a/src/os/bios/disk.rs
+++ b/src/os/bios/disk.rs
@@ -52,6 +52,18 @@ impl DiskBios {
 
 impl Disk for DiskBios {
     unsafe fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
+        // Optimization for live disks
+        if let Some(live) = crate::LIVE_OPT {
+            if block >= live.0 {
+                let start = ((block - live.0) * BLOCK_SIZE) as usize;
+                let end = start + buffer.len();
+                if end <= live.1.len() {
+                    buffer.copy_from_slice(&live.1[start..end]);
+                    return Ok(buffer.len());
+                }
+            }
+        }
+
         for (i, chunk) in buffer.chunks_mut((MAX_BLOCKS * BLOCK_SIZE) as usize).enumerate() {
             let mut dap = DiskAddressPacket::from_block(
                 block + i as u64 * MAX_BLOCKS,
diff --git a/src/os/uefi/disk.rs b/src/os/uefi/disk.rs
index 5a52355d45f4831e087077527f8e8cb52a857bf6..25b9aa01bb1fa1e0cb5e78d308f07f8ebc19167d 100644
--- a/src/os/uefi/disk.rs
+++ b/src/os/uefi/disk.rs
@@ -19,6 +19,18 @@ impl Protocol<UefiBlockIo> for DiskEfi {
 
 impl Disk for DiskEfi {
     unsafe fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
+        // Optimization for live disks
+        if let Some(live) = crate::LIVE_OPT {
+            if block >= live.0 {
+                let start = ((block - live.0) * BLOCK_SIZE) as usize;
+                let end = start + buffer.len();
+                if end <= live.1.len() {
+                    buffer.copy_from_slice(&live.1[start..end]);
+                    return Ok(buffer.len());
+                }
+            }
+        }
+
         let block_size = self.0.Media.BlockSize as u64;
 
         let lba = block * BLOCK_SIZE / block_size;