kernel/fs/vfs_v2/drivers/
initramfs.rs1use core::ptr;
11use alloc::string::ToString;
12use alloc::sync::Arc;
13use crate::device::fdt::FdtManager;
14use crate::fs::VfsManager;
15use crate::early_println;
16use crate::fs::FileSystemError;
17use crate::vm::vmem::MemoryArea;
18
19static mut INITRAMFS_AREA: Option<MemoryArea> = None;
20
21pub fn relocate_initramfs(usable_area: &mut MemoryArea) -> Result<(), &'static str> {
23 early_println!("[InitRamFS] Relocating initramfs to {:#x}", usable_area.start as usize);
24 let fdt_manager = FdtManager::get_manager();
25 let original_area = fdt_manager.get_initramfs()
26 .ok_or("Failed to get initramfs from device tree")?;
27 let size = original_area.size();
28 early_println!("[InitRamFS] Original initramfs at {:#x}, size: {} bytes", original_area.start, size);
29
30 if size == 0 || size > 0x10000000 {
32 return Err("Invalid initramfs size");
33 }
34 if original_area.start == 0 {
35 return Err("Invalid initramfs source address");
36 }
37
38 let raw_ptr = usable_area.start as *mut u8;
40 let aligned_ptr = ((raw_ptr as usize + 7) & !7) as *mut u8;
41 let aligned_addr = aligned_ptr as usize;
42
43 early_println!("[InitRamFS] Copying from {:#x} to {:#x} (aligned), size: {} bytes",
44 original_area.start, aligned_addr, size);
45
46 if aligned_addr + size > usable_area.end {
48 return Err("Insufficient memory for initramfs");
49 }
50
51 let new_area = MemoryArea::new(aligned_addr, aligned_addr + size - 1);
53
54 core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
56
57 let chunk_size = 4096; let mut src_addr = original_area.start as *const u8;
60 let mut dst_addr = aligned_ptr;
61 let mut remaining = size;
62
63 unsafe {
64 while remaining > 0 {
65 let copy_size = if remaining > chunk_size { chunk_size } else { remaining };
66 ptr::copy_nonoverlapping(src_addr, dst_addr, copy_size);
67
68 src_addr = src_addr.add(copy_size);
69 dst_addr = dst_addr.add(copy_size);
70 remaining -= copy_size;
71
72 core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
74 }
75 }
76
77 usable_area.start = (aligned_addr + size + 7) & !7;
79 early_println!("[InitRamFS] Relocated initramfs to {:#x}, next usable: {:#x}",
80 new_area.start, usable_area.start);
81 unsafe { INITRAMFS_AREA = Some(new_area) };
82 Ok(())
83}
84
85fn mount_initramfs(manager: &Arc<VfsManager>, initramfs: MemoryArea) -> Result<(), FileSystemError> {
86 early_println!("[InitRamFS] Initializing initramfs");
87 early_println!("[InitRamFS] Using initramfs at address: {:#x}, size: {} bytes", initramfs.start, initramfs.size());
88 let cpio_data = unsafe {
90 core::slice::from_raw_parts(initramfs.start as *const u8, initramfs.size())
91 };
92 let fs = crate::fs::vfs_v2::drivers::cpiofs::CpioFS::new("initramfs".to_string(), cpio_data)?;
93 manager.mount(fs, "/", 0)?;
94 early_println!("[InitRamFS] Successfully mounted initramfs at root directory");
95 Ok(())
96}
97
98#[allow(static_mut_refs)]
99pub fn init_initramfs(manager: &Arc<VfsManager>) {
100 let initramfs_ptr = unsafe { INITRAMFS_AREA.as_ref().map(|area| area.start as *const u8).unwrap_or(core::ptr::null()) };
101 if !initramfs_ptr.is_null() {
102 let initramfs = unsafe { *INITRAMFS_AREA.as_ref().unwrap() };
103 if let Err(e) = mount_initramfs(manager, initramfs.clone()) {
104 early_println!("[InitRamFS] Warning: Could not mount initramfs: {:?}", e);
105 return;
106 }
107 } else {
108 early_println!("[InitRamFS] Warning: Initramfs relocation failed, cannot mount");
109 }
110}