1 use fdt::node::FdtNode; 2 use system_error::SystemError; 3 4 use crate::{ 5 arch::mm::init::mm_early_init, 6 driver::{firmware::efi::init::efi_init, open_firmware::fdt::open_firmware_fdt_driver}, 7 init::{boot_params, init::start_kernel}, 8 kdebug, kinfo, 9 mm::{memblock::mem_block_manager, PhysAddr, VirtAddr}, 10 print, println, 11 }; 12 13 #[derive(Debug)] 14 pub struct ArchBootParams { 15 /// 启动时的fdt物理地址 16 pub fdt_paddr: PhysAddr, 17 pub fdt_vaddr: Option<VirtAddr>, 18 } 19 20 impl ArchBootParams { 21 pub const DEFAULT: Self = ArchBootParams { 22 fdt_paddr: PhysAddr::new(0), 23 fdt_vaddr: None, 24 }; 25 26 pub fn arch_fdt(&self) -> VirtAddr { 27 // 如果fdt_vaddr为None,则说明还没有进行内核虚拟地址空间的映射,此时返回物理地址 28 if self.fdt_vaddr.is_none() { 29 return VirtAddr::new(self.fdt_paddr.data()); 30 } 31 self.fdt_vaddr.unwrap() 32 } 33 } 34 35 static mut BOOT_HARTID: usize = 0; 36 static mut BOOT_FDT_PADDR: PhysAddr = PhysAddr::new(0); 37 38 #[no_mangle] 39 unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! { 40 let fdt_paddr = PhysAddr::new(fdt_paddr); 41 42 unsafe { 43 BOOT_HARTID = hartid; 44 BOOT_FDT_PADDR = fdt_paddr; 45 } 46 47 start_kernel(); 48 } 49 50 #[inline(never)] 51 fn print_node(node: FdtNode<'_, '_>, n_spaces: usize) { 52 (0..n_spaces).for_each(|_| print!(" ")); 53 println!("{}/", node.name); 54 node.properties().for_each(|p| { 55 (0..n_spaces + 4).for_each(|_| print!(" ")); 56 println!("{}: {:?}", p.name, p.value); 57 }); 58 59 for child in node.children() { 60 print_node(child, n_spaces + 4); 61 } 62 } 63 64 /// 解析fdt,获取内核启动参数 65 #[inline(never)] 66 unsafe fn parse_dtb() { 67 let fdt_paddr = boot_params().read().arch.fdt_paddr; 68 if fdt_paddr.is_null() { 69 panic!("Failed to get fdt address!"); 70 } 71 72 open_firmware_fdt_driver() 73 .early_scan_device_tree() 74 .expect("Failed to scan device tree at boottime."); 75 } 76 77 #[inline(never)] 78 pub fn early_setup_arch() -> Result<(), SystemError> { 79 let hartid = unsafe { BOOT_HARTID }; 80 let fdt_paddr = unsafe { BOOT_FDT_PADDR }; 81 boot_params().write().arch.fdt_paddr = fdt_paddr; 82 kinfo!( 83 "DragonOS kernel is running on hart {}, fdt address:{:?}", 84 hartid, 85 fdt_paddr 86 ); 87 mm_early_init(); 88 89 let fdt = 90 unsafe { fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!") }; 91 print_node(fdt.find_node("/").unwrap(), 0); 92 93 unsafe { parse_dtb() }; 94 95 for x in mem_block_manager().to_iter() { 96 kdebug!("before efi: {x:?}"); 97 } 98 99 efi_init(); 100 101 open_firmware_fdt_driver().early_init_fdt_scan_reserved_mem(); 102 103 return Ok(()); 104 } 105 106 #[inline(never)] 107 pub fn setup_arch() -> Result<(), SystemError> { 108 // todo 109 return Ok(()); 110 } 111 112 #[inline(never)] 113 pub fn setup_arch_post() -> Result<(), SystemError> { 114 // todo 115 return Ok(()); 116 } 117