RISC-V汇编学习(四)—— RISCV QEMU平台搭建(基于芯来平台) ...

打印 上一主题 下一主题

主题 968|帖子 968|积分 2904

RISCV汇编学习系列:
RISC-V汇编学习(一)—— 基础认识
RISC-V汇编学习(二)—— 汇编语法
RISC-V汇编学习(三)—— RV指令集
RISC-V汇编学习(四)—— RISCV QEMU平台搭建(基于芯来平台)
RISC-V汇编学习(五)—— 汇编实战、GCC内联汇编(基于芯来平台)
0 前言

无论是x86架构照旧ARM架构的汇编代码,都必要在对应架构的物理芯片或兼容的模拟环境中执行。这意味着任何机器码都必须在相应的处置惩罚器架构上运行,以实现对底层硬件的操纵。RISC-V架构也不例外,因此我们必要搭建一个合适的执行平台。通常有两种主要的方法来实现:1、使用实际的RISC-V开辟板 2、通过软件模拟器如QEMU创建虚拟环境。
幸运的是,现在有了更多选择。例如,博主手中就有一块兆易创新基于芯来科技N205 RISC-V焦点的GD32VF103开辟板。这块开辟板不仅提供了高性能和低功耗的优势,还配备了丰富的外设资源,是探索RISC-V架构的理想选择。对于有兴趣的朋侪来说,GD32VF103不仅是STM32F103的一个精良替代品,同时也是一个非常适合RISC-V入门学习的开辟板。不妨动手试试看,体验一下RISC-V带来的不同之处吧。
但是临时没有如许一块RISCV开辟板的同学也可以通过QEMU来学习RISCV架构指令集,甚至比有开辟板更灵活,也能更专注于开辟学习,而不用处置惩罚复杂的硬件连线和设置。接下来,将先介绍下基于芯来RISCV的QEMU实验平台搭建。
1 QEMU实验环境搭建

1.0 基础环境

virtualbox+ubuntu20.4(新版QEMU依靠20.4的lib库,之前16的版本踩过坑),按照典型设置来就可以,可以参考:VirtualBox安装Ubuntu20.04图文教程,这里不做赘述。(如有现成的linux环境,没有须要虚拟机,固然windows环境也是可以,看个人喜欢啦)
1.1 交织编译工具链

