2024-05-27
最后编辑于:2024-09-15
__start()
中la t0, __rt_init
,jr 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
初始化帧分配器,管理从 _end
到 VIRT_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);
设置相关的中断寄存器(sext
、stimer
、ssoft
),并启用中断(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()
}