1 use fdt::node::FdtNode;
2 use log::{debug, info};
3 use system_error::SystemError;
4
5 use crate::{
6 arch::{
7 driver::sbi::SbiDriver,
8 init::boot::{early_boot_init, BootProtocol},
9 mm::init::mm_early_init,
10 },
11 driver::{firmware::efi::init::efi_init, open_firmware::fdt::open_firmware_fdt_driver},
12 init::{boot_params, init::start_kernel},
13 mm::{memblock::mem_block_manager, PhysAddr, VirtAddr},
14 print, println,
15 smp::cpu::ProcessorId,
16 };
17
18 use super::{cpu::init_local_context, interrupt::entry::handle_exception};
19
20 mod boot;
21 mod dragonstub;
22
23 #[derive(Debug)]
24 pub struct ArchBootParams {
25 /// 启动时的fdt物理地址
26 pub fdt_paddr: PhysAddr,
27 pub fdt_vaddr: Option<VirtAddr>,
28 pub fdt_size: usize,
29
30 pub boot_hartid: ProcessorId,
31 }
32
33 impl ArchBootParams {
34 pub const DEFAULT: Self = ArchBootParams {
35 fdt_paddr: PhysAddr::new(0),
36 fdt_vaddr: None,
37 fdt_size: 0,
38 boot_hartid: ProcessorId::new(0),
39 };
40
arch_fdt(&self) -> VirtAddr41 pub fn arch_fdt(&self) -> VirtAddr {
42 // 如果fdt_vaddr为None,则说明还没有进行内核虚拟地址空间的映射,此时返回物理地址
43 if self.fdt_vaddr.is_none() {
44 return VirtAddr::new(self.fdt_paddr.data());
45 }
46 self.fdt_vaddr.unwrap()
47 }
48 }
49
50 static mut BOOT_HARTID: u32 = 0;
51 static mut BOOT_FDT_PADDR: PhysAddr = PhysAddr::new(0);
52
53 #[no_mangle]
kernel_main(hartid: usize, fdt_paddr: usize) -> !54 unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! {
55 let fdt_paddr = PhysAddr::new(fdt_paddr);
56
57 unsafe {
58 BOOT_HARTID = hartid as u32;
59 BOOT_FDT_PADDR = fdt_paddr;
60 }
61 setup_trap_vector();
62 start_kernel();
63 }
64
65 /// 设置中断、异常处理函数
setup_trap_vector()66 fn setup_trap_vector() {
67 let ptr = handle_exception as *const () as usize;
68
69 unsafe {
70 riscv::register::stvec::write(ptr, riscv::register::stvec::TrapMode::Direct);
71 // Set sup0 scratch register to 0, indicating to exception vector that
72 // we are presently executing in kernel.
73 riscv::register::sscratch::write(0);
74 }
75 }
76
77 #[inline(never)]
print_node(node: FdtNode<'_, '_>, n_spaces: usize)78 fn print_node(node: FdtNode<'_, '_>, n_spaces: usize) {
79 (0..n_spaces).for_each(|_| print!(" "));
80 println!("{}/", node.name);
81 node.properties().for_each(|p| {
82 (0..n_spaces + 4).for_each(|_| print!(" "));
83
84 if p.name == "compatible" {
85 println!("{}: {:?}", p.name, p.as_str());
86 } else {
87 println!("{}: {:?}", p.name, p.value);
88 }
89 });
90
91 for child in node.children() {
92 print_node(child, n_spaces + 4);
93 }
94 }
95
96 /// 解析fdt,获取内核启动参数
97 #[inline(never)]
parse_dtb()98 unsafe fn parse_dtb() {
99 let fdt_paddr = boot_params().read().arch.fdt_paddr;
100 if fdt_paddr.is_null() {
101 panic!("Failed to get fdt address!");
102 }
103
104 open_firmware_fdt_driver()
105 .early_scan_device_tree()
106 .expect("Failed to scan device tree at boottime.");
107 }
108
109 #[inline(never)]
early_setup_arch() -> Result<(), SystemError>110 pub fn early_setup_arch() -> Result<(), SystemError> {
111 SbiDriver::early_init();
112 let hartid = unsafe { BOOT_HARTID };
113 let fdt_paddr = unsafe { BOOT_FDT_PADDR };
114
115 let fdt =
116 unsafe { fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!") };
117
118 let mut arch_boot_params_guard = boot_params().write();
119 arch_boot_params_guard.arch.fdt_paddr = fdt_paddr;
120 arch_boot_params_guard.arch.fdt_size = fdt.total_size();
121 arch_boot_params_guard.arch.boot_hartid = ProcessorId::new(hartid);
122 // debug!("fdt_paddr: {:?}, fdt_size: {}", fdt_paddr, fdt.total_size());
123 drop(arch_boot_params_guard);
124
125 info!(
126 "DragonOS kernel is running on hart {}, fdt address:{:?}",
127 hartid, fdt_paddr
128 );
129 early_boot_init(BootProtocol::DragonStub).expect("Failed to init boot protocol!");
130 mm_early_init();
131
132 print_node(fdt.find_node("/").unwrap(), 0);
133
134 unsafe { parse_dtb() };
135
136 for x in mem_block_manager().to_iter() {
137 debug!("before efi: {x:?}");
138 }
139
140 efi_init();
141
142 open_firmware_fdt_driver().early_init_fdt_scan_reserved_mem();
143
144 return Ok(());
145 }
146
147 #[inline(never)]
setup_arch() -> Result<(), SystemError>148 pub fn setup_arch() -> Result<(), SystemError> {
149 init_local_context();
150 return Ok(());
151 }
152
153 #[inline(never)]
setup_arch_post() -> Result<(), SystemError>154 pub fn setup_arch_post() -> Result<(), SystemError> {
155 // todo
156 return Ok(());
157 }
158