Crate polyhal

source ·
Expand description

This is a crate to help you supporting multiple platforms.

If you want to use this crate, you should implement the following trait in your code.

/// impl
pub struct PageAllocImpl;

impl PageAlloc for PageAllocImpl {
    fn alloc(&self) -> PhysPage {
        frame_alloc()
    }

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

/// kernel interrupt
#[polyhal::arch_interrupt]
fn kernel_interrupt(ctx: &mut TrapFrame, trap_type: TrapType) {
    // println!("trap_type @ {:x?} {:#x?}", trap_type, ctx);
    match trap_type {
        Breakpoint => return,
        UserEnvCall => {
            // jump to next instruction anyway
            ctx.syscall_ok();
            log::info!("Handle a syscall");
        }
        StorePageFault(_paddr) | LoadPageFault(_paddr) | InstructionPageFault(_paddr) => {
            log::info!("page fault");
        }
        IllegalInstruction(_) => {
            log::info!("illegal instruction");
        }
        Time => {
            log::info!("Timer");
        }
        _ => {
            log::warn!("unsuspended trap type: {:?}", trap_type);
        }
    }
}

#[polyhal::arch_entry]
/// kernel main function, entry point.
fn main(hartid: usize) {
    if hartid != 0 {
        return;
    }

    println!("[kernel] Hello, world!");
    allocator::init_allocator();
    logging::init(Some("trace"));
    println!("init logging");

    // Init page alloc for polyhal
    polyhal::init(&PageAllocImpl);

    get_mem_areas().into_iter().for_each(|(start, size)| {
        println!("init memory region {:#x} - {:#x}", start, start + size);
        frame::add_frame_range(start, start + size);
    });
    panic!("end of rust_main!");
}

The main(hardid: usize) is the entry point.

You can find details in the example.

In this crate you can find some interfaces to use. These interfaces are classified into some structures.

PhysPage: PhysicalPage And its associated functions.

PhysAddr: PhysicalAddr And its associated functions.

VirtPage: VirtualPage And its associated functions.

VirtAddr: VirtualAddr And its associated functions.

IRQ: Interrupt ReQuest management, includes enable and disable.

Barrier: Memory barrier operations.

MultiCore: MultiCore operations. Now only [multicore::MultiCore::boot_all] is available.

PageTable: PageTable and its associated functions.

MappingFlags: MappingFlags, This is an abstraction of pagetable flags.

TLB: TLB operations.

PageTableWrapper: PageTableWrapper. It will dealloc all pagetable leaf when it was dropping.

Time: Time and its associated functions.

Instruction: Some platform instruction.

There also provides a debugging console(recommanded only for debugging).

DebugConsole: A console for debugging.

This crate provides a [TrapFrame], you can operate it through index with [TrapFrameArgs].

If you are using kernel task. You should to enable feature kcontext. Then you can use kernel task context structure [KContext], and manipulate it with [KContextArgs].

You can switch kcontext through [context_switch_pt] or [context_switch]

There are also some consts.

[VIRT_ADDR_START]: This is a higher half kernel offset address. [USER_VADDR_END]: End of the user address range. [PAGE_SIZE]: The size of the page.

You can get some device information using the functions below. [get_mem_areas]: Get the avaliable memorys. [get_fdt]: Get the Fdt structure(fdt is a rust dtb operation crate). [get_cpu_num]: Get the number of cpus.

TIPS: You should have finished [init] before using [get_mem_areas] and [get_fdt].

Re-exports§

Modules§

Structs§

Enums§

  • This structure indicates size of the page that will be mapped.

Attribute Macros§