资讯动态

Ripes 预编译 ELF 可执行示例深入解析:RanPi-RV32 / RanPi-RV64 的加载、校验与仿真

发布时间:2026/10/13 14:28:08 来源:尧图企业网站定制
教育硬件开发【免费下载链接】RipesA graphical processor simulator and assembly editor for the RISC-V ISA项目地址https://gitcode.com/gh_mirrors/ri/Ripes点击查看免费下载Ripes 是一个面向 RISC-V ISA 的图形化处理器模拟器与汇编编辑器。在其内置示例中除了可直接加载的汇编源码与 C 源码外还提供了一对已经预编译好的 ELF 可执行文件——RanPi-RV32与RanPi-RV64位于 examples/ELF/ 目录。本文以 examples/ELF/README.md 为线索结合仓库源码完整讲解这两个 ELF 示例的程序来源、二进制结构、Ripes 的 ELF 校验与加载流程以及如何在 GUI 与测试场景中运行它们。读完后你将理解一个 ELF 文件要能被 Ripes 执行需要满足哪些条件并能用同样的方法验证和加载自己编译的 RISC-V 可执行文件。一、示例概览examples/ELF 目录关联文档 examples/ELF/README.md 的内容非常凝练全文如下RISC-V Executable ExamplesRanPi (ELF): A precompiled version oftest/riscv-tests/ranpi.c.这段描述揭示了三个关键事实定位该目录存放的是 RISC-V可执行文件Executable示例即已经完成编译链接、可直接被模拟器加载执行的 ELF 二进制而非可读的源码内容RanPi-RV32与RanPi-RV64是 test/riscv-tests/ranpi.c 的预编译版本分别面向 RV32 与 RV64 两种位宽随 Ripes 内置分发在 examples/examples.qrc 的资源文件中ELF/RanPi-RV32与ELF/RanPi-RV64被一并打包进qresource前缀/examples因此这两个文件会随 Ripes 一起发布并出现在示例加载菜单中。从文件属性看RanPi-RV32约 88 KB与RanPi-RV64约 213 KB均为可执行文件-rwxr-xr-x。二、程序本源test/riscv-tests/ranpi.c 源码剖析要理解这两个 ELF 示例先要读懂它们的前身 ranpi.c。该程序是经典的RanPI用概率法计算圆周率 π基准程序源码注释明确标注程序用于计算 π 的近似值由 Mark Riordan 于 1986 年编写原始版本出自 Don Shull最初以 FORTRAN 写成、1993 年翻译为 C其历史用途是作为 CPU 基准测试CPU benchmark。2.1 算法核心Monte Carlo 方法与线性同余生成器main()中实现了标准的 Monte Carlo 打点求 π 算法用两个**线性同余生成器LCG**分别产生 x、y 两个 [0,1) 区间的均匀伪随机数iprod 27611 * ixran; ixran iprod - 74383 * (iprod / 74383)随后x ixran / 74383.0prod ymult * yran; yran prod - ymod * (prod / ymod)随后y yran / ymod对每次抽样计算z x*x y*y若z 1.0则落在单位圆内计数器low加一最终结果pi 4.0 * low / itot。源码注释特别说明这种整数与浮点混合的写法是为了模拟真实程序的计算负载同时刻意控制数值量级以避免 32 位整数溢出并保证 23 位尾数下的浮点精度。程序中还包含一个myadd()子程序以将子程序调用/返回的开销计入基准测试。2.2 面向 Ripes 的定制修改ranpi.c头部明确标注了为 Ripes 所做的两处修改去除原始打印逻辑改为通过 RISC-Vecall系统调用输出a7 4打印字符串printString、a7 1打印整数printInt、a7 2打印浮点数printFloat每次迭代都会输出Iteration: j结束时输出Result:与计算出的 π 值将计算结果移入预定寄存器 x27asm(mv x27, %[v])便于测试或外部工具在仿真结束后直接检查寄存器 x27 获取 π 值。此外迭代次数被设置为itot 100源码注释保留了原始基准的1200000字样这是为了让程序能在模拟器中快速完成仿真。2.3 浮点运算与软浮点soft-float值得注意ranpi.c中包含大量浮点运算float类型而 Ripes 内置的处理器模型默认没有浮点单元FPU。这正是选择-marchrv32im编译该程序的原因——如 docs/c_programming.md 所述编译器会生成soft-float 例程用整数算术指令序列模拟浮点加、乘、除、比较等操作。因此即使模拟器没有 FPU程序仍能正确执行代价是浮点指令被展开为较长的整数指令序列这也为流水线模拟与协同仿真提供了更丰富的指令流。三、ELF 文件的真实面貌readelf 验证我们可以直接对仓库内的二进制文件执行readelf -h来验证它们的 ELF 头确认它们满足 Ripes 的加载要求RanPi-RV32 的 ELF 头关键字段Class: ELF32 Data: 2s complement, little endian OS/ABI: UNIX - System V Type: EXEC (Executable file) Machine: RISC-V Flags: 0x0 Entry point address: 0x10090RanPi-RV64 的 ELF 头关键字段Class: ELF64 Data: 2s complement, little endian OS/ABI: UNIX - System V Type: EXEC (Executable file) Machine: RISC-V Flags: 0x0 Entry point address: 0x10284可以看到两个文件都是小端little endian、UNIX System V ABI、静态可执行ET_EXEC、RISC-V 机器类型与 docs/c_programming.md 中给出的可兼容 ELF 判定标准完全一致ELF32/ELF64 分别对应 RV32/RV64 处理器模型。四、Ripes 的 ELF 兼容性校验validateELFFileELF 文件并非能读就能跑。在加载任何 ELF 之前Ripes 会先通过LoadDialog::validateELFFile()实现在 src/loaddialog.cpp进行严格的兼容性校验该校验依次检查是否为合法 ELF使用 ELFIO 解析器读取失败则报 Not an ELF file机器类型是否匹配reader.get_machine()必须等于当前处理器 ISA 的elfMachineId()即 RISC-V否则报 Incompatible ELF machine type (ISA)文件位宽是否匹配ELFCLASS32对应 32 位 ISA、ELFCLASS64对应 64 位 ISA必须与当前处理器模型的bits()一致否则报 Expected N bit executable, but input program is M bit类型必须为可执行文件仅接受ET_EXEC拒绝动态链接ET_DYN与可重定位ET_REL文件报 Only executable ELF files are supportedELF flags 是否受支持通过 ISA 的elfSupportsFlags()检查非法 flags 会被拒绝。该校验逻辑在三条路径上都会生效GUI 加载对话框LoadDialog在用户选择 ELF 文件时即时调用src/loaddialog.cppCLI 模式CLIRunner加载ExternalELF类型源文件时先调用validateELFFile再加载src/clirunner.cppC 源码编译流程CCManager编译完成后也会对产物调用同样的校验src/ccmanager.cpp。这也解释了为什么 docs/c_programming.md 强调基于当前加载处理器的内部 ISA 规范Ripes 会执行自己的验证来判断输入 ELF 是否兼容。五、ELF 加载与程序模型构建loadElfFile通过校验后文件由loadElfFile()实现在 src/cli/programutilities.cpp解析并构建成内部的Program对象。从源码看加载过程包括节section加载遍历 ELF 的 sections将各节的名称、地址与数据存入program.sections跳过.debug*调试节符号表解析从SHT_SYMTAB节中收集STT_FUNC类型的函数符号建立地址 → 符号名映射program.symbols这也是编辑器反汇编视图中函数名显示的来源DWARF 源码映射读取 DWARF 调试信息中的行号表line table建立地址 → 源码行号的sourceMapping从而支持在仿真中高亮对应 C 源码行同时记录源文件哈希sourceHash供编辑器判断当前程序对应哪份编辑器内容入口点记录以 ELF 头的e_entry如 RanPi-RV32 的0x10090、RanPi-RV64 的0x10284作为program.entryPoint。最终加载得到的Program会通过ProcessorHandler::loadProgram()送入模拟器与汇编/平铺二进制加载后的执行方式完全一致。六、如何在 Ripes 中运行 RanPi ELF6.1 通过示例菜单直接加载推荐由于 examples/examples.qrc 将这两个 ELF 打包进了示例资源在 Ripes 图形界面中通过File - Load Example... - RanPI即可直接加载预编译版本该入口在 docs/c_programming.md 中亦有说明。加载完成后程序会出现在反汇编视图中接着按常规方式运行或单步执行模拟即可。仿真结束时可在寄存器视图中查看x27寄存器——其中保存的浮点位模式即计算得到的 π 值约 3.14。6.2 通过加载对话框手动选择文件也可以使用File - Load File...对话框选择 examples/ELF/RanPi-RV32 或 examples/ELF/RanPi-RV64。此时LoadDialog会调用validateELFFile()即时校验并在界面中显示 ELF 信息ELF 位宽、机器类型、文件类型等。注意RV32 变体必须配合 RV32 处理器模型使用RV64 变体必须配合 RV64 模型否则会因位宽不匹配被拒绝加载。6.3 命令行方式Ripes 提供 CLI 模式详见 docs/cli.md其加载 ELF 的路径与 GUI 完全一致CLIRunner对ExternalELF源类型先调用validateELFFile校验、再调用loadElfFile加载然后运行处理器模型直至程序结束并可输出 cycles、IPC、CPI、寄存器状态等报告src/clirunner.cpp。相关命令行参数可运行./Ripes --help查看。七、作为协同仿真co-simulation测试程序RanPi ELF 示例不仅是给用户演示用的例子它还被直接用作 Ripes 的自动化测试用例。在 test/tst_cosimulate.cpp 中RanPi-RV32以SourceType::ExternalELF类型被列入协同仿真测试文件列表与complexMul.s、factorial.s一起参与测试测试首先用参考模型 RVSS执行程序生成寄存器状态轨迹trace然后依次在各目标处理器模型如RV32_6S_DUAL、RV32_5S、RV32_5S_NO_FW、RV32_5MC_2M、RV32_5MC_1M均开启 M 扩展上模拟同一程序逐周期对比寄存器轨迹一旦出现寄存器状态分叉即认为处理器实现存在缺陷。测试通过ProgramLoadertest/programloader.h经EditTab加载外部文件并等待汇编/加载完成。这说明该 ELF 示例同时承担着处理器正确性回归验证的作用其作为基准程序的定位CPU benchmark在测试体系中得到了延续。八、自行编译可兼容的 ELF如果你想基于 ranpi.c 自行编译并加载docs/c_programming.md 给出了完整指南。关键要点如下需要裸机bare-metalRISC-V 工具链即riscv64-unknown-elf-*系列标准发行版仓库中的gcc-riscv64-linux-gnu可能链接入含 C 扩展指令的启动文件导致无法在 Ripes 中执行编译命令示例./riscv64-unknown-elf-gcc -marchrv32im -mabiilp32 -s foo.c -o a.out其中-marchrv32im指定目标 ISARV32I RV32M配合 soft-float 例程执行浮点运算-mabiilp32指定 32 位 ABI-s用于剥离符号信息可选编译后用readelf -h检查确保 ClassELF32/ELF64、Endiannesslittle、TypeEXEC、MachineRISC-V等字段与本文第三节所列一致若程序无需标准库可追加-nostdlib减少链接体积并手动把入口函数放在源文件第一位此时入口即可执行文件首条指令打印功能则通过ecall实现参考 docs/ecalls.md。九、小结与进一步阅读RanPi-RV32/RanPi-RV64是理解 Ripes ELF 支持机制的绝佳样本从 ranpi.c 的程序逻辑Monte Carlo 求 π、ecall 打印、结果落 x27到 src/loaddialog.cpp 的五步兼容性校验再到 src/cli/programutilities.cpp 的节/符号/调试信息加载一条完整的ELF 进入模拟器链路清晰可见。相关主题可继续阅读docs/c_programming.mdC 程序编译、工具链注册与 ELF 兼容标准docs/cli.md命令行加载与仿真报告选项docs/ecalls.mdRipes 支持的 ecall 系统调用docs/introduction.mdRipes 入门教程赞分享教育硬件开发【免费下载链接】RipesA graphical processor simulator and assembly editor for the RISC-V ISA项目地址https://gitcode.com/gh_mirrors/ri/Ripes点击查看免费下载相关推荐Ripes 中 C 程序的编译与执行从裸机工具链配置到 ELF 加载的完整实战指南Ripes 中 C 程序的编译与执行从裸机工具链配置到 ELF 加载的完整实战指南 本文是 RipesRISC V 图形化处理器模拟器与汇编编辑器的 C教育硬件开发SuperKernel 算子融合极简示例解析仅依赖 AscendC 与 Runtime 的编译、加载与执行全流程SuperKernel 算子融合极简示例解析仅依赖 AscendC 与 Runtime 的编译、加载与执行全流程 导读 本文基于 CANN graph aut人工智能模型编译AscendRISC-V架构可视化仿真利器Ripes深度解析与应用实践RISC V架构可视化仿真利器Ripes深度解析与应用实践 Ripes是一款面向RISC V ISA的图形化处理器仿真器和汇编编辑器它为开发者和学习者提供了教育硬件开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