香山CPU(国产开源)的 SoC SDK底层程序编写,以及其它开源SoC芯片介绍
-
目的是用C语言在以香山开源CPU核为基础的开源SoC芯片的硬件平台上,编写完整的裸机SDK、RTOS驱动、Linux驱动。限于当前香山CPU还没有完整的开源SoC,没有外设模块,前期会借鉴蜂鸟E203、玄铁CH2601、OpenTitan、SiFive Freedom E310等带外设的开源SoC的模块寄存器来编写程序。因为没有香山CPU的开发板,程序都会运行在NEMU或QEMU模拟器上。
-
香山开源CPU核的开发商是北京开源芯片研究院 ,目标是打造开源RISC-V产业生态,但现在才初步开始,并没有一款带所有外设的开源SoC,也没有开发板出售,当前的主线项目还只有香山CPU核;
| 作者 | 将狼才鲸 |
|---|---|
| 创建时间 | 2025-12-18 |
- 源码仓库:才鲸嵌入式/香山CPU(SoC)SDK
- CSDN阅读网址:香山CPU(国产开源)的 SoC SDK底层程序编写,以及其它开源SoC芯片介绍
一、前言
-
困扰:换过几家公司,用过几种芯片,它们有着不同的CPU核,不同的外设寄存器,不同的协议栈代码(例如8051、ARM Cortex-M、ARM Cortex-A、Xtensa、TI C66x、AVR),总是做一些重复性工作。既然芯片总是换来换去,代码没有延续性,反正都是要换的,为何不干脆针对一款普及最广的开源CPU IP核以及开源SoC芯片写一些底层代码呢?这样利用空余时间还能不断迭代代码,学习一些新思路。
- 这些底层SDK代码原本是会由芯片厂商提供的,也就是由芯片厂商里的嵌入式软件工程师编写。但是当前并没有专门提供可商用开源SoC芯片的公司,所以我准备选一个CPU核写一点。
- 因此这个学习型仓库的受众是芯片厂商的嵌入式软件工程师(SDK、中间件、操作系统移植、驱动),一般公司的嵌入式驱动软件工程师,以及对底层工作内容感兴趣的嵌入式应用软件工程师。
-
基于上述目的搜索了一下可用的硬件平台;
- 开源的CPU指令集:RISC‑V(使用最多)、OpenRISC、SPARC V8/V9、MIPS开源版本、OpenSPARC、OpenPOWER、MIPS Open、LatticeMico32、WARP‑V、MOR1KX;
- 开源的CPU核(IP):香山(国产)、玄铁C906/C910(国产)、wujian100_open/玄铁CH2601(国产)、VexRiscv、PicoRV32、Rocket、BlackParrot、OpenRio、CV32E40P、NEORV32、Ibex、CVA6、Ariane、BOOM、CV32E40P、darkriscv、Hummingbirdv2 E203、木心处理器、Sodor、YARVI、Pulpino、GRVI Phalanx、SweRV EH1、PicoRio、RISCY;
- 里面有很多是用在FPGA上,或者仅供研究无法商用,或者不再更新迭代的;
- 开源的MCU/SoC(CPU+总线+外设):蜂鸟Hummingbird E203(国产,偏教学)、LiteX(适配多种CPU核,SoC生成器)、Freedom E310、OpenTitan、X-HEEP、Sodor SoC、OpenPiton、NEORV32、IOb-SoC、PicoRV32 + PicoSoC、VexRiscv + Murax、Rocket Chip、PULPino;
- 基本上都是用在FPGA上,或者仅供研究无法商用,或者不是通用MCU的
- 最终选定香山CPU核,再融合其它开源SoC里的模块,在QEMU模拟器上运行代码。
-
香山CPU核资料:
- 代码仓库:XiangShan/XiangShan
- CPU使用文档:香山开源处理器用户手册
- 官网:北京开源芯片研究院
- 服务公司,北京开芯红科技有限公司:国内RISC-V CPU设计公司汇总,竟有四十多家!
-
挑战:香山是高性能CPU,本意是为服务器芯片、AI芯片、GPU、DPU、工业控制、能源、医疗、汽车、通信和机器人应用场景设计,而不是为嵌入式场景设计的,所以为了在SoC上集成USB、网络、串口、SPI、I2C、SD、2D等开源IP核,还要想些办法,主要是把开源外设模块的寄存器实现移植到QEMU的模拟器中去
-
已商用的产品:
- 首款香山笔记本------如意香山本全球首款香山笔记本"如意香山本"发布:2.5GHz 第二代"南湖"处理器、RX 550 独显
- 某国产量产GPGPU芯片正式亮相,基于该芯片的智能加速卡出货量已上万
- 一家国产GPU芯片头部企业展示的自研智算加速卡中成功集成了"香山"(南湖)IP核
- 进迭时空正基于"香山"(昆明湖)自研X200核,进迭时空RISC-V服务器芯片平台使用了"香山"(昆明湖)核,已在FPGA平台上稳定地运行Linux操作系统及虚拟机
- 芯动科技高性能全功能GPGPU芯片"风华3号"
-
阿里达摩院平头哥玄铁开源了E902、E906、C906、C9104四款量产处理器IP核,其中E系列为MCU级别的;
- 玄铁处理器
- 其它CPU核型号有C906-C930,E901-E907,R908-R910,大部分都是闭源的,提交次数都很少,都是四年前更新的;
- XUANTIE-RV/opene902
- XUANTIE-RV/opene906
- XUANTIE-RV/openc906
- XUANTIE-RV/openc910
- XUANTIE-RV/wujian100_open
- 无剑100芯片设计平台
- 玄铁·CH2601芯片(SoC) 含有DMA、RTC、PWM、USB1.1、GPIO、I2S、WDT、ADC、Timer、SPI、I2C、UART,但外设并不开源
-
蜂鸟E203 SoC资料:
- RISCV-MCU/e203_hbirdv2
- SI-RISCV/e200_opensource
- Nuclei-Software/e603_hbird
- RVMCU RV-STAR
- 芯来科技 官网上找不到E203的资料,E203只是他们开源用作教学的
-
LiteX SoC资料
-
香山CPU核源码:XiangShan/XiangShan
- 当前稳定版本为v3.2.2-alpha
- 里面没有C语言测试代码,rootfs、Linux在别的仓库,其中Linux仓库只存放在Github上,Gitee上没有
-
芯片运行平台:
- XiangShan/ready-to-run 编译好的二进制程序
- XiangShan/NEMU 模拟器
- NJU-ProjectN/nemu 平行发展的南京大学的一个教学模拟器,作者是同一个人
- NEMU 使用指南
- 网上其它的资源很少
二、资料阅读
-
芯片用户手册:
- 香山开源处理器用户手册
- Kunminghu-V2R2-alpha3
- xiangshan-user-guide-zh.pdf 对软件开发来说有用的内容不多,没有描述指令集,只描述了些基础的寄存器
- xiangshan-user-guide-twoside-zh.pdf 只是双面打印版本,内容和前面一样
-
可执行文件介绍(工作负载,指运行在香山CPU上的程序):
- 工作负载概述
- 适用于 NEMU、XS-GEM5 等模拟器环境;香山仿真环境仅支持纯二进制(Flat binary)格式的工作负载文件,香山仿真环境仅支持传递 1 个工作负载文件,香山仿真环境不支持 ELF 格式的可执行文件
- 工作负载概述
-
依赖库(例如将C源码编译成可执行二进制文件时调用的C语言标准库):
- AM 是一个裸机运行时环境,用户可以使用 AM 来编译在香山裸机上运行的程序
- 使用 AM 生成自定义 workload
- XiangShan/nexus-am
- 生成的可执行文件在emu模拟器运行
-
交叉编译工具链:
- 交叉编译工具链说明
- riscv64-linux-gnu- 用于Linux
- riscv64-unknown-linux-gnu- 用于Linux
- riscv64-unknown-elf- 用于嵌入式,裸机
- 交叉编译工具链说明
-
指令集架构:
- 香山的三代CPU名字分别为:第一代"雁栖湖"、第二代"南湖"、第三代"昆明湖"
- 所有三代处理器均基于开源的RISC-V指令集
- 第一代:RV64GC
- 第二代:RV64GCBK + RVV
- 第三代:RV64GC + RVV + 自定义扩展
- 香山处理器
- 欢迎访问香山官方文档!
-
EMU模拟器与Linux移植
- 工作负载概述
- Linux Kernel for XiangShan in EMU
- 从香山项目中克隆下来 riscv-pk, riscv-linux, riscv-rootfs,分别是启动加载程序 Bootloader, Linux kernel 和根文件系统 rootfs。请将三个仓库放到同一目录下。
- XiangShan/riscv-rootfs master 分支
- https://github.com/OpenXiangShan/riscv-pk noop 分支
- git clone https://github.com/OpenXiangShan/riscv-pk.git
- 注意,该仓库在Gitee码云官方上并没有上传,需要从Github上下载,速度奇慢,但仓库很小,能拉下来
- 可以使用镜像网址如:git clone https://github.com/OpenXiangShan/riscv-pk.git
- 最方便的是注册个Gitee账号,点击页面右上角,选择从GitHub导入,填入仓库地址,等导入成功后再从Gitee上下载。我导入好的地址是:git clone https://gitee.com/langcai1943/riscv-pk.git
- https://github.com/OpenXiangShan/riscv-linux nanshan 分支
- 注意:因为Linux源码在Windows系统上会checkout失败(部分文件名无法在Windows系统上留存),因此只会pull成功,看到一个.git的隐藏文件夹;如果需要查看源码,则需要在Linux系统下clone;也可以先在Windows下clone或pull成功,然后打成压缩包,再拷贝到Linux下解压,然后再checkout
- git clone https://github.com/OpenXiangShan/riscv-linux.git
- 注意,该仓库在Gitee码云官方上并没有上传,需要从Github上下载,有4.3G,速度奇慢
- 可以浅克隆,则大小只有175M,只是下载看源码和编译的话推荐这种方法:git clone --depth 1 --branch nanshan https://github.com/OpenXiangShan/riscv-linux.git
- 我上传好的地址是:git clone https://gitee.com/langcai1943/riscv-linux_shallow-clone.git
- 浅克隆的仓库无法推送到Gitee,因为历史记录不完整导致Git无法解决版本冲突,除非删掉.git文件夹按全新仓库提交
- 可以使用镜像网址如:git clone https://bgithub.xyz/OpenXiangShan/riscv-linux.git
- 最方便的是注册一个Gitee账号,点击页面右上角,选择从GitHub导入,填入仓库地址,等导入成功后再从Gitee上下载,必须保证你的Gitee免费空间够用(新人免费5G),否则导入会失败,且没有报错提示;同步完成的时间需要很久,因为仓库很大有4.3G。
- 可以浅克隆,则大小只有175M,只是下载看源码和编译的话推荐这种方法:git clone --depth 1 --branch nanshan https://github.com/OpenXiangShan/riscv-linux.git
- 另一款Linux内核 构建一个可在香山或者 NEMU 上运行的使用 OpenSBI 的最简 Linux Kernel
- 当前香山CPU的可执行文件还只能在NEMU模拟器上运行,而无法在QEMU模拟器上运行
-
NEMU模拟器
- NEMU 使用指南
- 在源码的resource文件夹里阅读相关的文档
- 使用 NEMU 生成 Simpoint Checkpoint
- OracleBP分支预测器简介
- XiangShan/NEMU 模拟器源码
- NJU-ProjectN/nemu 平行发展的另一个南京大学的教学模拟器,作者是同一个人
- 网上其它的资源很少
- NEMU 使用指南
-
RISC-V指令集文档
- TODO:待搜索
三、NEMU模拟器运行实践
- 我使用的平台是VMware17.5.2虚拟机 + Ubuntu20.04系统
- 记住:以下所有export注册环境变量都是临时的!命令行终端关闭后就失效了,如果要永久生效,请手动添加到~/.bashrc中,并source ~/.bashrc
1. NEMU模拟器的安装与香山CPU裸机程序运行
- 参考:NEMU 使用指南
- 下载源码:git clone https://gitee.com/OpenXiangShan/NEMU.git
- 进入NEMU仓库所在位置,执行
export NEMU_HOME=$(pwd) - make riscv64-xs_defconfig
- 期间会从GitHub下载子模块
- 需要先安装SDL2:sudo apt install libsdl2-2.0-0 libsdl2-dev,如果有冲突则使用sudo aptitude install libsdl2-2.0-0 libsdl2-dev,第一步输入N,后续一路输入Y解决冲突
- 需要先安装readline库:sudo apt install libreadline8 libreadline-dev
- 需要先安装zstd 库:sudo apt install libzstd1 libzstd-dev
- make -j4
shell
jim@virtual-pc:~/nemu$ make -j4
+ CC src/nemu-main.c
.
+ CXX src/memory/store_queue_wrapper.cpp
+ g++ /home/jim/nemu/build/riscv64-nemu-interpreter
jim@virtual-pc:~/nemu$
- 用NEMU运行裸机程序的命令,注意运行后还要手动敲一下c才能真正执行
~/nemu/build/riscv64-nemu-interpreter ~/nexus-am/apps/hello/build/hello-riscv64-xs.bin- 其中hello-riscv64-xs.bin程序已经上传到https://gitee.com/langcai1943/XiangShanSocSDK/bin/hello-riscv64-xs.bin
shell
jim@virtual-pc:~/nexus-am/apps/hello$ ~/nemu/build/riscv64-nemu-interpreter ~/nexus-am/apps/hello/build/hello-riscv64-xs.bin
[src/isa/riscv64/init.c:234,init_isa] NEMU will start from pc 0x80000000
[src/device/io/port-io.c:35,add_pio_map_with_diff] Add port-io map 'uartlite' at [0x00000000000003f8, 0x0000000000000404]
[src/device/io/port-io.c:35,add_pio_map_with_diff] Add port-io map 'screen' at [0x0000000000000100, 0x0000000000000107]
[src/device/io/port-io.c:35,add_pio_map_with_diff] Add port-io map 'keyboard' at [0x0000000000000060, 0x0000000000000063]
[src/device/sdcard.c:137,init_sdcard] Can not find sdcard image:
[src/monitor/image_loader.c:204,load_img] Loading image (checkpoint/bare metal app/bbl) from cmdline: /home/jim/nexus-am/apps/hello/build/hello-riscv64-xs.bin
[src/monitor/image_loader.c:260,load_img] Read 7048 bytes from file /home/jim/nexus-am/apps/hello/build/hello-riscv64-xs.bin to 0x0x776dee614000
[src/monitor/monitor.c:63,welcome] Debug: OFF
[src/monitor/monitor.c:68,welcome] Build time: 01:01:30, Dec 20 2025
Welcome to riscv64-NEMU!
For help, type "help"
(nemu) c
Hello Xiangshan!
这是裸机程序输出的字符串!
[/home/jim/nemu/src/isa/riscv64/include/../instr/special.h:38,execute] nemu_trap case 0
[src/cpu/cpu-exec.c:938,cpu_exec] nemu: HIT GOOD TRAP at pc = 0x0000000080000060
[src/cpu/cpu-exec.c:944,cpu_exec] trap code:0
[src/cpu/cpu-exec.c:155,monitor_statistic] host time spent = 7,328 us
[src/cpu/cpu-exec.c:157,monitor_statistic] total guest instructions = 1,456
[src/cpu/cpu-exec.c:158,monitor_statistic] vst count = 0, vst unit count = 0, vst unit optimized count = 0
[src/cpu/cpu-exec.c:161,monitor_statistic] simulation frequency = 198,689 instr/s
(nemu) q
[src/utils/state.c:30,is_exit_status_bad] NEMU exit with good state: 2, halt ret: 0
jim@virtual-pc:~/nexus-am/apps/hello$
2. 交叉编译工具的获取
-
- riscv64-linux-gnu- 用于Linux
- riscv64-unknown-linux-gnu- 用于Linux
- riscv64-unknown-elf- 用于嵌入式,裸机
- 三款处理器指令集默认均为 RV64GC
- 香山处理器南湖架构支持 RV64GCBK 扩展
-
- riscv64-elf-ubuntu-20.04-gcc-nightly-2024.04.12-nightly.tar.gz
- riscv64-glibc-ubuntu-20.04-gcc-nightly-2024.04.12-nightly.tar.gz
-
将下载到的 2 个 tar.gz 文件解压到 /opt,并把 /opt/riscv/bin 添加到 PATH 中。
- sudo tar -xzf riscv64-elf-ubuntu-20.04-gcc-nightly-2024.04.12-nightly.tar.gz -C /opt
- sudo tar -xzf riscv64-glibc-ubuntu-20.04-gcc-nightly-2024.04.12-nightly.tar.gz -C /opt
- export PATH=/opt/riscv/bin:$PATH
-
完成后,通过以下命令检查安装是否成功:
- riscv64-unknown-linux-gnu-gcc --version
- riscv64-unknown-linux-gnu-g++ --version
- riscv64-unknown-linux-gnu-gfortran --version
- riscv64-unknown-linux-gnu-objdump --version
- riscv64-unknown-linux-gnu-gdb --version
- riscv64-unknown-elf-gcc --version
- riscv64-unknown-elf-g++ --version
- riscv64-unknown-elf-objdump --version
- riscv64-unknown-elf-gdb --version
3. 使用AM运行时库编译裸机程序
-
在~家目录获取AM源码:git clone https://gitee.com/OpenXiangShan/nexus-am.git
-
export AM_HOME=~/nexus-am
-
export CROSS_COMPILE=/opt/riscv/bin/riscv64-unknown-elf- 不知道为什么改了这一步后编译还是提示riscv64-linux-gnu-gcc找不到,因此用蠢办法强行解决:
- cp /opt/riscv/bin/riscv64-unknown-elf-gcc /opt/riscv/bin/riscv64-linux-gnu-gcc 这是为了解决后面编译时报错,并且要用错误的编译器工具名称编出非Linux系统的裸机程序
- cp /opt/riscv/bin/riscv64-unknown-elf-ld /opt/riscv/bin/riscv64-linux-gnu-ld
- cp /opt/riscv/bin/riscv64-unknown-elf-objdump /opt/riscv/bin/riscv64-linux-gnu-objdump
- cp /opt/riscv/bin/riscv64-unknown-elf-objcopy /opt/riscv/bin/riscv64-linux-gnu-objcopy
-
cd ~/nexus-am/apps
-
mkdir hello
-
cd hello
-
vim Makefile
- 加入内容:
makefile
NAME = hello
SRCS = $(shell find -L ./src/ -name "*.c")
include $(AM_HOME)/Makefile.app
- mkdir src
- vim src/hello.c
- 加入内容:
c
#include <klib.h>
int main() {
printf("Hello Xiangshan!\n");
printf("这是裸机程序输出的字符串!\n");
return 0;
}
- make ARCH=riscv64-xs
shell
jim@virtual-pc:~/nexus-am/apps/hello$ make ARCH=riscv64-xs
# Building hello [riscv64-xs] with AM_HOME {/home/jim/nexus-am}
# Building lib-am [riscv64-xs]
+ AS src/nemu/common/mainargs.S
+ AR -> build/am-riscv64-xs.a
# Building lib-klib [riscv64-xs]
# Creating binary image [riscv64-xs]
+ LD -> build/hello-riscv64-xs.elf
+ OBJCOPY -> build/hello-riscv64-xs.bin
jim@virtual-pc:~/nexus-am/apps/hello$
- 如果上面编译流程报错可以参考下面的流程:
- 用NEMU运行裸机程序的命令 ~/nemu/build/riscv64-nemu-interpreter ~/nexus-am/apps/hello/build/hello-riscv64-xs.bin
4. 编译Linux、rootfs、设备树、OpenSBI获取可执行文件
-
./build/emu -i path/to/workload.bin
-
交叉编译工具链编译好的版本:riscv-gnu-toolchain/Nightly