在 QEMU RISC-V 服务器参考平台(rvsp-ref)上运行 OpenEuler RISC-V 25.09

OpenEuler RISC-V 25.09(社区创新版本)已支持 RVA23S64 Profile,为适配 RISC-V Server Platform Reference Spec(下文简称 RVSP-REF) 做好了充足的准备。

介于目前没有成熟的 RISC-V 服务器硬件平台支持完整的 RVA23S64 Profile,因此我们尝试先通过 QEMU 来搭建一个符合 RVSP-REF 规范的 Machine,来帮助 OpenEuler 进行软件栈左移开发。

本文会介绍一下 RISC-V 服务器参考平台规范,然后带大家简单梳理一下当前 QEMU RVSP-REF 的进展,最后说明如何在 QEMU rvsp-ref Machine 上启动 OpenEuler 25.09。

RISC-V 服务器参考平台规范介绍

RVSP-REF Spec 1.0 概要

服务器和我们平时用的电脑不一样,需要常年稳定运行,对可靠性、安全性、性能都要求更高(比如数据中心的服务器不能随便死机,还要防黑客偷数据)。因此,RVSP-REF Spec 定义了一套标准化的硬件能力和接口,使操作系统、虚拟机监控程序等可移植系统软件能够依赖这些能力,实现单一二进制镜像兼容。这个规范适用于通用服务器系统(如 Web 服务器、数据库服务器等),强调高可靠性(RAS)、安全性、性能和服务质量(QoS)等服务器级需求。

2025 年 3 月份 RVSP-REF Spec 1.0 定稿,同年 5 月份,QEMU 上游更新了 rvsp-ref board 补丁(PATCH v3),增加了对 RVA23 的支持以及 iommu 设备。

一个完整的 RISC-V 服务器平台,至少要包含四部分:

  1. 完善的 SoC 硬件支持:提供硬件接口(如 CPU 核满足 RVA23S64、定时器、高级中断控制器、PCIe 根端口等)。

  2. 标准化的平台固件:基于 UEFI 和 ACPI 标准,提供启动和运行时服务。

  3. 丰富的管理接口:通过基板管理控制器(BMC)支持带内(in-band)和带外(out-of-band)管理(如 MCTP、PLDM、IPMI、Redfish)。

  4. 多种安全模型:支持安全启动、调试授权、机密计算等。

硬件模块规范介绍

我们来看一些和 RISC-V 体系结构比较相关的硬件模块规范:

1.时钟与定时器

  • 时间计数器(time CSR) 必须以至少 100 MHz 的频率递增,单位纳秒。

  • 必须保持跨 CPU 核低功耗状态的计时连续性(系统级休眠状态除外)。

如果考虑性能,规范强烈推荐支持 Sstc 扩展,它通过引入stimecmpvstimecmp寄存器,为监管者和虚拟机提供了高效的计时器中断机制,是提升系统(尤其是虚拟化环境)性能的关键特性。

2. 中断控制器

  • 必须支持 RISC-V 高级中断架构(AIA)

  • 外部中断必须通过 消息信号中断(MSI) 传递。

  • IMSIC 需支持 S-mode 中断文件,并至少支持 5 个 VS-mode 中断文件(用于虚拟化)。

  • 若 SoC 使用线中断,需通过 APLIC 转换为 MSI。

值得一提的是,RISC-V 的 AIA(高级中断架构)相比传统的 PLIC(平台级中断控制器)在中断处理机制、性能、虚拟化支持等方面带来了显著的提升。

AIA 通过引入消息信号中断(MSI)、增强的优先级管理和对虚拟化的原生支持,从 PLIC 那种集中、静态的中断管理方式,转向了分布式、基于消息、且深度支持虚拟化的现代架构,为高性能计算和服务器场景提供了更现代、更高效的解决方案。

所以在 RVSP-REF Spec 1.0 中,强制要求使用 AIA,这对于将 RISC-V 推向数据中心、高性能计算和需要强实时性的应用领域至关重要。

3. 输入输出内存管理单元(IOMMU)

  • 所有 DMA 设备(包括 PCIe 设备和非 PCIe 设备)必须受 IOMMU 管理。

  • 必须支持 RISC-V IOMMU 规范,包括地址转换、PASID(20 位宽度)、ATS(地址转换服务)等。

  • 推荐支持硬件性能监控(HPM)和错误注入功能。

  • 复位后默认关闭 DMA,以增强安全性。

