分析对象最新主线 U-Boot 源代码u-boot-latestU-Boot 版本2026.07-rc2源码获取git clone --depth 1 https://github.com/u-boot/u-boot.git分析重点RISC-V 64-bitRV64I平台支持代码许可证GPL-2.01. 概览与此前分析的2013.10-rc2 Sunxi 版本相比最新的 U-Boot2026.07-rc2在架构设计、驱动模型、配置系统等方面发生了革命性的演进。RISC-V 作为相对较新的处理器架构其支持代码充分体现了现代 U-Boot 的设计思想设备模型Device Model, DM所有外设和 CPU 均通过统一的udevice/uclass框架管理设备树Device Tree驱动绝大多数板级参数通过.dts描述而非硬编码的 C 宏Kconfig 配置系统全面替代了老旧的boards.cfg 头文件宏配置方式模块化与可移植性RISC-V 32-bit 与 64-bit 共用大量代码通过编译时宏CONFIG_32BIT/CONFIG_64BIT区分2. RISC-V 代码在 U-Boot 中的位置u-boot/ ├── arch/riscv/ # RISC-V 架构核心重点分析目录 │ ├── cpu/ # CPU/SoC 级代码启动、DRAM、Cache │ ├── dts/ # 设备树源文件.dts / .dtsi │ ├── include/asm/ # 架构头文件CSR、SBI、encoding │ ├── lib/ # 架构库函数bootm、SMP、SBI、内存操作 │ ├── Kconfig # 架构级 Kconfig 配置 │ ├── config.mk # 编译标志与链接器配置 │ └── Makefile # 构建规则 ├── board/ # 板级支持包BSP │ ├── andestech/ae350 # Andes 开发板 │ ├── andestech/voyager # Andes Voyager │ ├── emulation/qemu-riscv # QEMU RISC-V Virt 平台 │ ├── sifive/unleashed # SiFive HiFive Unleashed │ ├── sifive/unmatched # SiFive HiFive Unmatched │ ├── starfive/visionfive2 # 赛昉 VisionFive 2 │ ├── thead/th1520_lpi4a # 平头哥 TH1520荔枝派 4A │ ├── spacemit/bananapi-f3 # 进迭时空 K1香蕉派 F3 │ ├── sophgo/milkv_duo # 算能 Milk-V Duo │ ├── sophgo/licheerv_nano # 算能 LicheeRV Nano │ ├── canaan/k230_canmv # 嘉楠 K230 CanMV │ ├── beagle/beaglev_fire # BeagleV-Fire (Microchip MPFS) │ ├── microchip/mpfs_generic # Microchip PolarFire SoC │ ├── openpiton/riscv64 # OpenPiton 多核平台 │ └── xilinx/mbv # AMD/Xilinx MicroBlaze V ├── drivers/ │ ├── cpu/riscv_cpu.c # RISC-V CPU 驱动DM 模型 │ ├── timer/riscv_timer.c # RISC-V 定时器驱动 │ ├── timer/riscv_aclint_timer.c # ACLINT 定时器 │ ├── serial/serial_htif.c # HTIF 串口QEMU/SPIKE │ └── rng/riscv_zkr_rng.c # Zkr 扩展硬件随机数驱动 ├── lib/efi_loader/ │ └── efi_riscv.c # RISC-V UEFI 支持RISCV_EFI_BOOT_PROTOCOL └── configs/ # defconfig 配置文件 ├── qemu-riscv64_defconfig ├── qemu-riscv64_smode_defconfig ├── sifive_unleashed_defconfig ├── visionfive2_defconfig └── ...3. 启动流程从复位到 LinuxRISC-V 64-bit3.1 汇编入口点arch/riscv/cpu/start.S这是 RISC-V 核心上电后执行的第一段代码同时支持RV32和RV64通过宏区分寄存器宽度#ifdef CONFIG_32BIT #define LREG lw #define SREG sw #define REGBYTES 4 #define RELOC_TYPE R_RISCV_32 #else #define LREG ld ; 64-bit 加载 #define SREG sd ; 64-bit 存储 #define REGBYTES 8 #define RELOC_TYPE R_RISCV_64 #endifstart.S的关键执行步骤读取 Hart ID通过CSR_MHARTIDM-mode获取当前硬件线程 ID保存到线程指针寄存器tp保存 DTB 指针固件如 OpenSBI传入的设备树地址保存在s1设置早期 Trap 处理程序将trap_entry写入mtvec/stvec屏蔽中断向mie/sie写入 0设置栈指针根据CONFIG_STACK_SIZE_SHIFT默认 14即 16KB为每个 CPU 分配独立栈SMP 场景下sp BASE - (hart_id shift)Hart 彩票机制非 XIP通过原子操作amoswap选出唯一的初始化主核Boot Hart其余核进入secondary_hart_loop等待 IPI初始化全局数据GD调用board_init_f_init_reserve()设置gd结构体保存启动信息将 DTB 地址和 Boot Hart ID 存入gd-arch调用 C 代码jal board_init_fSPL 路径CONFIG_XPL_BUILD清除.bss段调用spl_relocate_stack_gd()重定位栈和全局数据通过smp_call_function()同步通知从核更新栈和 GD调用board_init_r非 SPL 路径relocate_code()将 U-Boot 从 Flash/XIP 复制到 RAM处理 RELA 动态重定位.rela.dyn刷新 I-Cache / D-Cache跳转到 RAM 中的board_init_r()3.2 Trap 处理arch/riscv/cpu/mtrap.SRISC-V 的异常/中断入口点保存全部 32 个通用寄存器到栈上然后调用 C 函数handle_traptrap_entry: addi sp, sp, -32 * REGBYTES SREG x1, 1 * REGBYTES(sp) ... csrr a0, MODE_PREFIX(cause) # mcause / scause csrr a1, MODE_PREFIX(epc) # mepc / sepc csrr a2, MODE_PREFIX(tval) # mtval / stval mv a3, sp # 寄存器帧指针 jal handle_trap csrw MODE_PREFIX(epc), a0 # 更新返回地址 ... LREG x2, 2 * REGBYTES(sp) # 恢复 sp (x2) addi sp, sp, 32 * REGBYTES MODE_PREFIX(ret) # mret / sret32-bit 与 64-bit 差异仅体现在LREG/SREG的指令选择和栈帧大小128 bytes vs 256 bytes。4. 架构核心 C 代码分析4.1arch/riscv/cpu/cpu.c— CPU 初始化与 ISA 扩展管理这是 RISC-V 架构最重要的 C 文件之一负责4.1.1 ISA 字符串解析与扩展检测staticDECLARE_BITMAP(riscv_isa,RISCV_ISA_EXT_MAX);U-Boot 能够解析设备树中的riscv,isa属性如rv64imafdc_zba_zbb并将其映射为内部位图。支持的标准扩展包括扩展类别示例基础整数i,m,a,f,d,c位操作zba,zbb,zbc,zbs缓存管理zicbom,zicboz密码学zbkb,zbkc,zbkx,zknd,zkne,zknh,zkr向量扩展v,zve32x,zve64d,zvbb,zvkned监控/虚拟化h,smaia,ssaia,sstc4.1.2 CPU 功能配置intriscv_cpu_setup(void){/* 解析 ISA 字符串 */riscv_parse_isa_string(isa);/* 若支持 F/D 扩展启用浮点单元 */if(supports_extension(d)||supports_extension(f)){csr_set(MODE_PREFIX(status),MSTATUS_FS);csr_write(CSR_FCSR,0);}/* M-mode 下配置性能计数器、禁用分页 */if(CONFIG_IS_ENABLED(RISCV_MMODE)){csr_write(CSR_MCOUNTEREN,GENMASK(2,0));csr_write(CSR_SATP,0);}/* SMP初始化核间中断IPI */#ifCONFIG_IS_ENABLED(SMP)riscv_init_ipi();#endif}64-bit 特有关系PHYS_64BIT在ARCH_RV64I时被自动选中支持 64-bit 物理地址空间。4.2arch/riscv/lib/sbi.c— SBISupervisor Binary Interface在 RISC-V S-mode监督模式下运行的 U-Boot必须通过 SBI 调用来访问 M-mode机器模式的特权功能。这是 RISC-V 架构与 ARM/x86 最大的软件架构差异之一。核心机制sbi_ecall()封装了 RISC-V 的ecall指令structsbiretsbi_ecall(intext,intfid,unsignedlongarg0,...){registeruintptr_ta0asm(a0)arg0;registeruintptr_ta7asm(a7)ext;// 扩展 IDasmvolatile(ecall:r(a0),r(a1):r(a2),...,r(a7):memory);ret.errora0;ret.valuea1;returnret;}支持的 SBI 扩展v0.2扩展功能SBI_EXT_BASE查询 SBI 规范版本、实现 ID、支持的扩展SBI_EXT_TIME设置下一时钟中断sbi_set_timerSBI_EXT_IPI发送核间中断IPISBI_EXT_RFENCE远程 Fence 指令同步SBI_EXT_HSMHart 状态管理启动/停止/挂起从核SBI_EXT_SRST系统复位关机/冷启动/热启动SBI_EXT_DBCN调试控制台字节级读写SBI_EXT_PMU性能监控单元SBI_EXT_SUSP系统休眠状态32-bit 与 64-bit 在 SBI 调用中的区别32-bit 系统调用sbi_set_timer时64-bit 计时器值需要拆分为低 32 位和高 32 位分别传入a0和a164-bit 则直接通过a0传入完整 64-bit 值#if__riscv_xlen32sbi_ecall(SBI_EXT_SET_TIMER,SBI_FID_SET_TIMER,stime_value,stime_value32,0,0,0,0);#elsesbi_ecall(SBI_EXT_SET_TIMER,SBI_FID_SET_TIMER,stime_value,0,0,0,0,0);#endif4.3arch/riscv/lib/bootm.c— 引导 Linux 内核RISC-V 平台引导 Linux 的bootm实现非常简洁staticvoidboot_jump_linux(structbootm_headers*images,intflag){void(*kernel)(ulong hart,void*dtb);kernel(void(*)(ulong,void*))images-ep;cleanup_before_linux();#ifdefCONFIG_SMP/* 向所有从核发送 IPI使其跳转到内核入口 */smp_call_function(images-ep,(ulong)images-ft_addr,0,0);#endif/* 主核直接跳转a0 boot_hart_id, a1 dtb_addr */kernel(gd-arch.boot_hart,images-ft_addr);}RISC-V Linux 启动约定a0 Boot Hart ID硬件线程编号a1 扁平设备树FDT的物理地址内核入口地址由images-ep指定4.4arch/riscv/lib/fdt_fixup.c— 设备树修正在将设备树传递给 Linux 之前U-Boot 需要执行若干架构特定的修正保留内存拷贝将固件传递的 FDT 中的/reserved-memory节点拷贝到最终 FDTboot-hartid 写入在/chosen节点中写入boot-hartid属性告知 Linux 哪个核是主核ACPI 支持在CONFIG_EFI_LOADER启用时配合 UEFI 启动流程intarch_fixup_fdt(void*blob){/* 覆盖 boot-hartid因为 U-Boot 是最后阶段的 Bootloader */errfdt_setprop_u32(blob,chosen_offset,boot-hartid,gd-arch.boot_hart);/* 拷贝 reserved-memory 节点 */errriscv_fdt_copy_resv_mem_node(gd-fdt_blob,blob);}4.5arch/riscv/lib/smp.c— 对称多处理SMPU-Boot 的 RISC-V SMP 支持通过IPI核间中断实现intsmp_call_function(ulong addr,ulong arg0,ulong arg1,intwait){structipi_dataipi{.addraddr,.arg0arg0,.arg1arg1};returnsend_ipi_many(ipi,wait);}执行流程遍历设备树/cpus节点下的所有可用 hart跳过 boot hart 和超出CONFIG_NR_CPUS范围的核将目标地址和参数写入gd-arch.ipi[hart]通过内存屏障__smp_store_release标记有效位调用riscv_send_ipi(hart)触发硬件 IPI从核在secondary_hart_loop中被wfi唤醒读取 IPI 数据并跳转执行5. 设备模型Device Model驱动分析现代 U-Boot 全面采用DMDevice ModelRISC-V 平台的驱动也不例外。5.1 CPU 驱动drivers/cpu/riscv_cpu.cU_BOOT_DRIVER(riscv_cpu){.nameriscv_cpu,.idUCLASS_CPU,.of_matchriscv_cpu_ids,/* compatible riscv */.bindriscv_cpu_bind,.proberiscv_cpu_probe,.opsriscv_cpu_ops,.flagsDM_FLAG_PRE_RELOC,};功能从设备树读取clock-frequency、timebase-frequency、mmu-type统计可用 CPU 核心数为 Boot Hart 自动绑定riscv_timer驱动SMBIOS 支持64-bit 时family 0x20132-bit 时family 0x2005.2 定时器驱动drivers/timer/riscv_timer.cRISC-V 标准rdtime指令读取的定时器通过riscv,timercompatible 匹配。drivers/timer/riscv_aclint_timer.c针对ACLINTAdvanced Core Local Interruptor的定时器驱动兼容riscv,clint0旧版 CLINTriscv,aclint-mtimer新版 ACLINT5.3 随机数驱动drivers/rng/riscv_zkr_rng.c利用 RISC-VZkr 扩展Entropy Source CSR提供硬件随机数staticintriscv_zkr_read(structudevice*dev,void*data,size_tlen){/* 通过 SEED CSR 读取熵值 */for(i0;ilen;i){do{__asm____volatile__(csrr %0, seed:r(seed));}while(seedSEED_OP_BIST);/* 等待 BIST 完成 */*(u8*)(datai)seed0xFF;}}5.4 串口驱动drivers/serial/serial_htif.cHTIFHost-Target Interface是 RISC-V 仿真环境如 QEMU、Spike使用的虚拟串口仅在__riscv_xlen 64时支持某些功能。6. EFI / UEFI 支持lib/efi_loader/efi_riscv.cU-Boot 作为 UEFI 固件时需要向操作系统暴露RISCV_EFI_BOOT_PROTOCOL这是 RISC-V 特有的 UEFI 协议structriscv_efi_boot_protocolriscv_efi_boot_prot{.revisionRISCV_EFI_BOOT_PROTOCOL_REVISION,.get_boot_hartidefi_riscv_get_boot_hartid};staticefi_status_tEFIAPIefi_riscv_get_boot_hartid(structriscv_efi_boot_protocol*this,efi_uintn_t*boot_hartid){*boot_hartidgd-arch.boot_hart;returnEFI_SUCCESS;}作用让通过 UEFI 启动的操作系统如 Linux with EFI stub能够查询到 Boot Hart ID。7. 构建系统与配置7.1arch/riscv/Kconfig— 架构级配置RISC-V 架构的关键 Kconfig 选项配置项说明ARCH_RV32I/ARCH_RV64I基础 ISA 选择自动选择32BIT/64BIT/PHYS_64BITRISCV_MMODE/RISCV_SMODE运行特权模式M-mode 直接硬件控制 / S-mode 依赖 SBISPL_RISCV_MMODE/SPL_RISCV_SMODESPL 阶段的特权模式CMODEL_MEDLOW/CMODEL_MEDANY代码模型RV64 通常用 medanySBI_V01/SBI_V02SBI 规范版本SMP/NR_CPUS多核支持与最大 CPU 数2-32RISCV_ISA_C/F/D/A/ZBB各 ISA 扩展编译开关XIPExecute-In-Place就地执行用于 NOR FlashSYS_CACHE_THEAD_CMO平头哥 T-Head 非标准缓存操作C906/C9107.2arch/riscv/config.mk— 编译标志32bit-emul : elf32$(small-endian)riscv 64bit-emul : elf64$(small-endian)riscv ifdef CONFIG_64BIT KBUILD_LDFLAGS -m $(64bit-emul) EFI_LDS : elf_riscv64_efi.lds PLATFORM_ELFFLAGS -B riscv -O elf64-$(large-endian)riscv endif PLATFORM_CPPFLAGS -ffixed-x3 -fpic LDFLAGS_u-boot --gc-sections -static -pie关键标志-ffixed-x3固定gpx3寄存器不被 GCC 用作通用寄存器U-Boot 用 gp 存储全局数据指针-fpic/-pie位置无关代码支持重定位elf_riscv64_efi.lds64-bit EFI 应用程序链接脚本8. 支持的硬件平台RISC-V 64-bit厂商/平台核心/SoC板级目录特色QEMUVirtboard/emulation/qemu-riscv官方仿真平台支持 ACPISiFiveFU540board/sifive/unleashed首款商用 RISC-V Linux 板SiFiveFU740board/sifive/unmatched高性能桌面级赛昉 StarFiveJH7110board/starfive/visionfive2四核 64-bit集成 GPU平头哥 T-HeadTH1520board/thead/th1520_lpi4a荔枝派 4AC910 核心进迭时空 SpacemitK1board/spacemit/bananapi-f3香蕉派 F38 核 X60算能 SophgoCV1800B / SG2002board/sophgo/milkv_duoMilk-V Duo低成本嘉楠 CanaanK230board/canaan/k230_canmv集成 KPU AI 加速器MicrochipPolarFire SoCboard/beagle/beaglev_fireBeagleV-FireFPGARV64AndesAX45MPboard/andestech/ae350Andes 商业 IPOpenPitonRV64board/openpiton/riscv64学术研究多核平台AMD/XilinxMicroBlaze Vboard/xilinx/mbvFPGA 软核 RISC-V9. 与旧版 U-Boot2013 Sunxi的架构对比特性旧版 U-Boot (2013.10-rc2, ARM/Sunxi)新版 U-Boot (2026.07-rc2, RISC-V)配置系统boards.cfginclude/configs/*.h宏Kconfig defconfig 设备树驱动模型无统一模型直接调用全局函数Device Modeludevice/uclass板级参数C 语言硬编码dram_*.c设备树.dts描述启动流程BROM → SPL → U-Boot固件OpenSBI→ U-Boot / SPL → OS多核支持基本无 SMP 支持完整的 SMP IPI Hart 管理架构抽象以 ARMv7 为主宏区分32/64-bit 共用代码宏选择指令宽度特权模式ARM 的 M-mode/EL3隐含显式支持 M-mode / S-mode固件接口无直接操作硬件SBISupervisor Binary InterfaceUEFI 支持无完整 EFI Loader RISC-V 专用 ProtocolISA 扩展固定ARMv7 NEON/VFP运行时解析riscv,isa动态启用扩展代码体积优化手动裁剪宏-ffunction-sections -fdata-sections --gc-sections10. 总结最新 U-Boot 中的RISC-V 64-bit 支持代码展现了高度的工程成熟度优雅的 32/64-bit 共存通过CONFIG_32BIT/CONFIG_64BIT和宏化的汇编指令LREG/SREG同一份start.S同时支持 RV32 和 RV64极大减少了代码重复。SBI 是 RISC-V 软件生态的核心U-Boot 在 S-mode 下运行时完全依赖 SBI 访问特权功能这使得 U-Boot 本身不需要直接操作大量 M-mode CSR提升了安全性和可移植性。SPL 通常运行在 M-mode而主 U-Boot 可以运行在 S-mode。设备树驱动化与旧版将 DRAM 时序、GPIO 配置硬编码在 C 文件中的做法不同现代 RISC-V U-Boot 几乎完全依赖设备树进行硬件描述板级代码量极少如qemu-riscv.c仅有 58 行。SMP 原生支持RISC-V 多核启动机制Hart Lottery IPI被优雅地实现在start.S和smp.c中从核通过wfi休眠等待主核调度。活跃的社区生态从 QEMU 仿真到 SiFive、StarFive、平头哥、算能等商业芯片U-Boot 的 RISC-V 支持覆盖了从微控制器到高性能应用处理器的全谱系。