kernel/fs/vfs_v2/drivers/
initramfs.rs1use crate::device::fdt::FdtManager;
11use crate::early_println;
12use crate::fs::FileSystemError;
13use crate::fs::VfsManager;
14use crate::vm::vmem::MemoryArea;
15use alloc::format;
16use alloc::string::{String, ToString};
17use alloc::sync::Arc;
18use core::ptr;
19
20pub fn relocate_initramfs(usable_area: &mut MemoryArea) -> Result<MemoryArea, &'static str> {
22 let fdt_manager = FdtManager::get_manager();
23 let original_area = fdt_manager
24 .get_initramfs()
25 .ok_or("Failed to get initramfs from device tree")?;
26 let size = original_area.size();
27
28 if size == 0 || size > 0x10000000 {
30 return Err("Invalid initramfs size");
31 }
32 if original_area.start == 0 {
33 return Err("Invalid initramfs source address");
34 }
35
36 let raw_ptr = usable_area.start as *mut u8;
38 let aligned_ptr = ((raw_ptr as usize + 7) & !7) as *mut u8;
39 let aligned_addr = aligned_ptr as usize;
40
41 if aligned_addr + size > usable_area.end {
43 return Err("Insufficient memory for initramfs");
44 }
45
46 let new_area = MemoryArea::new(aligned_addr, aligned_addr + size - 1);
48
49 core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
51
52 let chunk_size = 4096; let mut src_addr = original_area.start as *const u8;
55 let mut dst_addr = aligned_ptr;
56 let mut remaining = size;
57
58 unsafe {
59 while remaining > 0 {
60 let copy_size = if remaining > chunk_size {
61 chunk_size
62 } else {
63 remaining
64 };
65 ptr::copy_nonoverlapping(src_addr, dst_addr, copy_size);
66
67 src_addr = src_addr.add(copy_size);
68 dst_addr = dst_addr.add(copy_size);
69 remaining -= copy_size;
70
71 core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
73 }
74 }
75
76 usable_area.start = (aligned_addr + size + 7) & !7;
78
79 Ok(new_area)
80}
81
82fn mount_initramfs(
83 manager: &Arc<VfsManager>,
84 initramfs: MemoryArea,
85) -> Result<(), FileSystemError> {
86 early_println!("[InitRamFS] Initializing initramfs");
87 early_println!(
88 "[InitRamFS] Using initramfs at address: {:#x}, size: {} bytes",
89 initramfs.start,
90 initramfs.size()
91 );
92 let cpio_data =
94 unsafe { core::slice::from_raw_parts(initramfs.start as *const u8, initramfs.size()) };
95 let fs = crate::fs::vfs_v2::drivers::cpiofs::CpioFS::new("initramfs".to_string(), cpio_data)?;
96 manager.mount(fs, "/", 0)?;
97 early_println!("[InitRamFS] Successfully mounted initramfs at root directory");
98 Ok(())
99}
100
101#[allow(static_mut_refs)]
102pub fn init_initramfs(manager: &Arc<VfsManager>, initramfs: MemoryArea) -> Result<(), String> {
103 match mount_initramfs(manager, initramfs) {
104 Ok(_) => Ok(()),
105 Err(e) => Err(format!("Failed to mount initramfs: {:?}", e)),
106 }
107}