1. 为什么我会把 Ubuntu 20.04 和 QEMU 放在一起讲
先交代一个背景。上个月我在做内核模块和交叉编译的实验,手头是一台 Windows 笔记本,但目标运行环境必须是一个干净的 Ubuntu 系统。一开始我图省事,直接在 VMware 里装了一个 Ubuntu 22.04,结果在编译某个老版本内核模块的时候,编译器行为和目标平台差异太大,折腾两天都没对上。后来换成 Ubuntu 20.04 搭配 QEMU 方案,问题立刻清晰了很多——这套组合让我第一次真正体会到“底层环境可控”有多重要。
1.1 这两个关键词的组合不是偶然
Ubuntu 20.04 是 2020 年 4 月发布的 LTS 版本,官方支持到 2030 年。它的特殊之处在于,很多老牌开源项目的依赖树都停留在这一代系统上。最典型的就是 ROS Noetic,它官方只支持 Ubuntu 20.04,想跑 Noetic 的同学绕不开这个版本。另外像一些嵌入式工具链、老版本 GCC、特定版本的 Python 环境,在 20.04 上表现最稳定。这不是说 22.04 不好,而是很多软件生态的“舒适区”恰好落在 20.04 上。
QEMU 则是一个纯软件的全系统模拟器。它和 VirtualBox、VMware 最大的不同是:不挑宿主机架构,也不挑客户机架构。你可以在一台 x86 的笔记本上模拟出 ARM 开发板、MIPS 路由器、甚至 RISC-V 的环境。对做嵌入式开发和内核学习的人来说,这几乎是刚需。很多热心网友搜索“qemu arm m3”就是想用 QEMU 模拟 Cortex-M3 开发板跑裸机程序。
把这两者放在一起,解决的是一个很实际的问题:你既需要一个稳定的基础系统作为宿主,又需要一套灵活的模拟环境去跑各种实验。Ubuntu 20.04 做宿主足够稳,QEMU 做模拟层足够灵活,主客配合下来,从内核模块调试到嵌入式固件开发都能覆盖。
1.2 这套方案适合什么样的读者
明确一下受众。如果你属于下面这几类人,这篇文章对你会很有用:
- 刚接触 Linux 的学生,需要在本地搭一个不容易弄坏主机的实验环境;
- 做嵌入式开发的工程师,需要在 x86 电脑上模拟 ARM 开发板;
- 做内核或驱动开发的人,需要一个可以随时快照、随时回滚的测试环境;
- 想搭 ROS Noetic 开发环境但不想重装系统的同学。
如果你只是需要一个日常办公用的 Linux 桌面,那直接装 Ubuntu 22.04 或者 24.04 会更省心,没必要绕这么大一圈。但如果你追求的是“环境可控、踩坑可复现、系统随便折腾”,那 Ubuntu 20.04 加 QEMU 这套组合比任何现成虚拟机都合适。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Ubuntu 20.04 到手前的三选一:双系统、虚拟机、WSL2
在安装 QEMU 之前,你得先有一个能用的 Ubuntu 20.04 环境。这里有三条路:物理机双系统、传统虚拟机、WSL2。很多人一上来就问“哪个好”,其实没有标准答案,只看你的场景适合哪一种。
2.1 物理机双系统:性能最完整,代价是分区和引导
如果你的电脑配置不差,而且你确定未来几个月都要在 Linux 下重度工作,那我建议直接装双系统。Ubuntu 20.04 的 ISO 从官网下载就行,大小 2 到 4 GB,用 Rufus 或 Ventoy 做成启动 U 盘。
安装过程有几个关键点容易被忽略。第一,进 BIOS 关闭 Secure Boot,否则 U 盘引导大概率失败。第二,分区时建议手动分区:/ 根分区 50 GB 起步,/home 单独分一个区放个人文件,swap 分区给 8 GB 就够。第三,如果电脑原本是 Windows,安装时选择“Install Ubuntu alongside Windows Boot Manager”,grub 会自动识别 Windows 引导项,开机时让你选系统。
这里提醒一个容易踩的坑:有些电脑是 NVMe 固态加 UEFI 引导,安装完成之后进入 grub 菜单,发现 Windows 启动项不见了。这不是 Ubuntu 的错,而是因为 Windows 的 EFI 分区没有被正确挂载。解决办法是进 Ubuntu 后执行 sudo update-grub 它会重新扫描 EFI 分区并生成 Windows 的引导项。如果还不行,手动挂载 Windows EFI 分区后再次 update-grub,基本都能解决。
2.2 传统虚拟机里装 Ubuntu:适合快速验证和过渡
如果只是临时用一下,或者不想动物理机的分区,那在 VMware Workstation 或 VirtualBox 里装 Ubuntu 20.04 是最省事的。新建虚拟机时选择 Ubuntu 64-bit 模板,内存建议分配 4 GB 以上,磁盘 40 GB 就够日常用。
虚拟机方案的优点是可以随意拍快照,系统搞坏了三秒钟回滚。缺点是嵌套虚拟化的性能损耗,不过如果你只是做普通开发,完全感受不到差别。有一点要注意:QEMU 在虚拟机里跑的时候,如果也需要硬件加速,那需要开启“虚拟化 Intel VT-x/AMD-V”选项,否则 QEMU 只能纯软件模拟,速度会非常慢。也就是说,你可以在 VMware 里装 Ubuntu,再在 Ubuntu 里跑 QEMU,属于套娃式方案,性能会打折,但作为学习环境是完全可行的。
2.3 WSL2:轻量但有限制
WSL2 是 Windows 自带的 Linux 子系统,安装方式命令行执行 wsl --install -d Ubuntu-20.04 就会自动拉取镜像。WSL2 的优点是启动快、几乎不占额外资源,和 Windows 文件系统互通非常方便。我用 WSL2 跑过 Ubuntu 20.04 加 QEMU,日常做命令行操作没问题,但有两个限制很影响体验。
第一个限制是 WSL2 本身是一个轻量虚拟机,它的网络模式是 NAT,QEMU 里再用用户模式网络的话,端口转发会变得很绕。第二个限制是图形界面。WSL2 的 WSLg 能跑 GUI 应用,但对 QEMU 的图形输出支持并不完善,显卡模拟经常出问题。所以如果你想用 QEMU 跑一个带桌面的系统,我建议还是老老实实用双系统或传统虚拟机,不要在 WSL2 上死磕。不过如果你只是用 QEMU 跑无头服务或者纯命令行系统,WSL2 加 QEMU 是没问题的。
选择建议很简单:长期重度使用选双系统,想快速验证选虚拟机,纯命令行测试选 WSL2。这篇后面所有内容,我以物理机 Ubuntu 20.04 环境为例。
3. QEMU 安装:apt 一把梭还是源码编译
Ubuntu 20.04 装好之后,进入 QEMU 的安装环节。这里也有两条路:用 apt 直接装官方包,或者源码编译。大多数情况下 apt 就够用,但有特定模拟目标的时候,源码编译反而能帮你少踩很多坑。
3.1 用 apt 安装:三分钟搞定基础环境
Ubuntu 20.04 官方源里的 QEMU 版本是 4.2.1,虽然不算新,但稳定性和兼容性都经过大量验证。执行下面这条命令就行:
bash复制sudo apt update
sudo apt install qemu-system qemu-utils qemu-user
qemu-system 包含架构相关的系统模拟器,包括 qemu-system-x86_64、qemu-system-arm、qemu-system-aarch64 等。qemu-utils 提供 qemu-img 等磁盘镜像工具。qemu-user 是用户态模拟器,如果你需要在 x86 上直接运行 ARM 编译出来的 Linux 可执行文件,这个包才用得上,不装也不影响整体使用。
如果你只想要某一个架构的模拟器,也可以精确安装,比如 qemu-system-arm 只装 ARM 相关的。但我不建议这样精确控制,因为后面你可能突然想模拟 x86 或者 RISC-V,缺一个包又得重新装,还不如一开始全量安装。
3.2 源码编译:什么时候需要这么做
官方源里的 QEMU 版本通常比上游慢一两个大版本。如果你需要模拟比较新的开发板,或者需要 QEMU 新版本对某些 ARM 外设的完整支持,那就要自己编译。
编译 QEMU 之前要装一堆依赖,这是最容易让人放弃的地方。我整理过一个最小依赖清单:
bash复制sudo apt install git build-essential ninja-build python3-venv \
libglib2.0-dev libpixman-1-dev libfdt-dev zlib1g-dev
然后从官网下载源码包,或者 clone 官方仓库:
bash复制git clone https://gitlab.com/qemu-project/qemu.git
cd qemu
mkdir build && cd build
../configure --target-list=x86_64-softmmu,arm-softmmu,aarch64-softmmu
make -j$(nproc)
--target-list 参数很重要,它决定你要编译哪些架构的模拟器。如果你全都编译,时间会非常长。只选常用的三个架构,1504 个配置基本 10 分钟左右能编完。如果你编译完发现命令还是老的,记得检查一下 PATH,源码编译出来的可执行文件在 build 目录下,比如 ./build/qemu-system-x86_64,用绝对路径调用就行。
这里有个实际经验:我不推荐为了追求新版本而盲目源码编译。QEMU 4.2.1 虽然老,但跑 Ubuntu 20.04 客户机、跑 ARM 裸机程序完全没问题。只有当你遇到具体的不兼容问题,再考虑升级到源码版本。
3.3 安装完成后怎么验证
不管用哪种方式安装,验证环境是否可用是同样的三步:
bash复制qemu-system-x86_64 --version
qemu-img --version
qemu-system-arm -machine help | head -20
第一步看版本确认安装成功;第二步确认磁盘工具可用;第三步看当前 QEMU 支持哪些 machine 类型。qemu-system-arm -machine help 的输出会列出一大堆开发板名称,比如 vexpress-a9、raspi2、mps2-an385 等。这一步能帮你确认编译时是否带了 ARM 支持,也方便后续选择正确的开发板类型。
4. 从零跑通一个 QEMU 虚拟机:磁盘、安装与启动参数
很多教程到这里就让你 qemu-system-x86_64 -hda ubuntu.img 直接跑,但你真的理解每个参数在干什么吗?我在这一节把从创建磁盘到启动系统的完整过程拆开讲,确保你以后遇到别的架构也能举一反三。
4.1 用 qemu-img 创建磁盘镜像
磁盘镜像是 QEMU 虚拟机的“硬盘”。创建一个即可:
bash复制cd ~/qemu-test
qemu-img create -f qcow2 ubuntu20.img 50G
qcow2 是 QEMU 最常用的镜像格式,它的特点是按需分配空间。你创建一个 50G 的镜像,实际占用可能只有几百 MB,等虚拟机里真正写入数据才会慢慢增大。这是普通文件镜像(raw)做不到的。
除了按需分配,qcow2 还支持快照。在 QEMU 命令行里用 -snapshot 参数启动,系统运行期间做的所有修改都只写入临时文件,退出后镜像恢复原样。这对做实验来说简直太方便了。比如你想练分区操作,失败了也不会有任何后果。
4.2 在 QEMU 里安装 Ubuntu 系统
如果你已经有了一个现成的 Ubuntu 20.04 ISO,可以挂载到 QEMU 虚拟机里当安装光盘。基础启动命令如下:
bash复制qemu-system-x86_64 \
-m 4096 \
-smp 4 \
-enable-kvm \
-cpu host \
-drive file=ubuntu20.img,format=qcow2 \
-cdrom ubuntu-20.04.6-desktop-amd64.iso \
-boot d \
-netdev user,id=net0 \
-device e1000,netdev=net0
一个个解释参数:
-m 4096分配 4 GB 内存给虚拟机。-smp 4分配 4 个虚拟 CPU 核心。-enable-kvm开启 KVM 硬件加速。没有这个参数 QEMU 会退化为纯软件模拟,速度慢到怀疑人生。-cpu host让虚拟 CPU 直接使用宿主机的 CPU 特性,性能最好。-drive指定磁盘镜像。-cdrom挂载安装 ISO。-boot d指定从光驱引导。-netdev user,id=net0创建用户模式网络,-device e1000添加一块网卡并连接到这个网络。
启动后你会看到系统安装界面,正常跟着安装步骤走就行。这里要提醒一句:Ubuntu 桌面版安装过程中可能需要比较长时间,耐心等,不要因为暂时的卡顿就强制关闭窗口。
4.3 日常启动参数与常用配置项
安装完成之后,后续启动不需要再挂 ISO,把 -cdrom 和 -boot d 去掉就行:
bash复制qemu-system-x86_64 \
-m 4096 \
-smp 4 \
-enable-kvm \
-cpu host \
-drive file=ubuntu20.img,format=qcow2 \
-netdev user,id=net0 \
-device e1000,netdev=net0
如果嫌命令行太长,可以把参数写进一个 shell 脚本,每次直接执行脚本。这也是我推荐的做法,一个项目一个脚本,参数清晰,改起来也方便。你还可以加两个很实用的参数:
-display none不带图形界面运行,适合服务器场景。-daemonize让 QEMU 进程后台运行。
这两个参数配合 SSH 使用,你完全可以在终端里像操作远程服务器一样操作这个虚拟机。
4.4 给镜像扩容的场景
用着用着磁盘不够了,这是躲不开的问题。qcow2 镜像扩容的命令是:
bash复制qemu-img resize ubuntu20.img +50G
扩容之后到虚拟机内部还要做一步。先用 df -h 确认当前分区大小,再用 growpart 和 resize2fs 扩展文件系统:
bash复制sudo growpart /dev/vda 1
sudo resize2fs /dev/vda1
这里用到的设备名取决于虚拟磁盘类型,virtio 驱动下通常是 vda,如果是 IDE 可能是 sda。执行 growpart 时要格外小心,别把分区编号写错,否则数据可能丢失。
5. 让 QEMU 真正可用的三个配置:网络、共享目录与远程连接
QEMU 系统跑起来之后,你马上会面对三个现实问题:虚拟机里怎么上网、怎么和宿主机传文件、怎么不靠图形窗口也能操作它。这节一次性讲清楚。
5.1 用户模式网络与端口转发
上面的启动参数里我用了 -netdev user,这就是 QEMU 的用户模式网络。它最大的优点是零配置,虚拟机里默认就能通过 NAT 上网。但用户模式网络有一个天然限制:外部访问不进虚拟机内部,除非你设置端口转发。
端口转发的写法是在 -netdev user 后面加 hostfwd 参数:
bash复制-netdev user,id=net0,hostfwd=tcp::2222-:22
这个参数的意思是宿主机的 2222 端口映射到虚拟机的 22 端口。这样你在宿主机上执行:
bash复制ssh -p 2222 user@localhost
就可以直接登录虚拟机了。如果你要在虚拟机里跑 Web 服务并希望从宿主机访问,原理一样,比如 hostfwd=tcp::8080-:80。
5.2 桥接网络:让虚拟机成为局域网里的一台“真机”
用户模式网络虽然方便,但不支持组播、不支持外部设备直接连接虚拟机。如果你在虚拟机上搭了局域网服务,想让手机或别的电脑直接访问,就需要桥接模式。
QEMU 的桥接模式需要手动创建网桥,不能像 VirtualBox 那样点一下就好。Ubuntu 20.04 下用 netplan 配置比较简单。假设你的物理网卡叫 enp3s0,配置一个 br0 网桥:
yaml复制network:
version: 2
ethernets:
enp3s0:
dhcp4: no
bridges:
br0:
interfaces: [enp3s0]
dhcp4: yes
然后在 QEMU 启动命令里加上:
bash复制-netdev bridge,id=net0,br=br0 \
-device e1000,netdev=net0
请注意,使用桥接模式需要 QEMU 有访问 /dev/net/tun 的权限,而且创建 /dev/net/tun 节点通常需要 root 权限。实际使用中我建议只在局域网调试场景下用桥接,日常学习用用户模式网络就够了。
5.3 共享目录:用 virtfs 在宿主机和虚拟机之间传文件
虚拟机里最痛苦的事情之一就是宿主机和客户机之间倒腾文件。QEMU 提供了 virtfs(也叫 9p 文件系统)来做共享目录,比配置 Samba 或者 scp 来回拷效率高多了。
启动参数加两行:
bash复制-fsdev local,id=myid,path=/home/user/shared,security_model=none \
-device virtio-9p-pci,fsdev=myid,mount_tag=hostshare
然后在虚拟机内部挂载:
bash复制sudo mkdir -p /mnt/shared
sudo mount -t 9p -o trans=virtio hostshare /mnt/shared
挂载成功之后,宿主机 /home/user/shared 和虚拟机 /mnt/shared 就是同一个目录,两边修改实时同步。这个方案在做交叉编译时特别好用:在宿主机上写好代码,虚拟机里直接编译运行。
有一个使用技巧:security_model=none 的意思是不做文件权限映射,虚拟机里的 root 可以直接读写宿主机上的文件。如果你想限制权限,可以改成 security_model=mapped,但复杂度和性能都会受一点影响,默认 none 即可。
5.4 远程操作:SSH 与图形界面的选择
QEMU 自带一个 VNC 图形输出,默认监听在 5900 端口。你可以用任何 VNC 客户端连接,也可以加 -vnc :1 让它监听在 5901。但在实际使用中我更推荐 SSH,理由很简单:比 VNC 轻量、稳定、传输文件方便。
虚拟机里安装并启动 SSH 服务:
bash复制sudo apt install openssh-server
sudo systemctl enable ssh --now
然后按照 5.1 小节的端口转发配置,宿主机执行 ssh -p 2222 user@localhost 就能登录。配合 SSH 的 X11 转发,虚拟机里的 GUI 程序也能在宿主机桌面上显示,完全不需要 QEMU 的图形窗口。
有个点要提前提醒:QEMU 的图形输出在 Windows 宿主机上的表现一般,尤其是分辨率识别和剪贴板共享功能都不太行。如果你想获得接近 VMware 的图形体验,现阶段最好的做法是用 virt-manager 来管理 QEMU。virt-manager 是一个图形化前端,支持窗口自适应和剪贴板共享,装好之后用 virt-manager 命令打开,界面交互熟悉后比在命令行里手敲参数舒服很多。
6. 实际部署中踩过的坑和完整排查链路
这个标题下我要讲的是真实踩坑的过程,不是说教的罗列。QEMU 看似简单,但坑都在细节里,而且多数错误信息非常不友好,不把排查思路理清楚,你可能会卡在一个小问题上很久。
6.1 KVM 权限问题:明明装了 KVM 却提示不可用
有一次我新建了一个虚拟机,启动命令里加了 -enable-kvm,结果 QEMU 直接报错:“Could not access KVM kernel module: Permission denied”。我当时第一反应是内核没加载 KVM 模块,但检查后发现 /dev/kvm 设备文件是存在的,只是当前用户没有权限访问。
排查过程是这样的:
bash复制ls -l /dev/kvm
输出显示 /dev/kvm 的属主是 root,组是 kvm。当前用户不在 kvm 组里。解决方案很简单:
bash复制sudo usermod -aG kvm $USER
重新登录生效。改完之后再跑 QEMU,问题解决。这提醒我,遇到权限类报错先看设备文件权限,不要盲目去重装 kernel 模块,那样浪费时间。
还有一个相关的情况是,在 VMware 虚拟机里跑 QEMU,宿主机的虚拟化设置没有开启嵌套虚拟化,报错是“KVM is not supported”。这时候要在 VMware 的虚拟机设置里勾选“虚拟化 Intel VT-x/EPT”选项。如果在 VirtualBox 里,对应选项叫“启用嵌套 VT-x/AMD-V”。这个坑在 2.2 节提醒过,这里再强调一次,容易忘。
6.2 启动黑屏问题:看似 QEMU 的锅,其实是显示模式的锅
有一次我跑一个 ARM 架构的系统镜像,启动命令里面用了默认的图形输出,结果 QEMU 窗口一直黑屏,但虚拟机没有死机,因为宿主机 CPU 占用率说明它一直在运行。
排查链路是这样的。先用 -nographic 参数把输出切到串口终端,看看能不能看到启动日志。对于没有显示输出的系统镜像,这个操作非常有诊断价值。我之前用的是 qemu-system-arm -M vexpress-a9 跑一个精简 Linux,默认图形输出根本没实现 framebuffer 驱动,所以黑屏是必然的,但日志能查出来它到底卡在哪里。
后来我把启动命令改成:
bash复制qemu-system-arm \
-M vexpress-a9 \
-kernel zImage \
-dtb vexpress-v2p-ca9.dtb \
-nographic \
-append "console=ttyAMA0"
这样串口输出直接打印在终端里,系统跑没跑、跑到哪一步,一目了然。处理 QEMU 图形问题的方法总结下来就两条:第一条是确认你模拟的板子是否带图形输出支持;第二条是优先用串口模式排查,确认系统核心部分没问题,再回头处理图形。
6.3 性能感人:同样的镜像,为什么别人跑得飞起
还有一次帮同事排查 QEMU 启动巨慢的问题。他的启动命令里没有加 -enable-kvm,也没有用 -cpu host,结果整个系统像蜗牛一样。QEMU 在没有 KVM 加速的情况下是纯软件模拟,CPU 密集型的任务慢 10 倍以上很正常。
加了 -enable-kvm 之后,性能提升立竿见影。如果 CPU 还是慢,检查一下 -smp 参数是否合理。内存方面,-m 1024 跑桌面版 Ubuntu 确实很勉强,建议至少 2 GB,桌面环境 4 GB 起步。这就是为什么在长期使用场景下,我都会在启动脚本里固定写好 -enable-kvm -cpu host -smp 4 -m 4096,防止下次启动忘了关键参数。
6.4 ARM 模拟的特别注意事项:以 qemu-system-arm 和 m3 场景为例
热门搜索词里有“qemu arm m3”,说明有很多人在用 QEMU 模拟 ARM Cortex-M3 芯片。这个场景和模拟 Linux 系统完全不同,更像是模拟一个单片机。
Cortex-M3 的模拟通常用 QEMU 的 mps2-an385 或 lm3s6965evb 机型号。以 STM32 为例,很多人直接在 Ubuntu 20.04 上用 arm-none-eabi-gcc 交叉编译一个裸机程序,然后丢给 QEMU 跑。启动命令长这样:
bash复制qemu-system-arm \
-M mps2-an385 \
-cpu cortex-m3 \
-nographic \
-kernel firmware.elf
这里要注意一点:-kernel 参数在嵌入式场景下读入的是 ELF 文件,在 Linux 场景下读入的是 zImage 或 bzImage,两种文件格式完全不同,不要拿错。我见过有人拿着 Linux 的 zImage 丢给 mps2-an385,当然什么反应都没有。
另外,Cortex-M3 模拟不涉及操作系统,程序通过串口打印日志。很多开发板的串口输出在 QEMU 里默认不会自动显示在终端上,除非你显式指定 -serial mon:stdio。这个参数的意思是把串口接到当前终端,QEMU 内部调试命令同时也能从键盘输入。如果你在模拟 m3 程序时什么都看不到,先检查是不是漏了这个参数。
从这些坑里可以总结出一个通用排查思路:先确认机器类型(-M)是否匹配,再确认内核或固件格式是否正确,然后用串口模式看输出,最后才考虑图形和性能问题。顺序反过来,容易在表象上浪费大量时间。
7. 把一个基础 QEMU 环境扩展成自己的实验平台
装好、跑通只是一个开始。真正的高频使用场景里,你要根据自己的方向对这套环境做一些定制。这里分享几个我一直在用的扩展思路。
7.1 快照与回滚:实验失败的正确打开方式
做内核实验或者系统配置实验,最怕的就是改错配置导致系统起不来。QEMU 的 qcow2 镜像天然支持快照,用 QEMU monitor 控制台可以随时保存和恢复快照。
在 QEMU 运行界面,按 Ctrl+Alt+2 进入 monitor 控制台,输入:
text复制savevm before_kernel_test
这样就把当前系统状态保存下来。下次想恢复,同样进入 monitor 执行:
text复制loadvm before_kernel_test
或者启动时直接加 -loadvm before_kernel_test。快照保存的是整个虚拟机内存和磁盘状态,恢复起来比冷启动快很多,特别适合反复做压力测试或者内核调试。
7.2 用 QEMU 跑 ROS Noetic 环境
很多同学搜“ubuntu20.04 安装 ros-noetic”,说明这个需求非常集中。ROS Noetic 官方只支持 Ubuntu 20.04,如果你不想把主力电脑降级成 20.04,用 QEMU 虚拟一个 20.04 环境跑 ROS 是最优雅的方案。
虚拟机里安装 ROS 时,注意使用国内镜像源。官方给的国外源在部分网络环境下下载速度很慢,我一般会先切换到清华源。具体操作是在 /etc/apt/sources.list 里换成镜像地址,然后执行:
bash复制sudo apt update
sudo apt install ros-noetic-desktop-full
还要记得初始化 rosdep:
bash复制sudo rosdep init
rosdep update
如果 rosdep update 卡住,多半是网络问题,可以把 rosdistro 的下载地址改成国内镜像。在 QEMU 虚拟机里跑 ROS,性能基本够用。我实际测试过,在普通 x86 笔记本上用 KVM 加速跑 Gazebo 仿真,帧率虽然比物理机低一点,但做初学者学习和跑通示例绰绰有余。
7.3 从 QEMU 到嵌入式开发平台的迁移
如果你最终目标是嵌入式开发,那更应该把 QEMU 当成日常调试工具来用。比如你在开发一个基于 ARM 的 Linux 驱动,QEMU 加 qemu-system-arm 加一个 vexpress 开发板镜像,足够你把驱动逻辑调对,再拿到真实开发板上去验证。
这种工作流的优势很明显:宿主机和客户机之间用 9p 共享目录同步代码,虚拟机里用交叉编译工具链编译,编译产物直接在 QEMU 里运行调试,整个流程不需要碰硬件。等代码逻辑稳定了,再烧写到真实开发板上,省下来的时间非常可观。
7.4 一个建议的目录结构和管理脚本
接触 QEMU 时间久了,你会发现启动参数越来越长,镜像文件越来越多。我建议给每个虚拟机建一个独立目录,目录里至少放三个文件:磁盘镜像、启动脚本、README。比如:
bash复制~/qemu-lab/
├── ubuntu20/
│ ├── ubuntu20.img
│ ├── start.sh
│ └── README.md
└── arm-vexpress/
├── vexpress.img
├── zImage
├── vexpress-v2p-ca9.dtb
└── start.sh
start.sh 里写清楚启动参数,README 里记一下这台机器的用途、账号密码、常用快照名字。别小看这些记录工作,它能在你忙乱的时候救你一命。我一开始觉得记住就行了,后来同时维护三个虚拟机时彻底乱套,才老老实实补上。
回到这套 Ubuntu 20.04 加 QEMU 的方案本身,我最大的体会是:环境问题确实是开发效率的隐形杀手。与其每次遇到问题都去网上搜“怎么装”“怎么配”,不如花一晚上把一套可控的环境搭好,把启动脚本和常见排查思路整理成文档,之后就再也不用为环境发愁了。如果你也正卡在安装或部署的某个环节,希望这篇里面的排查链路和参数解释能帮你跳过一个两个蹲过很久的坑。
