QEMU+RISC-V+Agent:搭建AI芯片仿真实验台的完整实践

发布时间:2026/10/7 15:44:08
QEMU+RISC-V+Agent:搭建AI芯片仿真实验台的完整实践 1. 引言把 AI 芯片的“实验台”搬进虚拟机划得来吗搞芯片验证或嵌入式系统开发的人大概都经历过这种场景目标 SoC 还在流片路上或者开发板排期排到年底但软件栈必须在今天开始调。你要跑 RISC-V 架构的 AI 加速器驱动要验证内核态与用户态的数据通路要做算子库的初步性能摸底——总不能干等着硬件到手才动手。QEMU 并不是什么新鲜东西但它和 RISC-V、AI 芯片这三个词绑在一起再叠一个“AGENT 辅助搭建”的 buff就成了一个非常具体的工程命题在一个纯软件模拟的虚拟机器上把四件事——RISC-V 指令集模拟、AI 算子的运行底座、交叉编译工具链、根文件系统——全部串起来而且最好由 AGENT 当作“执行工程师”来干。之前我收到这个项目需求的时候第一反应是“这个环境要搭到能用QEMU 的坑怕是要踩一大串”。RISC-V 的板级支持远没有 x86/ARM 成熟virt机型虽然通用但网卡、中断控制器、串口、设备树这些细节随便一个匹配不上就能让内核死得无声无息。再叠加 AGENT 来“帮我跑命令”意味着你不仅要懂环境本身还得把 AGENT 的认知边界、上下文窗口、工具调用的容错机制全部考虑进去。也就是说这篇文章表面上讲的是“怎么搭一个 RISC-V AI 芯片仿真实验台”实际上讲的是怎么把一个复杂的、多步骤的、可能出现各种非预期错误的环境搭建任务拆解并交给 AGENT 来执行并且让它最终交出可复现、可验证、可交接的成果。适合谁来读我建议三类人重点看一是做 RISC-V 相关系统软件或 AI 芯片软件栈的开发者你需要一个不依赖实体板子的开发环境二是做 AI Agent 工程化的人尤其是想把 Agent 用到 DevOps、环境部署这类“真实动手”场景里的本文的架构和踩坑记录可以直接复用三是刚接触 QEMU 和 RISC-V 的小白跟着本文走一遍你对“虚拟化、交叉编译、根文件系统”这几个概念会有比看十篇教程都深的体感。这篇文章不会只贴命令。核心思路、Agent 的每一步意图、我实测中踩到的坑、以及排查问题的底层逻辑都会展开讲。先把结论放在前面这套方案实测可行从零到 QEMU 成功启动 RISC-V Linux并由 Agent 自动完成 AI Runtime 的部署全程大约 40 分钟如果算上踩坑和写文档一个下午能交付一套带验收报告的环境。2. 整体设计拆解为什么选择 QEMU RISC-V AI 这个组合以及 Agent 在其中的角色2.1 用 QEMU 模拟 RISC-V AI 芯片省的不只是买板子的钱很多人会问“我直接用开发板不就行吗QEMU 跑出来的性能低模拟的东西又不能代表真实芯片有什么意义”这个问题的答案取决于你处于芯片软件开发的哪个阶段。最核心的价值在于“前置”。芯片的 RTL 还在验证阶段、或者样片还没回来的时候软件团队不能空转。QEMU 可以基于设备树和 ELF 加载近乎一比一地模拟目标机器的 CPU 核数、中断控制器、定时器、串口寄存器、甚至 PCIe 枚举过程。对于 AI 芯片来说即使 QEMU 无法模拟真正的 NPU 算力单元我们也可以先定义一个 MMIO 寄存器区段、一块预留的 DMA 内存区域把驱动框架和用户态算子调度逻辑跑通。等真片回来替换底层寄存器操作上层逻辑不变。其次QEMU 的测试闭环效率远高于实体板。CI/CD 场景下每天要构建几十次内核、rootfs、运行库实体板要么串口同时镜像几个环境要么就得排队。虚拟机的快照和恢复能力、启动参数的变化能力让“每次测试从干净内核启动”变成了几秒内的事。我在项目里更看重的一点是QEMU 能打出完全可复现的启动日志这对 AGENT 做“感知—决策—动作”闭环极其有利——Agent 不需要看一个物理串口上的实时输出它可以直接读日志文件、解析状态码、对比预期输出。至于“为什么是 RISC-V 而不是 ARM 或 x86”这就更直接了AI 芯片领域RISC-V 的可扩展指令集比如 RVV 向量扩展和自定义协处理器接口设计是被大量国产 AI 芯片和开源项目采用的。QEMU 对 RISC-V 的支持无论是virt机型还是sifive_u机型都已经相当成熟。你要在 ARM 上模拟一个“类似自家 AI 芯片”的环境反而要改一堆设备树和 bootloader 适配RISC-V 的virt机型加上 sysbus 上自定义的设备节点模拟成本低得多。换句话说如果你要验证的芯片是基于 RISC-V 指令集加上自定义 AI 扩展的QEMU 几乎是当前最合适、也是唯一免费且开放的选择。2.2 AGENT 在“环境搭建”任务中的角色——不是帮你敲命令而是承担“环境工程”全流程如果仅仅是将 AGENT 作为一个“命令执行器”让它帮我跑apt install qemu-system-riscv64那就太浪费了。这个项目的真正价值是把 AGENT 放在“环境工程师”的位子上让它做四层工作第一层是任务拆解。把“搭一个 RISC-V AI 芯片实验台”这个模糊目标拆成依赖关系明确、有验收标准的子任务准备交叉编译工具链 → 选择并配置 QEMU 机型 → 构建内核与设备树 → 制作 rootfs → 启动并验证 → 部署 AI 运行时组件。每个子任务都要有可量化的验收条件比如“内核能启动到 login 界面”“驱动模块加载成功打印特定日志”“Python 能 import torch 哪怕是在 qemu 模拟环境下降级版本”。第二层是环境感知与自适应。AGENT 不能假定主机环境是什么样它必须先去“探测”当前机器是什么发行版有没有现成的 qemu-system-riscv64网络能不能到外网磁盘空间和内存是否足够编译内核它要像一个人新手工程师一样先看环境再动手而且中途任何报错都要回读信息、判断根因、调整方案。这是 AGENT 与传统“脚本自动化”的最大区别——脚本碰到错误就停止而 AGENT 能围绕日志调整策略。第三层是决策与取舍。搭建过程中一定会遇到相互冲突的选择题。例如用virt机型还是sifive_u机型前者通用性强、virtio 设备支持好后者更接近真实开发板但设备支持老旧。AGENT 需要基于任务目标去权衡——既然目标是“AI 芯片实验台”而不是“复刻某块具体板卡”选virt就是更合理的决策。AGENT 能否给出这种决策并解释理由直接决定了它是不是“能做工程”而非“只会执行”。第四层是验证与交付。搭完环境不算完AGENT 需要做一次完整的 smoke test把启动日志、内核版本、工具链版本、AI 运行时状态全部汇总成一份报告甚至把整套脚本沉淀为可复用的仓库。能做到这一层AGENT 就真正变成了一个可以交接工作的“初级工程师”。3. 实操准备主机环境、工具链选择与依赖清单3.1 主机环境摸底——先别急着装东装西问问“我手里有什么”我在实际执行时第一步给 AGENT 的任务是环境信息收集直接跑一组命令然后把输出喂给它。下面这几条命令基本能覆盖 90% 的情况# 系统与架构 uname -a cat /etc/os-release # CPU 与内存编译内核和运行QEMU都比较吃资源 nproc free -h # 磁盘剩余空间内核源码加编译产物预留至少 10GB 比较稳妥 df -h /home # 已安装的虚拟化和工具链工具 qemu-system-riscv64 --version || echo qemu-system-riscv64 未安装 riscv64-linux-gnu-gcc --version || echo 交叉编译器未安装实测环境是一台 Ubuntu 22.04 x86_64 主机内存 16GB磁盘剩余约 60GB。这个配置只能算“入门标准”如果你内存只有 8GB编译 Linux 内核和多核 QEMU 模拟会吃力建议先加 swapsudo fallocate -l 8G /swapfile之类的操作。AGENT 在收集这些信息时最大的作用不是节省几步敲命令的时间而是它会把这些输出和我之后要求它做的事做关联——资源不够它会主动警告而不是像常规脚本那样无脑继续。3.2 工具链与关键软件包清单——少装一个都会让你卡住RISC-V 环境搭建最费时间的往往不是配置本身而是缺了关键依赖导致中途反复重试。我把整套环境分成四层依赖每层都有明确的用途QEMU 模拟器层qemu-system-miscUbuntu 里 RISC-V 的 qemu 通常归在这个包里或者从 QEMU 官方源码编译。如果直接用发行版包务必检查版本virt机型对sifive_u的默认配置在 7.x 和 8.x 之间有过设备树变动导致同一个内核镜像 boot 行为不一致。交叉编译工具链层gcc-riscv64-unknown-elf裸机和gcc-riscv64-linux-gnuLinux 用户态与内核模块。Ubuntu 下的包名是gcc-riscv64-linux-gnu和对应的binutils-riscv64-linux-gnu。注意如果你要编译内核模块必须让模块的编译器版本和内核编译时保持一致否则会有 vermagic 不匹配问题。内核构建依赖层libncurses-dev、flex、bison、bc、libssl-dev。这些是编译 Linux 内核的硬性依赖。有一个坑Ubuntu 22.04 里如果libssl-dev是 3.x 版本部分老内核源码的证书脚本会报错需要用HOSTLDFLAGS-static绕过或换更老的内核版本。AI 运行时层由于 QEMU 是纯模拟而且 RISC-V 架构的预编译 AI 轮子极少这里的“AI 运行时”通常指的是 Python 环境加上带有 RISC-V 支持的torch源码编译或者最少是部署一个可驱动的自定义算子库骨架。如果你只想验证环境可以先从python3-riscv64看交叉环境下 interpreter 能不能跑起来。AGENT 在解析这些依赖时我建议喂给它一个明确的“包清单 安装意图”结构而不是只让它“看着报错装”。比如sudo apt update sudo apt install -y qemu-system-misc gcc-riscv64-linux-gnu \ libncurses-dev flex bison bc libssl-dev装完后让 AGENT 做一次版本校验确认qemu-system-riscv64 --version输出非空且交叉编译器能编译一个最小的 hello world这些“安装动作”才不算白做。4. 核心细节解析QEMU 虚拟机配置与 RISC-V 内核启动的关键参数4.1 选机型、选固件、选内存——没有你想的那么简单QEMU 针对 RISC-V 提供了多款机型最常用的是virt和sifive_u。在 AI 芯片实验台的场景下我强烈建议选virt。原因有三点第一virt机型是 QEMU 官方为 virtio 生态设计的通用平台支持 PCIe 总线、virtio-net、virtio-blk这对后续挂 AI 加速器虚拟设备比如自定义 PCIe 设备非常友好。第二virt的启动方式支持-kernel直启不需要额外的 bootloader。第三sifive_u虽然更接近 SiFive 家的真实芯片但它的外设模型较老中断控制器和网卡配置很别扭你还得单独敲一套-bios参数。有一个细节值得注意virt机型的内存地址布局在不同 QEMU 版本里有过调整。比如老版本默认 RAM 起始地址是0x80000000新版本引入了-m参数和virtio设备的地址重映射。这直接会影响设备树里头 memory 节点的生成以及内核里CONFIG_PHYSICAL_START的匹配。最稳妥的做法是让 AGENT 先启动一次最小化的 QEMU 并 dump 出设备树qemu-system-riscv64 -machine virt -nographic \ -bios none -machine dumpdtb/tmp/virt.dtb然后在主机上用dtc工具反编译这个 dtb将内存起始地址、中断控制器类型、UART 地址核对清楚。这就是“基于证据做配置”而不是“照着别人的文档抄”。4.2 内核配置中最容易忽视的三个点RISC-V 内核启动到能进 shell关键不在“配置多”而在“配置对”。在make ARCHriscv CROSS_COMPILEriscv64-linux-gnu- defconfig之后我用 AGENT 自动做了三次menuconfig式的调整下面三个点是踩过坑后的经验第一个是CONFIG_RISCV_SBI和CONFIG_SERIAL_8250_CONSOLE。QEMUvirt机型的串口实现在设备树里是ns16550a内核需要把SERIAL_8250编译进内核而不是编成模块模块在启动早期没法加载。这一步漏掉表现就是 QEMU 启动了但串口黑屏、完全看不到内核日志。AGENT 排查这类“无日志”问题时会很抓瞎所以最好预先在配置阶段就检查。第二个是CONFIG_VIRTIO_*系列。如果你用virtio-blk作为 rootfs 载体必须保证CONFIG_VIRTIO_BLK、CONFIG_VIRTIO_PCI、CONFIG_VIRTIO_MMIO都编进内核。编译成模块也行但你得提前准备 initramfs否则内核挂载 rootfs 时找不到驱动就直接 kernel panic。对 AGENT 来说这个坑的排查成本极高因为日志的最后一行可能是VFS: Cannot open root device vda它得逆向推理到“模块没编进内核”。第三个是CONFIG_RISCV_ISA_C也就是压缩指令扩展。QEMU 默认模拟的 CPU 是支持 C 扩展的但如果你在自定义 CPU 型号时关闭了它而内核和二进制的用户态工具链是在开启 C 扩展的配置下编译的就会出现非法指令异常。这类问题在启动阶段可能不显示直到你跑一点复杂用户态程序才会崩。AGENT 最适合做的是对启动后的用户态做一次 smoke test例如跑openssl speed或一段计算密集的 Python 脚本来验证 ISA 配置的一致性。下面这段命令是完整的内核编译与启动验证命令AGENT 执行后我基本只做“复核日志”这一个动作cd linux/ make ARCHriscv CROSS_COMPILEriscv64-linux-gnu- defconfig # 用 scripts/config 修改关键开关 ./scripts/config -e CONFIG_RISCV_SBI ./scripts/config -e CONFIG_SERIAL_8250 ./scripts/config -e CONFIG_SERIAL_8250_CONSOLE ./scripts/config -e CONFIG_VIRTIO_BLK ./scripts/config -e CONFIG_VIRTIO_PCI ./scripts/config -e CONFIG_VIRTIO_MMIO make ARCHriscv CROSS_COMPILEriscv64-linux-gnu- -j$(nproc) # 先尝试 直接内核启动 initramfs 方式 qemu-system-riscv64 -machine virt -cpu rv64 -smp 4 -m 2G \ -kernel arch/riscv/boot/Image \ -nographic -no-reboot \ -append consolettyS0 root/dev/ram rdinit/sbin/init这里我特意写的是-cpu rv64而不是默认值这是 AGENT 在“CPU 特性探测”阶段发现的——目标 AI 芯片扩展指令集尚未在 QEMU 中实现所以先用基础 rv64 保证环境可用后续再通过-cpu rv64, vtrue之类的方式开启向量扩展。关于这一点后面第四节还会展开。4.3 rootfs 的制作——让环境从“能启动”到“能干活”内核启动到 initramfs 只是验证了半截真正的“AI 实验台”需要一套能装软件、能跑应用的根文件系统。构建 rootfs 的方式有 buildroot、Debian riscv64 根文件系统、以及用 debootstrap 交叉制作三种。在这个项目里我选了 Debian 的 riscv64 根文件系统作为基础因为它自带包管理方便后续装 Python 和 AI 库。搭建 rootfs 的具体流程我用 AGENT 把下面这几步全做了输出的是一个可以直接mount使用的 ext4 镜像# 1. 用 docker 或 chroot 环境先拉一个基础 debian sid riscv64 rootfs # 2. 配置 qemu-user-static 做 chroot 交叉运行 sudo apt install qemu-user-static debootstrap # 重点设计: 使用 debootstrap 创建 riscv64 的最小 rootfs sudo debootstrap --archriscv64 --foreign sid ./riscv64-rootfs http://deb.debian.org/debian sudo cp /usr/bin/qemu-riscv64-static ./riscv64-rootfs/usr/bin/ sudo chroot ./riscv64-rootfs /debootstrap/debootstrap --second-stage # 3. 进入 rootfs, 装基础工具和 Python 环境 sudo chroot ./riscv64-rootfs /bin/bash # 在 chroot 内执行: apt update apt install -y python3 python3-pip openssh-server vim exit # 4. 制作 ext4 镜像 dd if/dev/zero ofriscv64-rootfs.img bs1M count2048 mkfs.ext4 riscv64-rootfs.img sudo mkdir /mnt/rootfs-mount sudo mount riscv64-rootfs.img /mnt/rootfs-mount sudo cp -a riscv64-rootfs/* /mnt/rootfs-mount/ sudo umount /mnt/rootfs-mount很多教程在这里喜欢直接将整个 rootfs 目录里的文件拷贝进 ext4 镜像看起来没错但有个坑镜像文件系统里的/etc/fstab、/etc/hostname等配置可能保留着debootstrap阶段的默认值不能直接用于 QEMU 启动。AGENT 在 mount 完镜像后我要求它逐项检查fstab 是否指向了正确的/dev/vda、/etc/network/interfaces是否配置了 DHCP、/etc/resolv.conf是否指向了可用的 DNS。不检查这些rootfs 板子能启动但网络不通后续 AI 运行时下载依赖库的时候又要返工排查。制作镜像最耗时的是debootstrap --second-stage阶段因为它要在 user-mode 模拟下解包几百个软件包。实测用了约 12 分钟如果中途断了--second-stage是可以断点重跑的不要整个目录删掉再来。5. 实操过程AGENT 驱动的 QEMU 环境搭建全流程记录5.1 目标定义与任务卡设计——让 Agent “开工”前先给定验收标准AGENT 工程化很重要的一点是不要让 Agent 在模糊指令下自由发挥。我这次在开工前给 AGENT 下发的任务卡大概是这样的结构化内容任务目标在 x86_64 Ubuntu 22.04 主机上用 QEMU 搭建一个 RISC-V 64 虚拟环境 要求 1. QEMU 能启动 Linux 内核版本 6.1架构 riscv64 2. 系统能进入可用的 rootfsDebian riscv64 3. 能通过 SSH 或串口登录并可以执行 Python3 脚本 4. 预留 AI 加速设备地址空间自定义 MMIO 区域在设备树中添加 5. 输出一份可重复执行的 build 脚本和启动脚本。 验收标准 - qemu-system-riscv64 启动 30 秒内看到 login 提示符 - 在 QEMU 内部执行 python3 --version 输出 3.9 - 挂载一个虚拟 AI 设备驱动模块dmesg 出现 my-ai-device probed。任务卡写得越明确“环境搭建”这种多步骤任务越不容易跑偏。AGENT 拿到任务卡之后会把大任务拆成若干阶段并在每个阶段完成时打一个勾写上验证日志。我后面每次只需要看它的“阶段小结 日志证据”就行不用从头到尾盯着终端。这个设计有两个好处第一如果中途某个环节失败AGENT 能明确指出失败发生在哪个阶段、已完成的依赖有哪些从而方便局部重跑第二任务卡本身就是一份活文档最终交付时可以直接转成说明文档省了日后另写《环境搭建手册》的时间。5.2 步骤实录从安装依赖到第一次启动成功以下是我配合 AGENT 实际执行的流程每一步后面都附了关键日志或产物说明。第一步安装依赖。AGENT 先检测了qemu-system-riscv64是否存在然后自动执行了apt install。由于国内部分镜像源对qemu-system-misc有版本滞后我在任务卡里约定如果系统包版本低于 7.0则从源码编译 QEMU这一步实测耗时约 20 分钟但不是每次都必要可以先试系统包。第二步编译内核。我单独给 AGENT 分配了一个工作目录/workspace/riscv-lab它按要求拉取 Linux 官方仓库的稳定分支源码我指定了 v6.1 LTS因为它在virt机型的兼容性和 AI 驱动常用接口的稳定性方面都不错然后按上一节说的三个关键配置项做调整再make -j$(nproc)编译。首次全量编译 6.1 内核在 8 核机器上大约花了 15 分钟。AGENT 编译完提取了vmlinux、Image、*.dtb三个产物并把它们的 SHA256 记录在构建日志中。第三步构建 rootfs 并制作 ext4 镜像。这部分耗时主要在 debootstrap 的第二阶段约 12 分钟。在进入 chroot 安装 Python 的时候有一个细节apt install python3默认装的是 Debian sid 的 Python 3.11这个版本在 RISC-V 用户态模拟下跑得很慢qemu-user 的解释执行开销但功能正常。如果你对性能有追求可以在 QEMU 内加-cpu rv64, vtrue开启向量扩展后再编译一个 RISC-V 原生的 Python——第一次启动会慢但后续脚本执行会快不少。第四步启动 QEMU。这一步大概率会遇到问题后面单独讲但调试通之后的启动命令如下在这里我特意选了virtio-blk-device而不是virtio-blk-pci原因是在virt机型里virtio-mmio作为平台设备直接挂在 sysbus 上比走 PCIe 枚举少一道配置对初学者更省事。启动日志出现如下内容时说明内核和 rootfs 已经打通[ 0.000000] Linux version 6.1.xx (riscv64-linux-gnu-gcc-12) ... [ 3.251236] VFS: Mounted root (ext4 filesystem) on device 254:0. Debian GNU/Linux bookworm/sid ttyS0 riscv-lab login:第五步追加 AI 加速设备。为了让这个环境更像“AI 芯片实验台”我在设备树里加了一个自定义的 sysbus 设备节点地址段为0x10000000-0x10001000并在内核里写了一个 hello-world 级虚拟设备驱动。这一步不是我手搓的而是让 AGENT 根据任务卡去尝试“往 dtb 里加节点”和“写一个最小内核模块”两个子任务。它实现后QEMU 启动参数里多了-device loader,filemyai.dtb,addr0x10000000之类的内容模块加载日志也如期出现。这算是从“模拟一台普通 RISC-V 机器”向“模拟一块 RISC-V AI 芯片”迈出的一小步——真正的 AI 算力单元模拟是下一步工作但环境和接口基调已经定好了。6. 常见问题与排查技巧实录——没有这几板斧环境搭到一半最容易弃坑6.1 串口黑屏、内核无输出先分“硬件层没有输出”还是“内核崩在没有 console”最折磨人的问题就是 QEMU 启动后终端一片漆黑。我见过太多人卡在这一步。排查思路是有层次的AGENT 特别适合做这种“分层逻辑推理”先确认是不是 QEMU 启动参数有问题。最简单是加-d guest_errors -D qemu.log看 QEMU 的 guest 错误日志如果日志里有Invalid read at addr 0x...基本可以确定是设备访问异常。如果 QEMU 本身没有错误那就是固件或内核没有产出串口输出。此时用-bios default与-bios none -kernel Image两种方式分别试如果default模式能出 OpenSBI 日志而-kernel直启不出说明内核里串口驱动没有初始化成功优先检查CONFIG_SERIAL_8250_CONSOLE和consolettyS0是否到位。virt机型的串口中断号、地址是固定的在设备树里体现为/soc/serial10000000我在内核里见过一种情况用户自己加了virtual_platform的代码导致设备树冲突串口地址被覆盖启动过程完全没有打印。定位到这类问题靠的就是“二分法测试最小配置”——只保留-machine virt -kernel Image -nographic不加盘、不加网络、不加自定义设备树再逐渐加回参数看哪个节点加入导致黑屏。6.2 rootfs 无法挂载VFS: Cannot open root device vda的三个常见原因virtio-blk设备看到的内核设备名通常是/dev/vda但如果你在 append 里写的是/dev/sda或者 root 设备写成.img文件名就会在挂载 rootfs 时 panic。我给 AGENT 定的规则很简单结合-drive的实际设备 id 来推断 root 设备名先不加root参数让内核自己枚举一遍块设备在日志的[?? ] sd 0:0:0:0: [sda]或类似的输出中确认设备号再补 root 参数。第二个原因是CONFIG_VIRTIO_BLK没编进内核。前面说过如果配置成m模块而没有提前做 initramfs启动到挂载阶段会直接失败。解决办法是在内核配置阶段把CONFIG_VIRTIO_BLKy写死。第三个原因是镜像格式。用dd创建的文件是 raw 格式QEMU 默认能识别但如果你用qemu-img创建了 qcow2 而启动时忘记加-drive ...,formatqcow2QEMU 在 raw 模式下读 qcow2 文件会直接读出坏块。检查方法很简单看file riscv64-rootfs.img的输出是data还是QEMU QCOW2 ImageAGENT 会把它和启动参数里的 format 字段做一致性校验。6.3 用户态程序Illegal instruction不一定是代码问题往往是 ISA 配置不一致QEMU 模拟下遇到Illegal instruction崩溃最常见的不是程序写错而是 CPU 特性与二进制编译目标不匹配。defconfig默认开启了 RISC-V 的 C 压缩指令扩展但是 QEMU 启动时如果用-cpu rv64没带con它模拟的 CPU 默认是否支持 C 扩展取决于 QEMU 版本。在 7.x 里rv64默认带 C在 8.x 部分版本却变成了需要显式配置。这导致我每次升级 QEMU 版本后都要重新核对一遍完整 CPU 特性。AI 芯片方向要特别注意的是向量扩展 RVV。现阶段 QEMU 对 RVV 1.0 的模拟正在逐步完善如果你的 AI 算子或运行时库是用启用 RVV 的编译器比如-marchrv64gcv编译的而 QEMU 的-cpu默认没开启vtrue运行必崩。排查手段是用gdb或 QEMU 内部的-d in_asm抓到非法指令的 PC再反汇编确认是vsetvli这类向量指令。这类问题的解决策略一般有两种要么关闭向量编译采用标量兼容路径要么在 QEMU 启动参数里显式开vtrue。对于“AI 芯片实验台”来说显式开启向量扩展更符合真实场景——因为你能在这种配置下更早验证向量算子的编译和调度逻辑。6.4 Agent 自身出错的三种典型情况这个项目的标题是“用 AGENT 做环境搭建”所以 AGENT 本身的问题排查也必须记录。我遇到的第一种情况是“过度自信的并行”。AGENT 看着有多核环境就想并行下载内核、编译根文件系统、配置 QEMU 参数结果互相抢占磁盘和内存导致 debootstrap 的解包出错。后来我给它加了一条规则阶段之间严格串行阶段内部可以先并行探测后串行执行。第二种情况是“上下文遗忘”。任务进行到内核编译阶段时AGENT 忘了前面已经安装过交叉工具链在日志里看到一条和工具链无关的 warning 后又重复执行了一遍apt install gcc-riscv64-linux-gnu。这类问题可以通过将“已完成状态”显式写到一个state.json文件里每次行动前后都读一遍来缓解。这是一个非常实用的 AGENT 工程技巧——不要依赖纯对话上下文记住状态外置状态文件更可靠。第三种情况是“工具调用失败后的盲目重试”。当网络下载失败时AGENT 会一直重试同一个wget命令这是非常典型的 AI 行为。我在任务卡里写了异常处理策略“同一命令连续失败两次则停止并改写方案”。改成从同行镜像站拉取或换用用户态模拟方式安装后问题瞬间解决。这类逻辑写在项目文档里会让任何人都能接手这套 AGENT 工作流。7. 进阶思考从“QEMU 能启动”到“AI 芯片的模拟可信度”7.1 模拟的边界与对后端的抽象——QEMU 到底能不能“像”一块 AI 芯片老实说QEMU 不可能真正模拟一块 NPU 的算力。它擅长的是模拟通用 CPU 和标准外设而 AI 芯片的加速器要么是自定义指令要么是专用 DMA 引擎。但作为软件栈开发平台QEMU 的作用在于“接口先行”让驱动代码、运行时调度、数据通路这些和硬件强相关的软件部分在流片前就能按真实寄存器的行为定义来开发测试。比如你可以把0x10000000到0x10001000这块 MMIO 区域当成 NPU 的配置寄存器在 QEMU 里把它挂上一个自定义的 platform device驱动写writel时 QEMU 会触发回调、更新设备状态机的模拟值。这种“模拟后端”与“真实后端”的抽象思路和现在很多软件工程的依赖注入如出一辙。我在项目里让 AGENT 做的事情是从设备树节点定义到驱动 probe 函数再到 QEMU 的-device参数一条链路全部打通。对于做 AI 芯片系统软件的朋友这个实验台可以直接作为驱动开发的语法验证环境、运行时调度框架的功能测试环境、以及给算法同学做算子移植的“0 号沙箱”。算力上不要有幻想但功能逻辑上是可信的。7.2 后续扩展快照、CI、以及多节点仿真的升级路径这个实验台搭好之后有三个非常自然的扩展方向第一个是快照复用。QEMU 的 monitor 支持savevm/loadvm在搭建好整套带 AI 驱动的环境后打一个快照。之后每次团队新成员入职只需要加载这个快照就能获得统一环境比让他们从头debootstrap节省一整天。第二个是 CI 集成。把“启动 QEMU→跑冒烟测试→快照保存”写进 GitLab CI 或 GitHub Actions 里每次内核或 rootfs 更新后自动跑一遍AGENT 把失败日志自动归类到 issue 或飞书群通知。有这套机制后软件栈的回归效率提升非常明显。第三个是多节点仿真。QEMU 支持-netdev socket组成的多台虚拟机互联两个 RISC-V QEMU 通过模拟网络通信就能复现多芯片卡间通信的软件路径。AI 芯片往往有成百上千个计算节点虽然 QEMU 跑大规模仿真不现实但验证点对点的通信协议和组网逻辑完全够了。做这类扩展时AGENT 的价值会被进一步放大它可以在无人值守的情况下把“一天 200 次构建—启动—测试—报告”的循环跑起来而且每次执行都有日志可审计。这其实已经接近“AI Agent 做性能验证工程师”的工作模式了。8. 经验总结这套环境搭建下来我最想说的三句话先说第一句QEMU 搭建 RISC-V 环境这件事难点从来不在 QEMU 命令本身而在构建链路上所有版本、配置和设备树的隐性耦合。你在 A 机器的完美命令拿到 B 机器上可能就黑屏原因可能只是 QEMU 版本不同导致内存布局变化。所以搭建环境和开发软件一样必须有版本锁定和产物校验的习惯。我这次用 AGENT 做的每一份构建产物都有 SHA256 记录这种“可验证闭环”会在你对着一份陌生机器的报错日志时省下你大量排查时间。第二句是关于 Agent 的把 AGENT 当成“记性差但有执行能力的实习生”。它需要在每个关键决策点有明确的输入和输出格式需要有外置状态文件来记住已完成的工作更需要验收标准来约束它的自由发挥。很多人在用 AGENT 做环境搭建时总期待它“一次成功”这不现实。你要设计的是“失败后如何低成本恢复”的流程以及“如何让 Agent 的每一步都留下日志”这比期待一个完美的 AI 更重要。第三句是关于 AI 芯片研发的软件虚拟平台和真实硬件之间的“接口一致性”决定了这套实验台未来能发挥多大价值。建议在环境刚搭好、还没被各种临时修改污染的时候就把设备树、启动脚本、驱动框架版本全部归档到一个 git 仓库里。后续真实芯片回来后你只需要替换底层设备访问层整个上层的 AI 运行时、驱动框架、测试用例的迁移成本会小很多。最后再分享一个小技巧在 QEMU 启动参数的-append最后加上quiet可以过滤掉大部分启动噪音只保留内核错误和关键日志但调试阶段千万不要加这个参数——启动过程的每一行信息都可能成为 AGENT 判断根因的线索。这个设置我在项目里踩过坑调试时加了quiet导致 HALF 数据丢失最后还是靠去掉quiet从日志里定位到问题。环境搭建的乐趣就在这种“去掉一层噪声看清一层机理”的过程中希望这套基于 AGENT 的 RISC-V AI 实验台也能帮你少走几段弯路。