Boot

2024-05-27

最后编辑于:2024-09-15

    #umi
    #OS

Boot

__start()la t0, __rt_initjr t0

进入__rt_init, 此处的参数

On entry to a stage or payload (including SELF payloads),

  • all harts are running.
  • A0 is the hart ID.
  • A1 is the pointer to the Flattened Device Tree (FDT).
  • A2 contains the additional program calling argument:
    • cbmem_top for ramstage
    • the address of the payload for opensbi

清空bss

if !GLOBAL_INIT.load(Relaxed) {
	r0::zero_bss(&mut _sbss, &mut _ebss);
}

初始化TLS

unsafe {
	let tp: *mut u32;
	asm!("mv {0}, tp", out(reg) tp);

	let len = (&_tdata_size) as *const u32 as usize;
	tp.copy_from_nonoverlapping(&_stdata, len / mem::size_of::<u32>());
}

禁用中断,初始化trap

unsafe { ksync::disable() };

unsafe { crate::trap::init() };

klog::init_logger 初始化日志 kalloc::init 初始化内核堆内存。 将 GLOBAL_INIT 设置为 true,表明全局初始化已完成。 调用 hart_id::init_bsp_id 初始化引导处理器(BSP)的 ID。 调用 kmem::init_frames 初始化帧分配器,管理从 _endVIRT_END 的内存区域。 调用 hart_id::init_hart_id 初始化当前硬件线程的 ID。

if !GLOBAL_INIT.load(Relaxed) {
    // Init logger.
    unsafe { klog::init_logger(log::Level::Warn) };

    // Init the kernel heap.
    unsafe { kalloc::init(&mut _sheap, &mut _eheap) };

    // Can't use cmpxchg here, because `zero_bss` will reinitialize it to zero.
    GLOBAL_INIT.store(true, Release);
    hart_id::init_bsp_id(hartid);

    // Init the frame allocator.
    unsafe {
        let range = (&_end as *const u8).into()..VIRT_END.into();
        kmem::init_frames(range)
    }
}
hart_id::init_hart_id(hartid);

设置相关的中断寄存器(sextstimerssoft),并启用中断(spie)。 调用run_art 函数,传递 payload 参数。

启动[[异步调度]] ^952402

异步运行时退出后,再次调用 ksync::disable 禁用中断。

unsafe {
    sie::set_sext();
    sie::set_stimer();
    sie::set_ssoft();
    sstatus::set_spie();

    ksync::enable();
}

run_art(payload);
unsafe { ksync::disable() };

bsp负责关机,否则进入无限循环等待,防止函数返回。

if hart_id::is_bsp() {
    sbi_rt::system_reset(Shutdown, NoReason);
}
loop {
    core::hint::spin_loop()
}