4. PCIe 子系统

  • 根复合体(Root Complex) 必须符合 PCIe 6.0 标准。

  • ECAM 配置空间 必须支持非缓存、强序访问,并确保写操作的完成语义。

  • 内存映射空间 需支持 32 位和 64 位 BAR,并定义访问错误处理规则(如返回全 1 数据)。

  • 必须支持 ACS(访问控制服务)AER(高级错误报告)DPC(下游端口遏制) 等可靠性功能。

  • 可选支持 PTM(精确时间测量)SR-IOV 虚拟化。

5. 可靠性、可用性与可服务性(RAS)

  • 推荐使用 ECC 内存数据毒化(Data Poisoning)定期内存巡检

  • 应支持 RISC-V RERI(错误记录接口),实现错误日志持久化(跨复位保留)。

  • 需区分可纠正错误(CE)、非致命错误(UED)和致命错误(UEC)的处理策略。

值得补充的是,RISC-V RERI(RAS Error Record Register Interface)是 RISC-V 体系架构中一项重要的 可靠性、可用性与可维护性 规范,它为标准化的错误报告和日志记录提供了硬件接口,在高端应用如数据中心服务器中,RAS 特性是必不可少的。

6. 服务质量(QoS)

  • 要求 SoC 提供资源管理机制(如缓存、内存带宽分配),以减少应用间性能干扰。

7. 性能监控

  • CPU 核和 IOMMU 应支持硬件性能计数器(至少 40 位宽),用于优化分析。

8. 安全性

  • 通过 IOMMU 隔离设备 DMA 访问。

  • 支持 T2GPA 模式(防止设备滥用 ATS)。

  • 可选集成 SPDM、TDISP 等可信 I/O 协议。

QEMU RVSP-REF 进展

QEMU rvsp-ref Machine 目前包含的组件如下:

  • Based on riscv virt machine type
  • A new memory map as close as virt machine as possible
  • A new virt CPU type rvsp-ref-cpu for server platform compliance
  • AIA
  • PCIe AHCI
  • PCIe NIC
  • No virtio device
  • No fw_cfg device
  • No ACPI table provided
  • Only minimal device tree nodes

PS:服务器平台规范要求 BRS-I(参见 FIRM_010)。BRS-I 需要 ACPI,甚至还需要一些特定的 ACPI 表,例如 PPTT(参见 BRS 规范第 6 章)。不过,我认为我们的思路应该是在这里生成一个设备树(DT),然后让 edk2 从该设备树生成 ACPI 表。

QEMU 已经支持了 RVA23S64,但是对于服务器规范还缺少一些规范,比如 sdext,之前我在论坛做过这个规范的分享:探讨 The RISC-V Debug Specification 的实现(笔者已经和上游做了沟通,后续会补全这个扩展的实现,并贡献到 QEMU 上游)。

在 QEMU rvsp-ref Machine 上启动 OpenEuler

下载 QEMU

目前 rvsp-ref 的补丁还游离在主线之外(因为缺少 sdext 扩展),因此笔者基于 riscv-to-apply.next 添加了一些必要的组件和 bugfix,可以在这里下载到源码:

git clone -b riscv-server-platform git@github.com:zevorn/qemu.git

截至当前文章撰写时的提交历史如下:

commit 07b4e4467a94e8e538b272e5a3135d16cc98ab03 (HEAD -> riscv-server-platform, origin/riscv-server-platform)
Author: Chao Liu <chao.liu.riscv@isrc.iscas.ac.cn>
Date:   Sat Nov 1 19:04:41 2025 +0800

    hw/riscv: update rvsp-ref default cpu type to cpu-max
    
    temp patch for support openEuler 25.09
    
    Signed-off-by: Chao Liu <chao.liu.riscv@isrc.iscas.ac.cn>

然后使用如下命令编译:

./configure --target-list=riscv64-softmmu && make -j$(nproc)

验证是否编译成功:

./build/qemu-system-riscv64 -M ?
Supported machines are:
amd-microblaze-v-generic AMD Microblaze-V generic platform
microchip-icicle-kit Microchip PolarFire SoC Icicle Kit
none                 empty machine
rvsp-ref             RISC-V Server SoC Reference board # 这是我们需要的
shakti_c             RISC-V Board compatible with Shakti SDK
sifive_e             RISC-V Board compatible with SiFive E SDK
sifive_u             RISC-V Board compatible with SiFive U SDK
spike                RISC-V Spike board (default)
virt                 RISC-V VirtIO board
xiangshan-kunminghu  RISC-V Board compatible with the Xiangshan Kunminghu FPGA prototype platform

