SomeHAL - 平台硬件抽象层实现
SomeHAL (Sparreal Hardware Abstraction Layer) 是 Sparreal OS 的平台硬件抽象层实现,提供统一的跨平台硬件接口,位于内核核心 (sparreal-kernel) 和底层架构支持 (someboot) 之间。
📋 目录
概述
SomeHAL 负责将通用的内核接口与具体的硬件平台连接起来,提供:
- 统一平台接口: 通过
PlatOptrait 定义平台操作抽象 - 多架构支持: AArch64 (ARMv8) 和 LoongArch64
- 中断管理: GICv2/GICv3 支持,运行时版本检测
- 驱动集成: 通过
rdrive驱动框架管理硬件设备 - 内存抽象: 统一的 I/O 内存重映射接口
设计原则
- 分层设计:
sparreal-rt→somehal→someboot - 平台无关: 内核核心不需要知道底层硬件细节
- 驱动优先: 硬件初始化通过驱动系统自动完成
- 类型安全: 充分利用 Rust 的类型系统确保安全性
架构支持
AArch64 (ARMv8)
支持的中断控制器:
- ✅ GICv2 (ARM Cortex-A15 GIC, GIC-400)
- ✅ GICv3 (现代 ARMv8 处理器)
- 🔧 运行时版本自动检测
定时器支持:
- ARM Generic Timer (EL1/EL2)
虚拟化扩展:
- GICv2: GICH/GICV 虚拟接口支持
- GICv3: 完整的虚拟化支持
LoongArch64
- 基础架构支持
- 平台特定的中断控制器
主要特性
🔄 多版本 GIC 支持
// 运行时自动检测 GIC 版本
🎯 驱动系统集成就绪
- 通过设备树 (FDT) 自动探测硬件
- 支持动态设备注册
- 统一的探测优先级管理
🔌 中断处理统一接口
// 上层统一接口,底层版本无关
目录结构
somehal/
├── src/
│ ├── arch/ # 架构特定实现
│ │ ├── aarch64/ # AArch64 架构
│ │ │ ├── gic/ # 通用中断控制器
│ │ │ │ ├── mod.rs # GIC 统一接口
│ │ │ │ ├── v2.rs # GICv2 实现
│ │ │ │ └── v3.rs # GICv3 实现
│ │ │ ├── systick.rs # 系统定时器
│ │ │ └── mod.rs # AArch64 平台实现
│ │ └── loongarch64/ # LoongArch64 架构
│ ├── common.rs # 平台通用定义
│ ├── driver.rs # 驱动管理
│ ├── irq.rs # 中断接口
│ ├── lib.rs # 库入口
│ └── setup.rs # 初始化设置
├── Cargo.toml # 项目配置
└── README.md # 本文档
快速开始
使用 Entry 宏
SomeHAL 提供了 #[somehal::entry] 宏来自动化初始化流程:
use ;
use mem;
// 1. 定义内核类型并实现 KernelOp trait
;
// 2. 使用 entry 宏自动初始化
!
宏的参数要求:
- 必需参数: 必须指定实现
KernelOptrait 的类型(如Kernel) - 自动行为: 宏会在函数开头自动插入
somehal::init(&<type>)调用 - 错误提示: 无参数时会显示清晰的编译错误
KernelOp Trait
所有使用 SomeHAL 的平台必须实现 KernelOp trait:
use KernelOp;
初始化流程
-
自动初始化 (
#[somehal::entry(Kernel)])- 宏自动调用
somehal::init(&Kernel) - 设置内核操作回调接口
- 宏自动调用
-
驱动系统启动 (
somehal::post_paging())- 在分页系统初始化后调用
- 通过设备树自动探测硬件
- 初始化中断控制器和定时器
中断处理
use *;
// 使能中断
irq_set_enable;
// 禁用中断
irq_set_enable;
// 获取系统定时器 IRQ
let timer_irq = systick_irq;
平台操作
SomeHAL 通过 KernelOp trait 提供平台特定功能:
use KernelOp;
// 在平台运行时中实现
;
平台接口
核心接口
SomeHAL 提供两个核心接口:
1. KernelOp Trait
内核操作接口,由平台运行时实现:
2. PlatOp Trait
平台操作接口,由架构实现提供:
初始化函数
| 函数 | 调用时机 | 说明 |
|---|---|---|
init(kernel) |
entry 宏自动调用 | 设置内核操作回调 |
post_paging() |
分页系统初始化后 | 启动驱动系统,初始化硬件设备 |
I/O 内存映射
通过 KernelOp::ioremap 进行内存映射:
// 在内核代码中
let virt_addr = ioremap?;
特性标志
| 特性 | 描述 | 默认 |
|---|---|---|
efi |
UEFI 固件支持 | No |
hv |
虚拟化支持 (Hypervisor) | No |
mmu |
MMU/分页支持 | No |
uspace |
用户空间支持 | No |
使用示例
[]
= { = "0.5", = ["hv", "uspace"] }
依赖说明
核心依赖
someboot: 底层架构抽象和引导支持rdrive: 统一驱动框架rdif-intc: 中断控制器驱动接口page-table-generic: 通用页表管理kernutil: 内核工具库(StaticCell 等)
AArch64 特定依赖
aarch64-cpu: AArch64 寄存器访问arm-gic-driver: ARM GIC 驱动实现tock-registers: 寄存器操作接口
构建依赖
somehal-macros: 平台宏(entry、irq_handler 等)
开发指南
创建新平台
使用 SomeHAL 创建新平台运行时的步骤:
1. 定义内核类型
// platform/my-platform/src/lib.rs
use KernelOp;
;
2. 使用 entry 宏
!
3. 实现平台特定接口
在 hal_impl.rs 中实现内核的 HAL trait:
use al;
;
添加新架构支持
- 在
src/arch/下创建新目录 - 实现
PlatOptrait - 提供中断控制器支持(如果需要)
- 实现定时器接口
- 更新
src/lib.rs添加条件编译路径
添加新的中断控制器
参考 GICv2/v3 实现模式:
- 创建独立的模块文件
- 实现统一的接口函数:
init_cpu(): CPU 接口初始化handle_irq(): 中断处理irq_set_enable(): IRQ 使能控制
- 在上层添加版本检测逻辑
- 使用
StaticCell管理全局状态
宏使用最佳实践
entry 宏 (#[somehal::entry]):
- ✅ 必须提供参数: 指定实现
KernelOp的类型 - ✅ 每个项目仅一次: 整个依赖图只能有一个入口点
- ✅ 函数签名:
fn main() -> !或unsafe fn main() -> ! - ❌ 不要手动调用:
somehal::init()由宏自动处理
irq_handler 宏 (#[somehal::irq_handler]):
代码风格
- 使用
#![no_std]环境 - 遵循 Rust 2024 Edition 规范
- 使用
logcrate 进行日志输出 - 错误处理使用
thiserror和anyhow
相关文档
- Sparreal OS CLAUDE.md - 项目总览
- someboot 文档 - 底层架构抽象
- sparreal-kernel 文档 - 内核核心
许可证
本项目采用与 Sparreal OS 相同的开源许可证。
贡献
欢迎提交 Issue 和 Pull Request!
在提交代码前,请确保:
- 代码通过
cargo fmt格式化 - 通过
cargo clippy检查 - 在目标平台上测试通过
- 更新相关文档
最后更新: 2026-01-21