交织编译是在一个平台(宿主)上生成另一个不同平台(目标)上运行的代码,我们这里就是要用芯来提供的工具链来编译调试。

  • RISC-V GNU Toolchain (链接: https://nucleisys.com/download.php)
  • 选择嵌入式工具链(2025.2版本)、QEMU(2025.2版本)

  • 解压:
  1. tar -zxvf nuclei-qemu-2025.02-linux-x64.tar.gz
  2. tar -jxvf nuclei_riscv_newlibc_prebuilt_linux64_2025.02.tar.bz2
复制代码
得到如图所示的gcc和qemu工具

这里就是芯来官方提供的gcc(还有clang、llvm,但我们只用了gcc)和qemu的工具链了



  • 环境变量设置
    将解压后得工具链路径加入环境变量

1.2 裸机sdk

  1. github: git clone https://github.com/Nuclei-Software/nuclei-sdk.git
  2. 或者
  3. gitee:  git clone https://gitee.com/Nuclei-Software/nuclei-sdk.git
复制代码
工程文件环境变量设置

1.3 测试sdk和工具链


  • 编译
  1. make CORE=nx900fd SOC=evalsoc DOWNLOAD=ilm ARCH_EXT=_xxldsp dasm
复制代码
进入*nuclei-sdk/application/freertos/demo/*路径下,编译一个freertos的demo elf出来

2. qemu运行测试
  1. make CORE=nx900fd SOC=evalsoc DOWNLOAD=ilm ARCH_EXT=_xxldsp run_qemu
复制代码
一个简单的demo就跑起来啦

3. 调试
一个终端运行gdb server
  1. make CORE=nx900fd SOC=evalsoc DOWNLOAD=ilm ARCH_EXT=_xxldsp run_qemu
  2. _debug
复制代码
另起一个终端,
  1. riscv64-unknown-elf-gdb freertos_demo.elf
复制代码
之后连接3333号端口,就进入了熟悉的gdb调试界面。就可以调试啦

另外更多的makefile阐明,可以参考资助和sdk中的makefile,这里不做过多阐明。
关于QEMU的介绍、使用,感兴趣的小伙伴可以自行了解,使用下令和下令参数参考芯来QEMU阐明 。
我这里介绍步骤也相对直接简单很多,不去介绍过多东西,让学习者有更多精力学习RISCV上,而不是在折腾环境。
至此,芯来基于RISCV裸机QEMU平台就搭建好了,你已经相当于拥有了一台RISC-V装备了,只不外它现在躺在虚拟机里,但是你可以把它当成是物理机对待。(对芯来linux感兴趣的同学可以在下面参考官网链接里自行搭建学习,后面博主应该也会玩下)
2 初识RISCV汇编

基于步骤1搭建的QEMU平台可以就可以进行RISCV汇编的学习,固然也可以学习芯来的cpu和接口ip,这里重点照旧学习RISCV汇编。但这里仅仅是管中窥豹,看下汇编风格,简单体验下。
一样平常嵌入式开辟见到的汇编最多的场合就是freeloader.S、裸机的startup.S以及文件调试编译*.S等
以上面跑到的eval开辟板的startup_evalsoc.S为例,先来一窥下官方release的RISCV汇编究竟如何。

这里仅截取一部分来看下:
  1. /**
  2. * Reset Handler called on controller reset
  3. */
  4. _start:
  5.     /* ===== Startup Stage 1 ===== */
  6.     /* Disable Global Interrupt */
  7.     csrc CSR_MSTATUS, MSTATUS_MIE
  8.     /* If SMP_CPU_CNT is not defined,
  9.      * assume that only 1 core is allowed to run,
  10.      * the core hartid is defined via BOOT_HARTID.
  11.      * other harts if run to here, just do wfi in __amp_wait
  12.      */
  13. #ifndef SMP_CPU_CNT
  14.     /* take bit 0-7 for hart id in a local cluster */
  15.     csrr a0, CSR_MHARTID
  16.     andi a0, a0, 0xFF
  17.     /* BOOT_HARTID is configurable in Makefile via BOOT_HARTID variable */
  18.     li a1, BOOT_HARTID
  19.     bne a0, a1, __amp_wait
  20. #endif
  21.     /* Initialize GP and TP and jump table base when zcmt enabled */
  22.     .option push
  23.     .option norelax
  24.     la gp, __global_pointer$
  25.     la tp, __tls_base
  26. #if defined(__riscv_zcmt)
  27.     la t0, __jvt_base$
  28.     csrw CSR_JVT, t0
  29. #endif
  30.     .option pop
  31. /* TODO if don't have SMP, you can remove the SMP_CPU_CNT related code */
  32. #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
  33.     /* Set correct sp for each cpu
  34.      * each stack size is __STACK_SIZE
  35.      * defined in linker script */
  36.     lui t0, %hi(__STACK_SIZE)
  37.     addi t0, t0, %lo(__STACK_SIZE)
  38.     la sp, _sp
  39.     csrr a0, CSR_MHARTID
  40.     andi a0, a0, 0xFF
  41.     li a1, 0
  42. 1:
  43.     beq a0, a1, 2f
  44.     sub sp, sp, t0
  45.     addi a1, a1, 1
  46.     j 1b
  47. 2:
  48. #else
  49.     /* Set correct sp for current cpu */
  50.     la sp, _sp
  51. #endif
复制代码
固然有了前面RISCV汇编的基础,这些汇编看起来应该能大概看懂了,我们一起来看看下。
界说了一个复位处置惩罚函数 _start,它在控制器复位时被调用。这个函数主要负责初始化体系状态和设置栈指针等基础操纵,以便程序能够正确地开始执行。
通过扫除 CSR_MSTATUS 控制状态寄存器中的 MSTATUS_MIE(Machine Interrupt Enable)标志来禁用所有停止,确保在初始化过程中不会被停止打断。
  1. csrc CSR_MSTATUS, MSTATUS_MIE
复制代码
  1. #ifndef SMP_CPU_CNT
  2.     /* take bit 0-7 for hart id in a local cluster */
  3.     csrr a0, CSR_MHARTID
  4.     andi a0, a0, 0xFF
  5.     /* BOOT_HARTID is configurable in Makefile via BOOT_HARTID variable */
  6.     li a1, BOOT_HARTID
  7.     bne a0, a1, __amp_wait
  8. #endif
复制代码
这部分代码查抄是否界说了 SMP_CPU_CNT(Symmetric Multiprocessing CPU Count)。如果没有界说,意味着只允许一个焦点运行,并且该焦点的 hartid(硬件线程ID)是通过 BOOT_HARTID 界说的。如果当前焦点的 hartid 不即是 BOOT_HARTID,则跳转到 __amp_wait 标签处期待(即进入低功耗模式),否则继续执行
  1. .option push
  2. .option norelax
  3. la gp, __global_pointer$
  4. la tp, __tls_base
  5. #if defined(__riscv_zcmt)
  6.     la t0, __jvt_base$
  7.     csrw CSR_JVT, t0
  8. #endif
  9. .option pop
复制代码
这里使用 .option push 和 .option pop 来临时改变一些编译选项。la 指令用于加载地址到寄存器中,这里设置了全局指针 gp 和线程指针 tp。如果启用了 RISC-V 的零资本上下文切换扩展 (__riscv_zcmt),还会设置 CSR_JVT 寄存器指向跳转表基址。
  1. #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
  2.     /* Set correct sp for each cpu
  3.      * each stack size is __STACK_SIZE
  4.      * defined in linker script */
  5.     lui t0, %hi(__STACK_SIZE)
  6.     addi t0, t0, %lo(__STACK_SIZE)
  7.     la sp, _sp
  8.     csrr a0, CSR_MHARTID
  9.     andi a0, a0, 0xFF
  10. 1:
  11.     beq a0, a1, 2f
  12.     sub sp, sp, t0
  13.     addi a1, a1, 1
  14.     j 1b
  15. 2:
  16. #else
  17.     /* Set correct sp for current cpu */
  18.     la sp, _sp
  19. #endif
复制代码
此段代码根据是否界说了 SMP_CPU_CNT 并且其值大于1来决定如何设置每个CPU的焦点栈指针。如果是多核设置,则为每个焦点分配独立的栈空间,大小由链接脚本中界说的 __STACK_SIZE 决定。csrr 指令读取当前焦点的 hartid,然后根据这个ID调解栈指针的位置。如果只有一个焦点或没有界说 SMP_CPU_CNT,则直接将栈指针设置为 _sp 地址。
代码展示了如何在RISC-V架构上进行根本的体系初始化工作,包括停止管理、多核支持以及内存布局的设置。这些都是嵌入式开辟中非常重要的步骤,确保操纵体系大概应用程序能够在硬件上稳固运行,也就相当于BootLoader了
参考:
https://doc.nucleisys.com/nuclei_tools/qemu/intro.html
https://doc.nucleisys.com/nuclei_board_labs/hw/hw.html

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

缠丝猫

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表