更新镜像

这里我们以 OpenEuler 25.09 为例,可以参考 使用qemu启动openeuler-24.03-LTS-SP2 - openEuler - RISC-V 开发者社区,先从 virt 启动,我们需要修改一点东西来支持 rvsp-ref Machine。

主要是修改一下 grub.cfg:

vim /boot/efi/EFI/openEuler/grub.cfg 

找到这部分:

        linux   /vmlinuz-6.6.0-102.0.0.5.oe2509.riscv64 root=UUID=c6dd218d-fc09--4066-bc5d-b20a8eb9da7a ro
...

ro 改为 rw 即可(后续我们会做优化,避免直接修改 openEuler 镜像)。

更新启动脚本

新建一个启动脚本,命令如下:

#!/usr/bin/env bash

# The script is created for starting a riscv64 qemu virtual machine with specific parameters.

RESTORE=$(echo -en '\001\033[0m\002')
YELLOW=$(echo -en '\001\033[00;33m\002')

## Configuration
vcpu=8
memory=8
drive="$(ls *.qcow2)"
fw1="RISCV_VIRT_CODE.fd"
fw2="RISCV_VIRT_VARS.fd"
ssh_port=12055

cmd="/home/zevorn/qemu/build/qemu-system-riscv64 \
  -nographic -machine rvsp-ref,pflash0=pflash0,pflash1=pflash1 \
  -smp "$vcpu" -m "$memory"G \
  -blockdev node-name=pflash0,driver=file,read-only=on,filename="$fw1" \
  -blockdev node-name=pflash1,driver=file,filename="$fw2" \
  -object rng-random,filename=/dev/urandom,id=rng0 \
   -drive file=$drive,format=qcow2,id=virtio-drive,if=none \
   -device virtio-blk-pci,drive=virtio-drive,id=virtio-blk-0"

echo ${YELLOW}:: Starting VM...${RESTORE}
echo ${YELLOW}:: Using following configuration${RESTORE}
echo ""
echo ${YELLOW}vCPU Cores: "$vcpu"${RESTORE}
echo ${YELLOW}Memory: "$memory"G${RESTORE}
echo ${YELLOW}Disk: "$drive"${RESTORE}
echo ${YELLOW}SSH Port: "$ssh_port"${RESTORE}
echo ""
echo ${YELLOW}:: NOTE: Make sure ONLY ONE .qcow2 file is${RESTORE}
echo ${YELLOW}in the current directory${RESTORE}
echo ""
echo ${YELLOW}:: Tip: Try setting DNS manually if QEMU user network doesn\'t work well. ${RESTORE}
echo ${YELLOW}:: HOWTO -\> https://serverfault.com/a/810639 ${RESTORE}
echo ""
echo ${YELLOW}:: Tip: If \'ping\' reports permission error, try reinstalling \'iputils\'. ${RESTORE}
echo ${YELLOW}:: HOWTO -\> \'sudo dnf reinstall iputils\' ${RESTORE}
echo ""

sleep 2

eval $cmd

然后执行这个脚本,可以直接启动:

chmod +x ./start_rvsp-ref_vm.sh
./start_rvsp-ref_vm.sh

下面截取一些关键输出:


OpenSBI v1.7
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name               : riscv-rvsp-ref,qemu # 这里显示 rvsp-ref
Platform Features           : medeleg
Platform HART Count         : 8
Platform IPI Device         : aia-imsic # 使用的是 aia 高级中断
Platform Timer Device       : aclint-mtimer @ 10000000Hz
Platform Console Device     : uart8250
Platform HSM Device         : ---
Platform PMU Device         : ---
Platform Reboot Device      : syscon-reboot
Platform Shutdown Device    : syscon-poweroff
Platform Suspend Device     : ---
Platform CPPC Device        : ---
Firmware Base               : 0x80000000
Firmware Size               : 403 KB
Firmware RW Offset          : 0x40000
Firmware RW Size            : 147 KB
Firmware Heap Offset        : 0x54000
Firmware Heap Size          : 67 KB (total), 4 KB (reserved), 13 KB (used), 49 KB (free)
Firmware Scratch Size       : 4096 B (total), 1400 B (used), 2696 B (free)
Runtime SBI Version         : 3.0
Standard SBI Extensions     : time,rfnc,ipi,base,hsm,srst,pmu,dbcn,fwft,legacy,dbtr,sse
Experimental SBI Extensions : none

