Skip to content

template 解析

yufeng edited this page May 9, 2024 · 2 revisions

main.rs

main.rs 定义了程序的入口 main(在启动阶段由 polyhal 跳转至此),中断的处理函数 interrupt_handler。以及一个 trait PageAlloc 的实现 PageAllocImpl.

main

#[polyhal::arch_entry]
pub fn main(hart_id: usize) {
    println!("run default @ {}", hart_id);
    crate::allocator::init_allocator();
    crate::logging::init(Some("trace"));
    println!("init logging");

    // Init polyhal with page alloc, This init will init every platform
    polyhal::init(&PageAllocImpl);

    // get hardware available memory regions
    get_mem_areas().into_iter().for_each(|(start, size)| {
        println!("init memory region {:#x} - {:#x}", start, start + size);
        crate::frame::add_frame_range(start, start + size);
    });
    
    println!("[kernel] exited successfully");
}

main 函数上有一个属性宏 #[polyhal::arch_entry],这个标识 main 函数是程序的入口,main 函数有一个参数 hart_id,当从 polyhal 进入到这个函数时会携带当前的核心 id

println 是在 logging.rs 中定义的一个实现,可以输出信息。 polyhalinit 函数需要 kernel 支持 rustGlobalAlloc 功能来使用 alloc 库下的一些东西,所以在调用 polyhal::init 之前需要先对 alloc 进行初始化。crate::logging::init 主要用于调试信息的输出,对 polyhal 的使用并无影响。然后就可以使用 polyhal::init 函数来完成 polyhal::init 的最终初始化。(可能你会感到奇怪,为什么不在 main 函数之前完成 polyhal 的初始化,可以参考 为什么需要 polyhal::init 函数)

在初始化之后我们就可以使用 polyhal 的全部功能了,比如我们可以通过 get_mem_areas 函数来获取平台的可用内存范围。获取到内存范围后就可以将可用内存范围传递给 kernel 管理内存的模块,这里是调用 crate::frame::add_frame_range 来初始化内存。

interrupt handler

#[polyhal::arch_interrupt]
fn interrupt_handler(ctx: &mut TrapFrame, trap_type: TrapType) {
    println!("trap_type @ {:x?} {:#x?}", trap_type, ctx);
}

interrupt_handler 函数在内核发生中断或者异常的时候被调用,首先会在 polyhal 中的处理程序首先处理和封装,然后再调用这里的函数。ctx 是中断发生的上下文,trap_type 是中断发生的类型,具体信息可以参考 polyhal 的文档。

PageAllocImpl

struct PageAllocImpl;

impl PageAlloc for PageAllocImpl {
    fn alloc(&self) -> polyhal::addr::PhysPage {
        crate::frame::frame_alloc()
    }

    fn dealloc(&self, ppn: polyhal::addr::PhysPage) {
        crate::frame::frame_dealloc(ppn)
    }
}

在介绍 main 函数的时候我们已经描述过了,我们需要实现一个 PageAlloc Trait,然后在 polyhal::init 的时候将实现传递给 polyhalalloc 为申请一个物理页,目前支持的物理页大小为 4KB,且这里申请的物理页仅在 dealloc 的时候才会被释放(TIPS: 如果在相应的物理页结构上实现了 Drop, 可能会产生一些异常行为)。