openEuler RISC-V 零基础入门实操:从装 QEMU 到跑通第一个 RISC-V 程序
openEuler RISC-V 零基础入门实操:从装 QEMU 到跑通第一个 RISC-V 程序
作者:linght153
关键词:openEuler、RISC-V、QEMU、虚拟机、gcc、hello world
一、写在前面:为什么我非要折腾一台"假"的 RISC-V 电脑
最近在跟着 openEuler RISC-V 相关的学习资料做入门实践,第一道坎就是:我手上没有 RISC-V 开发板,怎么办?
答案就是 QEMU——一个开源模拟器,可以在我的 x86 电脑上"假装"出一台完整的 RISC-V 电脑(CPU、内存、硬盘、网卡全都有),然后在里面装一个真正的 openEuler RISC-V 操作系统。更妙的是,QEMU 用的是纯软件模拟(TCG 技术),不需要 CPU 支持硬件虚拟化,也不用去 BIOS 里开 VT-x,装完就能用。
这篇文章就是我的完整实操记录:从装 QEMU、下载镜像、启动虚拟机,到在 riscv64 系统里编译运行我写的第一个 C 程序。全程第一人称踩坑实录,零基础可跟。
我的环境:Windows 11 + WSL2(Ubuntu 22.04),所有命令都在 WSL 终端里执行。如果你用 Windows 原生 PowerShell 或 macOS,命令大同小异,我在文末踩坑区会标注差异点。
二、环境准备:装 QEMU 并完成"验证三连"
2.1 安装 WSL(Windows 用户)
管理员身份打开 PowerShell,执行:
wsl --install
重启后按提示设置 Ubuntu 的用户名和密码(记好这个密码,sudo 要用)。装好后打开"开始菜单 → Ubuntu"进入 Linux 终端。
2.2 安装 QEMU
在 WSL 终端里依次执行:
sudo apt update
sudo apt install -y qemu-system-misc qemu-utils
qemu-system-misc 这个包里就包含了 riscv64 等"杂项架构"的全系统模拟器,qemu-utils 提供 qemu-img 工具。装完 qemu-system-riscv64 就在系统里了。
2.3 验证三连(装完必做)
qemu-system-riscv64 --version
qemu-system-riscv64 -machine help | grep virt
qemu-img --version
我的实际输出:
QEMU emulator version 8.2.2 (Debian 1:8.2.2+dfsg-1~22.04.5)
Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers
virt RISC-V VirtIO Board (default)
三条全过 = QEMU 装好了。要求版本号 ≥ 7.0,因为 openEuler 24.03 LTS 的官方镜像和启动脚本是按新版 QEMU 写的;-machine help 里能看到 virt 行说明模拟器支持 openEuler 官方镜像默认的机器型号。
💡 踩坑预警:如果你的 WSL 里
apt update卡住不动,多半是 Ubuntu 官方源在大陆网络慢,把/etc/apt/sources.list里的archive.ubuntu.com换成清华或阿里镜像源再试。
三、下载镜像:三个文件,一个都不能少
打开 openEuler 官方下载页:https://www.openeuler.org/zh/download/,找到 24.03 LTS 版本 → RISC-V 架构分区 → 虚拟机镜像区,下载这四个文件到 ~/riscv-lab/ 目录:
openEuler-24.03-LTS-SP3-riscv64.qcow2.xz # 磁盘镜像压缩包,约 3-5GB,最大最慢
RISCV_VIRT_CODE.fd # UEFI 固件-代码(几 MB)
RISCV_VIRT_VARS.fd # UEFI 固件-变量(几 MB)
start_vm.sh # 官方启动脚本(几 KB)
三个文件的角色:.qcow2.xz 是整块硬盘(装了 openEuler 系统,被 xz 压缩打包了);两个 .fd 是UEFI 固件(电脑开机第一段代码,负责把系统从硬盘里叫醒);start_vm.sh 是官方写好的启动说明书。
下载完做两件事:
- 看大小:qcow2.xz 应该有 3-5GB,如果只有几百 MB,多半是下载中断了,删掉重下。
- 校验完整性:用
sha256sum对比下载页给的校验值,整串一致才放心:
cd ~/riscv-lab
sha256sum openEuler-24.03-LTS-SP3-riscv64.qcow2.xz
⏳ 踩坑预警:镜像下载慢是大陆网络的老大难。我的解法三件套:① 用支持断点续传的下载工具(IDM/迅雷),断了不用从头来;② 换清华镜像源
https://mirrors.tuna.tsinghua.edu.cn/openeuler/,路径结构和官方站一致;③ 实在不行就半夜下(说多了都是泪,但真的快)。
四、解压 + 启动:那条 200 字符的长命令,逐参数看懂
4.1 解压镜像
cd ~/riscv-lab
xz -dk openEuler-24.03-LTS-SP3-riscv64.qcow2.xz
-d 是解压(decompress),-k 是保留原压缩包。解压要等 1-5 分钟,终端没输出是正常的。完成后 ls -lh 应该能看到不带 .xz 后缀的 qcow2 文件(解压后约 5-7GB)。
4.2 启动命令逐参数拆解
第一次启动,我建议直接用官方 start_vm.sh,但一定要看懂它在干什么。它的核心就是下面这条命令(我整理成了经典写法,每个参数独立一行,行尾 \ 只是续行符):
qemu-system-riscv64 \
-machine virt -m 4G -smp 4 \
-drive file=openEuler-24.03-LTS-SP3-riscv64.qcow2,format=qcow2,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-netdev user,id=n0,hostfwd=tcp::12055-:22 \
-device virtio-net-device,netdev=n0 \
-nographic
用人话翻译:“QEMU,请模拟一台 RISC-V 电脑(virt 型号),给它 4GB 内存、4 个 CPU 核心;把 qcow2 文件当作硬盘接上;给它一张能上网的虚拟网卡,并把宿主机的 12055 端口转发到虚拟机的 22 号端口;不开图形窗口,所有输出走终端。”
各参数逐个说:
| 参数 | 含义 | 去掉会怎样 |
|---|---|---|
-machine virt |
机器型号,virt 是 RISC-V 世界最常用的虚拟主板 |
报错 No machine specified |
-m 4G |
内存 4GB(从宿主机"借"走的,别开太大) | 内存太小起不来 |
-smp 4 |
4 个 CPU 核心(纯软件模拟,核给多了宿主机反而卡) | 默认 1 核,慢但能跑 |
-drive ... |
定义硬盘:file= 指定 qcow2 文件,format=qcow2 声明格式,id=hd0 起名 |
系统无盘可用 |
-device virtio-blk-device,drive=hd0 |
把硬盘 hd0 通过 virtio 高速总线接上主板 |
硬盘"看不见",Kernel panic |
-netdev user,...hostfwd=tcp::12055-:22 |
用户模式网卡 + 端口转发:访问宿主机 12055 端口 = 访问 VM 的 22 端口(SSH) | VM 无法上网、无法 SSH |
-device virtio-net-device,netdev=n0 |
把网卡接上主板 | 网卡"看不见" |
-nographic |
不开图形窗口,虚拟机的"屏幕"直接接到终端 | 尝试开图形窗口,无图形环境会报错 |
📌 这里最重要、全书必考的是
hostfwd=tcp::12055-:22:它决定了你后面能不能 SSH 进虚拟机。22 是 SSH 默认端口,12055 是宿主机上的映射端口(高位端口,避免和宿主机自己的 22 冲突)。想换就换,但换了以后 SSH 命令的-p参数要跟着改。
4.3 启动!你会看到四个阶段
./start_vm.sh
💡 踩坑预警:如果报
Permission denied,说明脚本没有执行权限,先chmod +x start_vm.sh再运行。如果报command not found,检查pwd确认你在riscv-lab目录里。
回车后耐心等待 1-3 分钟,启动日志按这个顺序刷屏:
OpenSBI v1.4
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
...(固件先醒来,确认自己在 QEMU 的 virt 机器上)
[ 0.000000] Linux version 6.6.0-76.0.0.76.oe2403.riscv64 (oe-build@localhost) ...
[ 0.000000] CPU: rv64imafdc_zicsr_zifencei_zba_zbb_zbc_zbs ...
[ 0.000000] 4 CPUs detected
[ 1.234567] virtio_blk virtio0: [vda] 62914560 512-byte logical blocks (32.2 GB)
[ 3.456789] systemd[1]: Running in virtual machine.
[ OK ] Started OpenSSH server daemon.
[ OK ] Reached target Multi-User System.
openEuler Linux 24.03 (LTS)
Kernel 6.6.0-76.0.0.76.oe2403.riscv64 on an riscv64
localhost login:
看到 login: 提示符,你的第一台 RISC-V 虚拟机就启动成功了! 重点看三处:Linux version ...riscv64(RISC-V 世界的内核)、virtio_blk ... [vda](你的 qcow2 硬盘被识别了)、on an riscv64(架构实锤)。
4.4 登录 + 立刻改密码
localhost login: root
Password: openEuler12#$
openEuler RISC-V 官方镜像默认密码是 openEuler12#$(#$ 是密码的一部分,一共 13 个字符,别把 # 打成中文的)。输密码时屏幕什么都不显示——这是 Linux 的安全设计,不是键盘坏了,盲打回车即可。
登录成功提示符会变成 [root@localhost ~]#(# 是 root 用户的标志)。第一件事改密码:
passwd
⚠️ 默认密码全世界都知道,登录后必须立刻改。密码至少 8 位,建议字母+数字+符号混合。忘了密码很麻烦(要进单用户模式重置),一定记牢。
五、换个姿势进门:SSH 远程登录
在 QEMU 黑窗口里操作只是第一步,真实服务器工作流全靠 SSH。回到宿主机终端:
ssh root@127.0.0.1 -p 12055
第一次连接会弹"主机指纹确认"提示(这是 SSH 的防伪机制,防止有人冒充你的 VM),输入完整的 yes 回车,然后输 VM 的 root 密码。登录后验证一下:
uname -m
输出 riscv64——你在 x86 宿主机上,手却伸进了 riscv64 的虚拟机,这就是 12055 端口转发的功劳。
💡 进阶一步:
ssh-keygen -t ed25519生成密钥对,再ssh-copy-id root@127.0.0.1 -p 12055把公钥登记进 VM,以后ssh root@127.0.0.1 -p 12055免密直进,传文件用scp -P 12055 文件 root@127.0.0.1:/root/(注意 scp 是大写-P,ssh 是小写-p,这个坑坑过无数人)。
六、第一个 RISC-V 程序:从装 gcc 到跑通 hello
6.1 装编译器
在 VM 里执行(注意提示符是 [root@localhost ~]#,别在宿主机敲):
dnf install -y gcc
注意输出里这行:gcc riscv64 12.3.1-2.oe2403——你装的是 riscv64 版的 gcc,它编译出来的机器码就是 RISC-V 方言,这就是"原生编译"。验证:
gcc --version
gcc (GCC) 12.3.1 20230508 (openEuler 12.3.1-2.oe2403)
6.2 写 hello.c
nano hello.c
输入(强烈建议手敲一遍,别复制):
#include <stdio.h>
int main(void)
{
printf("Hello from RISC-V!\n");
return 0;
}
Ctrl+O 保存,Ctrl+X 退出。逐行含义一句话版:#include <stdio.h> 是引入标准输入输出库的"说明书";int main(void) 是程序唯一的大门,CPU 从这里开始执行;printf 把文字打到屏幕,\n 是换行,行尾分号 ; 是 C 语言的"句号"(漏掉它是新手第一大报错来源);return 0 表示程序正常结束。
6.3 编译 → 运行 → 验证架构(三连)
gcc hello.c -o hello
./hello
file hello
我的实际输出:
Hello from RISC-V!
hello: ELF 64-bit LSB executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1, for GNU/Linux 4.15.0, not stripped
三个要点:
gcc hello.c -o hello编译成功是"沉默"的——没有任何输出就是最好的输出(注意-o是小写字母 o,不是数字 0)。- 运行必须写
./hello——Linux 默认不在当前目录找命令,直接敲hello会报command not found。 file hello是本章最有成就感的时刻:输出里UCB RISC-V就是架构实锤(UCB = 加州大学伯克利分校,RISC-V 的诞生地,名字留在了 ELF 格式里);RVC表示用了压缩指令扩展;/lib/ld-linux-riscv64-lp64d.so.1是 riscv64 的程序加载器。
强烈建议做个对照实验:把 hello.c 在 x86 宿主机上也编译一次,file 输出会变成 ELF 64-bit ... x86-64 ...——同一个源码,不同架构的编译器,产出不同"方言"的机器码。把 VM 里编的 hello 拷到宿主机运行,会报 Exec format error(架构不对,不是文件坏了)。架构的壁垒,这一刻你亲手摸到了。
七、踩坑合集:我替你踩过的坑
| 现象 | 原因 | 解法 |
|---|---|---|
执行脚本报 Permission denied |
脚本没有执行权限 | chmod +x start_oe.sh,或改用 bash start_oe.sh |
启动报 Failed to bind socket: Address already in use |
12055 端口被占(上次 VM 没关干净 / 别的程序占用) | 换端口(改脚本里的 hostfwd 和 SSH 的 -p);查占用:Windows netstat -ano | findstr 12055,Linux ss -ltnp | grep 12055 |
| 镜像下载慢 / 中断 | 官方站在大陆网络慢 | 清华镜像源 mirrors.tuna.tsinghua.edu.cn/openeuler/;IDM/迅雷断点续传;sha256sum 校验完整性 |
ssh: connect to host 127.0.0.1 port 22: Connection refused |
忘了写 -p 12055,ssh 默认去敲 22 端口 |
命令补上 -p 12055 |
SSH 报 Connection refused(端口写对了) |
VM 没启动 / 防火墙拦截 / VM 里 sshd 没运行 | 确认 QEMU 窗口还开着;Windows 防火墙放行 qemu;VM 里 systemctl start sshd |
| 输密码没反应 | 正常现象,终端故意不回显密码 | 盲打回车即可 |
bash: hello: command not found |
运行少了 ./ 前缀 |
写 ./hello |
bash: ./hello: cannot execute binary file: Exec format error |
把 x86 编译的程序拷进 riscv64 VM 跑(反过来也一样) | 在目标机器上重新编译,或学交叉编译 |
编译报 stray '\...' in program |
代码里混入全角字符(中文引号/分号,输入法没切回) | 按 文件名:行号:列号 定位,改成英文半角 |
| 杀毒软件把 QEMU 当病毒 | 误报(模拟器常被误判为"黑客工具") | 从官网 qemu.org 下载,加白名单(安装目录 + 工作目录) |
八、总结:我这一路学到了什么
从零到跑通第一个 RISC-V 程序,我完成了三件有里程碑意义的事:
- 装好了 QEMU,用纯软件模拟在 x86 电脑上"无中生有"了一台 RISC-V 电脑——不需要真机,不需要硬件虚拟化。
- 看懂了一条 200 字符的 QEMU 启动命令:
-machine选机型、-m给内存、-smp给核数、-drive挂硬盘、-netdev hostfwd做端口转发、-nographic走终端。从此虚拟机在我眼里不再是"黑魔法",而是一台参数明确的电脑。 - 在 riscv64 上原生编译并运行了自己的程序,并且用
file hello亲眼看到了UCB RISC-V的字样——那一刻我才真正理解了什么是"架构":同一个printf,x86 和 RISC-V 会翻译成完全不同的机器码,程序必须在目标架构上编译才能运行。
下一步我准备挑战交叉编译:在 x86 宿主机上用 riscv64-linux-gnu-gcc 编出 riscv64 的程序,再用 qemu-riscv64(用户态模拟)直接验证——“编译放宿主机、运行验证靠模拟器”,这是 RISC-V 软件生态里最常用的生产工作流,也是我实习测评工作的标准姿势。等我把 RVV 向量扩展也玩明白了,再来分享第二篇。
如果这篇文章帮到了你,或者你在实操中遇到了其他坑,欢迎评论区交流。RISC-V 的世界,入门真的没有想象中那么难。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)