1. 为什么选择QEMU搭建嵌入式开发环境刚接触嵌入式开发的朋友们可能都有这样的困惑动辄上千元的开发板复杂的硬件调试工具还有各种难以复现的环境问题。我在2015年第一次接触STM32开发时就深有体会——一个简单的GPIO控制实验因为硬件接触不良调试了整整两天。直到后来发现了QEMU这个神器才明白原来80%的嵌入式开发调试工作完全可以在虚拟环境中完成。QEMU的全称是Quick Emulator它最大的特点就是能模拟各种CPU架构ARM、MIPS、RISC-V等和硬件设备。我实测下来用QEMU模拟树莓派开发环境从编译到调试的完整流程比真机开发效率至少提升30%。特别是在团队协作时再也不用担心在我机器上能跑的经典问题了——每个人拿到的都是完全一致的虚拟硬件环境。2. 环境准备与QEMU安装2.1 基础环境配置我推荐使用Ubuntu 22.04 LTS版本这个长期支持版对各种开发工具的支持最完善。先更新软件源是个好习惯sudo apt update sudo apt upgrade -y安装编译工具链时ARM架构和x86架构需要的包略有不同。如果是开发ARM嵌入式系统比如树莓派建议安装以下工具链sudo apt install -y gcc-arm-linux-gnueabihf g-arm-linux-gnueabihf2.2 QEMU安装详解官方源里的QEMU版本可能比较旧我更喜欢用更全能的qemu-system包sudo apt install -y qemu-system qemu-utils安装完成后验证下ARM模拟支持是否正常qemu-system-arm --version如果遇到依赖问题特别是32位库兼容性可以试试这个万能修复命令sudo apt --fix-broken install3. 获取和配置系统镜像3.1 官方镜像与自定义编译对于树莓派开发官网提供的raspios镜像可以直接使用wget https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2023-05-03/2023-05-03-raspios-bullseye-armhf-lite.img.xz unxz 2023-05-03-raspios-bullseye-armhf-lite.img.xz但官方镜像可能缺少某些开发工具我更喜欢用Debian官方提供的ARMHF镜像自己定制wget https://cdimage.debian.org/cdimage/archive/11.7.0/armhf/iso-cd/debian-11.7.0-armhf-netinst.iso3.2 镜像扩容技巧默认镜像通常只有2GB左右我用qemu-img工具扩容到8GBqemu-img resize 2023-05-03-raspios-bullseye-armhf-lite.img 6G扩容后还需要在系统内用fdisk调整分区这个步骤比较关键fdisk /dev/mmcblk0 # 删除第二分区后重建 # 注意保持起始扇区不变4. QEMU启动参数详解4.1 基础启动命令这是我调试过最稳定的树莓派模拟命令qemu-system-arm \ -M raspi2b \ -cpu cortex-a7 \ -m 1G \ -kernel kernel-qemu-5.10.63-bullseye \ -dtb versatile-pb-bullseye.dtb \ -sd 2023-05-03-raspios-bullseye-armhf-lite.img \ -append consolettyAMA0 root/dev/mmcblk0p2 rw rootwait \ -serial stdio \ -net nic \ -net user,hostfwdtcp::5022-:22几个关键参数说明-M raspi2b指定树莓派2B型号-sd指定虚拟SD卡镜像hostfwd将虚拟机的22端口映射到主机的5022端口4.2 网络配置进阶要实现完整的网络功能需要配置TAP设备sudo ip tuntap add dev tap0 mode tap sudo ip link set tap0 up sudo ip addr add 192.168.100.1/24 dev tap0然后在QEMU启动参数中加入-net nic -net tap,ifnametap0,scriptno5. 开发环境实战技巧5.1 交叉编译配置在主机上编译ARM程序时需要指定正确的工具链export CCarm-linux-gnueabihf-gcc export CXXarm-linux-gnueabihf-gCMake配置示例set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)5.2 内核调试技巧要调试Linux内核需要带调试信息的版本qemu-system-arm -kernel zImage -append kgdbocttyAMA0,115200 -serial tcp::1234,server然后在主机上用gdb-multiarch连接gdb-multiarch vmlinux target remote :12346. 常见问题排查6.1 启动卡住问题如果系统启动卡在Booting Linux...通常是内核参数不匹配检查-append中的root参数是否正确指向根分区确认dtb文件与内核版本匹配尝试添加earlyprintk参数查看早期日志6.2 网络连接失败网络不通时建议分步检查确认虚拟机内网卡是否识别ip link show测试DHCP是否工作dhclient eth0检查主机iptables规则是否拦截我在实际项目中遇到最棘手的问题是USB设备穿透后来发现需要添加以下参数-device usb-host,vendorid0x1234,productid0x56787. 性能优化建议经过多次测试这些配置能显著提升QEMU性能启用KVM加速x86主机-enable-kvm -cpu host使用virtio设备-drive filedisk.img,ifvirtio -net nic,modelvirtio调整内存分配策略-mem-prealloc -mem-path /dev/hugepages对于嵌入式开发我建议将常用命令写成脚本。比如这是我的start_qemu.sh#!/bin/bash qemu-system-arm \ -M virt \ -cpu cortex-a15 \ -m 1024 \ -kernel zImage \ -dtb virt.dtb \ -drive filerootfs.ext4,ifvirtio,formatraw \ -append root/dev/vda rw consolettyAMA0 \ -nographic \ -net nic,modelvirtio \ -net user,hostfwdtcp::2222-:22记得给脚本执行权限chmod x start_qemu.sh