xref: /DragonOS/kernel/src/arch/riscv64/init/mod.rs (revision d46c6d27941a26de14f55a2bbf956219bcc70871)
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