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