Crate axplat

Source
Expand description

§axplat

Crates.io Docs.rs CI

This crate provides a unified abstraction layer for diverse hardware platforms. It allows kernel developers to bootstrap custom kernels across various platforms and interact with essential peripherals using hardware-agnostic APIs.

Interfaces can be divided into the following categories:

CategoryTraitDescription
initInitIfPlatform initialization
consoleConsoleIfConsole input and output
powerPowerIfPower management
memMemIfPhysical memory information
timeTimeIfTime-related operations
irqIrqIfInterrupt request handling

Each category of interfaces provides a trait (e.g., ConsoleIf) for a platform package to implement. You can use the corresponding platform-related functions in your project directly from the axplat crate without importing the specific platform package.

§How to use in your kernel project

// Link you kernel with the specific platform package in some crate.
// extern crate your_platform_crate;

// Write your kernel code (can be in another crate).
#[axplat::main]
fn kernel_main(cpu_id: usize, arg: usize) -> ! {
    // Initialize trap, console, time.
    axplat::init::init_early(cpu_id, arg);
    // Initialize platform peripherals (not used in this example).
    axplat::init::init_later(cpu_id, arg);

    // Write your kernel code here.
    axplat::console_println!("Hello, ArceOS!");

    // Power off the system.
    axplat::power::system_off();
}

More APIs can be found in the documentation. More example kernels can be found in the examples directory.

§How to write a platform package

§1. Implement each interface trait
use axplat::impl_plat_interface;

/// Implementation of Platform initialization.
struct InitIfImpl;

#[impl_plat_interface]
impl axplat::init::InitIf for InitIfImpl {
    fn init_early(cpu_id: usize, arg: usize) { /* ... */ }
    fn init_later(cpu_id: usize, arg: usize) { /* ... */ }
    fn init_early_secondary(cpu_id: usize) { /* ... */ }
    fn init_later_secondary(cpu_id: usize) { /* ... */ }
}

/// Implementation of Console input and output.
struct ConsoleIfImpl;

#[impl_plat_interface]
impl axplat::console::ConsoleIf for ConsoleIfImpl {
    fn write_bytes(bytes: &[u8]) { /* ... */ }
    fn read_bytes(bytes: &mut [u8]) -> usize { /* ... */ 0 }
}

// Implementation of other traits...
§2. Implement platform bootstrapping code and call the entry function of axplat
#[unsafe(no_mangle)]
unsafe extern "C" fn __start() -> ! {
    // platform bootstrapping code here.
    /* ... */

    // Call the entry function of axplat.
    axplat::call_main(0, 0xdeadbeef); // cpu_id = 0, arg = 0xdeadbeef
}

We also provide a cargo plugin called cargo-axplat for creating a new platform package and adding it into your project.

Some examples of platform packages for various platforms are listed in the platforms directory.

Modules§

console
Console input and output.
init
Platform initialization.
irqirq
Interrupt request (IRQ) handling.
mem
Physical memory information.
power
Power management.
time
Time-related operations.

Macros§

assert_str_eq
Checks that two strings are equal. If they are not equal, it will cause a compile-time error. And the message will be printed if it is provided.
console_print
Simple console print operation.
console_println
Simple console print operation, with a newline.

Functions§

call_main
Call the function decorated by axplat::main for the primary core.
call_secondary_mainsmp
Call the function decorated by axplat::secondary_main for secondary cores.

Attribute Macros§

impl_plat_interface
Implement the interface for a struct.
main
Marks a function to be called on the primary core after the platform initialization.
secondary_mainsmp
Marks a function to be called on the secondary cores after the platform initialization.