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