1. 介绍 #
在移植 Arceos 的过程中,实现了一些 seL4 系统上特有的功能,比如中断管理、内存管理等。这些模块和 arceos 无关,同时可以用于后续其他 os 的移植,因此抽象出来为 crate。
抽象的 crate 为两个
2. 背景 #
得益于 seL4 中的 capability 设计,其安全性很高,但同样也增加了使用复杂度。如果我们能将各种成熟 OS 移植到其上,作为操作系统服务,那无疑会大大降低其使用难度,增加适配性。比如将 Linux 移植上去,那可以继承所有 Linux 生态,解决了 seL4 用户态开发困难的问题。
进行这种移植,就需要将 seL4 相关的底层操作,如中断注册、内存分配和映射、任务切换等功能抽象出来,供操作系统服务调用,尽量减少移植工作量。
3. 实现 #
3.1 seL4 接口 #
目前 crate 提供向上的接口有
目前设计很粗糙,需要仔细考虑优化
/// 任务接口
#[def_plat_interface]
pub trait Sel4TaskIf {
/// Switches to the given seL4 task.
///
/// It returns the previous task's ID.
fn switch_task(prev_task: usize, next_task: usize) -> usize;
/// Creates a new seL4 task with the given parameters.
///
/// It returns the created task's ID.
fn create_task(
tid: usize,
entry_point: usize,
stack_top: usize,
priority: usize,
cpu_id: usize,
) -> usize;
/// Destroys the seL4 task with the given ID.
fn destroy_task(task_id: usize);
/// Migrates the seL4 task with the given ID to the target CPU.
fn migrate_task(task_id: usize, target_cpu_id: usize);
/// Starts the seL4 task with the given ID.
fn start_task(task_id: usize);
/// Stops the seL4 task with the given ID.
fn stop_task(task_id: usize);
/// Checks if the current task is the initial task.
fn is_init_task() -> bool;
/// Get Current Sel4 Task ID
fn sel4_task_id() -> usize;
/// Set Current Sel4 Task ID
fn set_sel4_task_id(tid: usize);
}
/// 事件处理接口
#[def_plat_interface]
pub trait Sel4EventIf {
/// 事件处理函数
fn handler(cpu_id: usize) -> !;
}
/// 中断相关接口
#[cfg(feature = "irq")]
#[def_plat_interface]
pub trait Sel4IrqIf {
/// Disables IRQs.
fn disable_irqs();
/// Enables IRQs.
fn enable_irqs();
/// Checks if IRQs are enabled.
fn irqs_enabled() -> bool;
}
3.2 oskit 的实现 #
oskit 主要包括以下部分实现
- 中断管理,包括注册和处理中断
- 内存管理,内存分配并映射,类似页表相关的操作
- 能力管理,能力分配回收功能,上层无需考虑回收,直接使用分配即可
- IPC 事件定义
4 讨论 #
- kit 的实现依赖 alloc,导致上层操作系统服务在初始化时就必须分配好堆空间。计划是至少将内存管理功能一部分剥离,不依赖 alloc,在其初始化中分配堆空间。
- 目前接口设计相当随意,用到什么加什么,需要仔细设计