### RISC-V Linux 软件栈概览 (OpenSBI / U-Boot / Kernel) 在 Nuclei RISC-V Linux SDK 中,系统启动是一个分层的过程,涉及三个核心组件。它们各自独立编译,但通过 **设备树(DTS)** 紧密耦合,以确保对硬件描述的一致性。 #### 1. 三层架构简介 | 组件 | 角色与职责 | 参考文档依据 | | :--- | :--- | :--- | | **OpenSBI** (Open Supervisor Binary Interface) | **一级引导加载程序**。运行在 Machine Mode (M态)。负责初始化最底层的硬件(如PLIC、Timer),并为上层操作系统(U-Boot/Linux)提供 SBI 服务(如关机、重启、时间服务)。 | 文档中 `freeloader` 实际包含了 Small boot code + OpenSBI + Uboot + DTB。 | | **U-Boot** (Universal Boot Loader) | **二级引导加载程序**。运行在 Supervisor Mode (S态)。负责加载 Linux 内核镜像和 Initramfs,并传递启动参数(bootargs)。 | 文档中 `BOOT_MODE` 支持 `sd` (SD卡) 和 `flash` (仅Flash) 启动。 | | **Linux Kernel** | **操作系统内核**。运行在 S态。直接管理硬件资源,依赖设备树了解硬件拓扑。 | 默认分支文档中 Linux 版本为 6.6.y,支持 SMP。 | #### 2. 核心关注点:设备树 (DTS) 的协同与维护 根据 Nuclei Linux SDK 的设计,**OpenSBI、U-Boot 和 Linux Kernel 都会使用到设备树(DTS)**。这是一个非常关键的维护点: * **一致性要求**: 这三个软件栈虽然各自编译,但它们对硬件的描述必须保持一致。特别是**CPU 的频率、总线频率(PERIPH_HZ)以及内存映射**。 * **同步维护策略**: 如果你在其中一个组件(例如 Linux Kernel)中修改了 DTS(比如增加了新的外设节点或修改了时钟频率),**必须**同步更新其他两个组件对应的 DTS 文件。 * *场景举例*:如果你在 Linux 的 DTS 中将 CPU 频率改为 100MHz,但 OpenSBI 中的 DTS 仍认为是 50MHz,会导致 OpenSBI 提供的时间服务(SBI Timer)出现严重误差,进而导致 Linux 内核启动后时间流逝异常。 #### 3. Nuclei 特定硬件配置:CLINT Timer 地址 在编写或修改 DTS 时,关于定时器(Timer)的配置有一个特定的硬件细节需要注意: * **CLINT 节点配置**: 在 DTS 中定义 `clint` 节点时,其寄存器基地址的计算方式为: > **CLINT 基地址 = Nuclei SysTimer 基地址 + 0x1000** * **配置建议**: 请在编写 DTS 时,务必核对硬件实际的 SysTimer 基地址,并在此基础上加上 `0x1000` 偏移量来填写 `reg` 属性。如果地址填写错误,OpenSBI 将无法正确读取计数器(mtime)或设置比较器(mtimecmp),导致系统无法产生时钟中断和正确的IPI核间中断,进而导致多核启动异常,其他核心无法正常唤醒等问题。 --- ### 附录:Nuclei SDK 中的典型 DTS 文件结构 为了方便你进行同步维护,以下是 Nuclei SDK 中常见的 DTS 文件存放位置(基于参考文档路径 `conf/evalsoc/`): * **`nuclei_rv64imafdc.dts`** (示例文件名,根据 ISA 不同后缀变化) * 这是主要的硬件描述文件,通常被 OpenSBI 和 Linux 共用或作为模板。 * **注意**:文档提到 `xlspike` (内部仿真器) 有专用的 `nuclei_rv64imafdc_sim.dts`,请勿混淆。 * **U-Boot 的 DTS**: U-Boot 通常会编译自己的 DTS 生成 DTB,用于在启动阶段传递给 Kernel。虽然 U-Boot 的配置主要在 `uboot.cmd`,但它依赖的环境变量和内存布局需与 DTS 中的内存描述匹配。 **维护检查清单 (Checklist):** 1. [ ] 修改 Linux DTS 时,是否同步修改了 OpenSBI 的 platform DTS? 2. [ ] Timer 的 `reg` 地址是否已加上 `0x1000` 偏移? 3. [ ] CPU/PERIPH 频率在 `build.mk` (Makefile配置) 和 DTS (硬件描述) 中是否一致?
RISC-V Linux 软件栈概览 (OpenSBI / U-Boot / Kernel)
在 Nuclei RISC-V Linux SDK 中,系统启动是一个分层的过程,涉及三个核心组件。它们各自独立编译,但通过 设备树(DTS) 紧密耦合,以确保对硬件描述的一致性。
1. 三层架构简介
freeloader实际包含了 Small boot code + OpenSBI + Uboot + DTB。BOOT_MODE支持sd(SD卡) 和flash(仅Flash) 启动。2. 核心关注点:设备树 (DTS) 的协同与维护
根据 Nuclei Linux SDK 的设计,OpenSBI、U-Boot 和 Linux Kernel 都会使用到设备树(DTS)。这是一个非常关键的维护点:
这三个软件栈虽然各自编译,但它们对硬件的描述必须保持一致。特别是CPU 的频率、总线频率(PERIPH_HZ)以及内存映射。
如果你在其中一个组件(例如 Linux Kernel)中修改了 DTS(比如增加了新的外设节点或修改了时钟频率),必须同步更新其他两个组件对应的 DTS 文件。
3. Nuclei 特定硬件配置:CLINT Timer 地址
在编写或修改 DTS 时,关于定时器(Timer)的配置有一个特定的硬件细节需要注意:
CLINT 节点配置:
在 DTS 中定义
clint节点时,其寄存器基地址的计算方式为:配置建议:
请在编写 DTS 时,务必核对硬件实际的 SysTimer 基地址,并在此基础上加上
0x1000偏移量来填写reg属性。如果地址填写错误,OpenSBI 将无法正确读取计数器(mtime)或设置比较器(mtimecmp),导致系统无法产生时钟中断和正确的IPI核间中断,进而导致多核启动异常,其他核心无法正常唤醒等问题。附录:Nuclei SDK 中的典型 DTS 文件结构
为了方便你进行同步维护,以下是 Nuclei SDK 中常见的 DTS 文件存放位置(基于参考文档路径
conf/evalsoc/):nuclei_rv64imafdc.dts(示例文件名,根据 ISA 不同后缀变化)xlspike(内部仿真器) 有专用的nuclei_rv64imafdc_sim.dts,请勿混淆。U-Boot 的 DTS:
U-Boot 通常会编译自己的 DTS 生成 DTB,用于在启动阶段传递给 Kernel。虽然 U-Boot 的配置主要在
uboot.cmd,但它依赖的环境变量和内存布局需与 DTS 中的内存描述匹配。维护检查清单 (Checklist):
reg地址是否已加上0x1000偏移?build.mk(Makefile配置) 和 DTS (硬件描述) 中是否一致?