Domain0 Name                : root
Domain0 Boot HART           : 1
Domain0 HARTs               : 0*,1*,2*,3*,4*,5*,6*,7*
Domain0 Region00            : 0x0000000000100000-0x0000000000100fff M: (I,R,W) S/U: (R,W)
Domain0 Region01            : 0x0000000010000000-0x0000000010000fff M: (I,R,W) S/U: (R,W)
Domain0 Region02            : 0x0000000002000000-0x0000000002007fff M: (I,R,W) S/U: ()
Domain0 Region03            : 0x000000000c000000-0x000000000c007fff M: (I,R,W) S/U: ()
Domain0 Region04            : 0x0000000024000000-0x0000000024007fff M: (I,R,W) S/U: ()
Domain0 Region05            : 0x0000000080000000-0x000000008003ffff M: (R,X) S/U: ()
Domain0 Region06            : 0x0000000080040000-0x000000008007ffff M: (R,W) S/U: ()
Domain0 Region07            : 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X)
Domain0 Next Address        : 0x0000000020000000
Domain0 Next Arg1           : 0x000000027fe00000
Domain0 Next Mode           : S-mode
Domain0 SysReset            : yes
Domain0 SysSuspend          : yes
...

# 成功登录系统以后,可以打印一下信息:

[root@localhost ~]# fastfetch 
                 `.cc.`
             ``.cccccccc..`
          `.cccccccccccccccc.`
      ``.cccccccccccccccccccccc.``
   `..cccccccccccccccccccccccccccc..`
`.ccccccccccccccc/++/ccccccccccccccccc.`
.cccccccccccccccmNMMNdo+oso+ccccccccccc.
.cccccccccc/++odms+//+mMMMMm/:+syso/cccc
.cccccccccyNNMMMs:::/::+o+/:cdMMMMMmcccc    root@localhost
.ccccccc:+NmdyyhNNmNNNd:ccccc:oyyyo:cccc    --------------
.ccc:ohdmMs:cccc+mNMNmyccccccccccccccccc    OS: openEuler 25.09 riscv64
.cc/NMMMMMo////:c:///:cccccccccccccccccc    Host: riscv-rvsp-ref,qemu
.cc:syysyNMNNNMNyccccccccccccccccccccccc    Kernel: Linux 6.6.0-102.0.0.5.oe2509.riscv64
.cccccccc+MMMMMNyc:/+++/cccccccccccccccc    Uptime: 56 mins
.cccccccccohhhs/comMMMMNhccccccccccccccc    Packages: 306 (rpm)
.ccccccccccccccc:MMMMMMMM/cccccccccccccc    Shell: bash 5.2.37
.ccccccccccccccccsNNNNNd+cccccccccccccc.    Cursor: Adwaita
`..cccccccccccccccc/+/:cccccccccccccc..`    Terminal: vt220
   ``.cccccccccccccccccccccccccccc.``       CPU: rv64gcvh (8)
       `.cccccccccccccccccccccc.`           Memory: 277.14 MiB / 7.50 GiB
          ``.cccccccccccccc.``              Swap: Disabled
              `.cccccccc.`                  Disk (/): 1.32 GiB / 37.11 GiB
                 `....`                     Local IP (eth0): 10.0.2.15/24
                                            Locale: en_US.UTF-8


5 个赞

硬件未到,软件先行 提前做好准备~
话说整体部署流程还蛮快的

1 个赞

亲测可行,成功在 QEMU rvsp-ref 上启动 openEuler RISC-V 25.09 :tada:
很期待后续上游合入及真实服务器平台落地~

3 个赞

哇感谢测试!

你好,我用qemu运行了openEuler24.03,发现有以下问题,不知道您是否有相关的经验?

  • 启动之后用pip安装包时很慢,会卡到build这步,怀疑是模拟的硬件能力不足,且尝试开启kvm失败,vcpu应该是分配了16个,内存是8G。不知道您是否有思路或建议?

受宿主机性能影响,可能仿真性能不够

2 个赞

好的,我换一台机器试试

1 个赞

可以在宿主机和guest里面分别跑一个简单的 benchmark,或者build简单的程序,预估一下性能损耗,来判断在qemu里面pip 大概耗时多少

2 个赞