设备管理
rdrive 是驱动框架的核心管理 crate。它 负责驱动注册(DriverRegister)、设备探测(probe)分发、类型化设备 registry 和设备查询。rdrive 不包含具体硬件逻辑,也不依赖任何 OS runtime 或平台 HAL。
源码位于 drivers/rdrive/src/,入口 lib.rs。
核心 API
rdrive 的公共 API 围绕平台初始化、驱动注册和设备查询三组能力:
// 平台来源初始化
pub enum Platform {
Static,
Fdt { addr: NonNull<u8> },
Acpi(probe::acpi::AcpiRoot),
}
pub fn init(platform: Platform) -> Result<(), DriverError>;
pub fn register_append(slice: DriverRegisterSlice);
// 探测
pub fn probe_pre_kernel() -> Result<(), ProbeError>;
pub fn probe_all(stop_if_fail: bool) -> Result<(), ProbeError>;
// 设备查询
pub fn get_device<T: DriverGeneric>(id: DeviceId) -> Result<Device<T>, GetDeviceError>;
pub fn get_one<T: DriverGeneric>() -> Option<Device<T>>;
pub fn get_list<T: DriverGeneric>() -> Vec<Device<T>>;
Platform 是初始化时传入的平台来源。仓库内置平台默认使用 FDT 或 ACPI;外部静态平台使用 Platform::Static。init() 只能调用一次,重复调用 panic。
Manager
Manager 是 rdrive 的核心,源码位于 manager.rs。它只持有两个状态:
pub struct Manager {
pub registers: RegisterContainer,
pub(crate) dev_container: DeviceContainer,
}
registers:所有已注册的DriverRegister,按ProbeLevel和ProbePriority排序。dev_container:类型化设备 registry,BTreeMap<DeviceId, DeviceOwner>。
Manager 全局唯一,通过 Once<Mutex<Manager>> 保护:
static CONTAINER: Once<Mutex<Manager>> = Once::new();
pub(crate) fn container() -> &'static Mutex<Manager> { ... }
Mutex 使用 ax-kspin::SpinRaw,在多核环境下提供互斥访问。所有写操作(register、probe、insert device)经过 edit() 闭包,所有读操作(query)经过 container().lock()。
DriverRegister
DriverRegister 描述一个驱动的注册信息,源码位于 register/mod.rs:
pub struct DriverRegister {
pub name: &'static str,
pub level: ProbeLevel,
pub priority: ProbePriority,
pub probe_kinds: &'static [ProbeKind],
}
| 字段 | 含义 |
|---|---|
name | 驱动名,用于日志和诊断 |
level | PreKernel(内核前早期 probe)或 PostKernel(普通 probe) |
priority | 同 level 内的排序权重,值小者优先 |
probe_kinds | 该驱动支持的平台来源和匹配规则 |
ProbePriority 预定义了关键平台设备的优先级:
pub const CLK: ProbePriority = ProbePriority(6); // 时钟控制器
pub const INTC: ProbePriority = ProbePriority(10); // 中断控制器
pub const DEFAULT: ProbePriority = ProbePriority(256);
时钟和中断控制器必须在其它设备之前 probe,因为后续设备的 clk 和 IRQ 解析依赖它们。
ProbeKind 与 backend 分发
ProbeKind 是多来源分发的基础:
pub enum ProbeKind {
Static { on_probe: static_::FnOnProbe },
Fdt { compatibles: &'static [&'static str], on_probe: fdt::FnOnProbe },
Acpi { ids: &'static [acpi::AcpiId], on_probe: acpi::FnOnProbe },
Pci { on_probe: pci::FnOnProbe },
}
一个 DriverRegister 可以同时声明多个 ProbeKind,例如同一驱动既能从 FDT 发现,也能从 PCI 枚举。各 backend 的职责如下:
| backend | 独立状态 | 匹配输入 | probe 输入 | 职责 |
|---|---|---|---|---|
probe::static_ | System { probed_names } | 显式注册的 driver name | PlatformDevice | 保留外部平台和板级 glue 的手工注册能力 |
probe::fdt | System { fdt, phandle_map, probed } | compatible + node status | FdtInfo + PlatformDevice | FDT 设备树解析与匹配 |
probe::acpi | System { root, routing, pci, probed } | HID/CID + ACPI device | AcpiInfo + PlatformDevice | ACPI source、MCFG/GSI routing、PCI _PRT |
probe::pci | PCIe controller enumerator | vendor/device/class | endpoint + PlatformDevice | PCIe 二阶段 endpoint probe |
probe_pre_kernel() 只运行 ProbeLevel::PreKernel,通过 backend 分发器执行 Static、FDT、ACPI 中的早期 probe(interrupt controller、clock、timer、systick、pinmux、PCIe root complex)。PCI endpoint 枚举依赖已注册的 PCIe controller,因此在普通 probe 阶段触发。probe_all(stop_if_fail) 运行普通设备 probe,再执行 PCI endpoint 枚举。