ARM仿真开发环境——QEMU虚拟化平台搭建

一、QEMU虚拟化平台

1.1 为什推荐QEMU

在嵌入式与操作系统开发领域,ARM 架构凭借其高性能低功耗的显著优势,已成为现代计算设备的核心技术基础——从物联网传感器、智能手机、汽车电子,到数据中心服务器,ARM 无处不在。

然而,许多开发者在学习 ARM 体系与操作系统开发时会遇到很多问题,第一个拦在面前的障碍往往不是代码本身,而是开发环境。翻开任何一本嵌入式书籍,前几章几乎都在教你买板子、接串口、装驱动、配烧录工具。还没碰到一行代码,时间和精力已经耗去大半。

一块主流的ARM开发板,再加上电源、串口线、SD卡、JTAG调试器……整套下来,还没开始学,钱包先瘦了一圈。对于学生和刚入行的工程师来说,这不是一个可以轻松做出的决定。

真实开发板当然有它不可替代的价值,但在源码学习和原理分析这个阶段,它的短板明显:

  • 开发板成本高昂:一块功能完整的 ARM 开发板动辄数百上千元
  • 调试环境复杂:需要配置 JTAG 调试器、串口线、电源等一系列硬件
  • 实验破坏性风险:误操作可能导致硬件损坏,试错成本极高
  • 平台绑定性强,环境难以复现和共享:代码往往与特定开发板深度耦合,难以迁移

QEMU是一个开源的全系统模拟器,它可以模拟完整的ARM处理器以及外设,让代码以为自己运行在一块真实的硬件上。更重要的是,QEMU内置了GDB调试桩——这意味着你可以在U-Boot执行第一条指令之前就断下来,逐条指令单步执行,实时观察每一个寄存器、每一块内存的变化。这种调试深度,即便是价格不菲的JTAG调试器也很难轻松做到。

QEMU几乎完美地解决了上述所有问题:

维度 真实开发板 QEMU
成本 数百至数千元 免费
环境搭建 串口、电源、烧录工具 一条命令启动
编译→运行周期 分钟级 秒级
调试能力 依赖JTAG,门槛高 内置GDB Server,直接单步
环境一致性 因人而异 完全可复现
状态快照 不支持 支持存档/恢复

1.2 为什么选择mcimx6ul-evk

选择mcimx6ul-evk(NXP i.MX6UltraLite EVK)作为QEMU的目标机器,原因有三:

  1. i.MX6UL资料生态好。大量中文教程、开发板、培训课程都基于这颗芯片,社区资料丰富,遇到问题容易找到答案。
  2. QEMU对i.MX6UL的支持相对完善。与 I.MX6ULL Mini 使用相同的 SoC。CPU核心(Cortex-A7)、中断控制器(GIC)、定时器(GPT/EPIT)、UART等关键外设均已建模,足以支撑U-Boot从上电到引导内核的完整流程。
  3. U-Boot主线对i.MX6UL的支持成熟稳定。我们可以直接使用U-Boot官方源码,无需依赖厂商私有的BSP补丁,最大程度保证代码的通用性和可读性。

二、安装QEMU

主机系统:Ubuntu24.04

QEMU版本:QEMU-10.2.1

交叉编译工具链:gcc-arm-none-eabi

调试器(GDB):GDB是一个强大的调试工具,可以与QEMU配合使用

2.1. 使用apt-get命令安装

大多数 Linux 发行版已经为 QEMU(或 KVM)提供了二进制包。Ubuntu可以使用下面命令安装:

sduo apt-get install qemu-system

这种方式安装的QEMU版本一般不是最新的,Ubuntu20.04提供的QEMU版本为4.2.1,Ubuntu24.04提供的QEMU版本为8.2.2。

如果需要更新的版本的话,需要采用下载源码本地编译安装的办法。

2.2 QEMU源码安装

(1)下载源码

QEMU官网下载地址:https://www.qemu.org/download/

qemu所有releases版本下载地址:https://download.qemu.org/

终端使用命令下载:

wget https://download.qemu.org/qemu-10.2.1.tar.xz

解压命令:tar xvJf qemu-9.2.2.tar.xz [-C 指定路径]

git克隆下载QEMU

git clone https://gitlab.com/qemu-project/qemu.git

(2)安装编译依赖
参考文档:https://wiki.qemu.org/Hosts/Linux

必要依赖:

  • git, 版本管理器
  • glib2.0-dev,这会自动包含 zlib1g-dev
  • libfdt-devel
  • Python3 pip、tomli、setuptools 和 wheel
  • Flex(词法分析器生成器) Bison(语法分析器生成器)

对于Ubuntu, 所有必要的额外软件包都可以如下安装:

sudo apt update
sudo apt-get install git build-essential libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build python3-pip python3-setuptools python3-tomli python3-wheel bison flex

推荐额外依赖:

  • git-email,用于发送补丁
  • libsdl2-dev (libsdl2-devel),基于 SDL 的图形用户界面需要
  • libgtk-3-dev (gtk3-devel),用于简单的 UI 而不是 VNC
  • libvte-dev (vte291-devel),用于通过 GTK 接口访问 QEMU 监视器和串行/控制台设备
  • libcapstone-dev (capstone-devel),用于反汇编 CPU 指令

上述列表远非完整。为了最大化代码覆盖,应尽可能启用 QEMU 功能。 运行configure时,你应该会看到很多行是“YES”,只有少数几行是“NO”。

对于Ubuntu, 大多数推荐的额外软件包以实现最大代码覆盖,可以安装如下:

sudo apt-get install git-email
sudo apt-get install libaio-dev libbluetooth-dev libcapstone-dev libbrlapi-dev libbz2-dev
sudo apt-get install libcap-ng-dev libcurl4-gnutls-dev libgtk-3-dev
sudo apt-get install libibverbs-dev libjpeg8-dev libncurses5-dev libnuma-dev
sudo apt-get install librbd-dev librdmacm-dev
sudo apt-get install libsasl2-dev libsdl2-dev libseccomp-dev libsnappy-dev libssh-dev
sudo apt-get install libvde-dev libvdeplug-dev libvte-2.91-dev libxen-dev liblzo2-dev
sudo apt-get install valgrind xfslibs-dev libssl-dev
sudo apt-get install libnfs-dev libiscsi-dev

注意:

qemu9.0之后的版本要求:

glib>=2.66
python>=3.8
Ubuntu20.04在不升级glib和python3的情况下可以安装较新的9.0.x版本
查看glib版本:pkg-config --modversion glib-2.0

(3)编译

1. 进入qemu源码目录
2. mkdir build
3. cd build
4. ../configure --target-list=arm-softmmu
# --target-list=arm-softmmu 表示只编译 ARM 全系统模拟器,跳过大量不需要的目标(如x86_64,aarch64等)
# 不使用 --target-list,会编译安装各种平台的Qemu模拟器(aarch64,riscv64等)
# 不指定 --prefix,一般会安装到 /usr/local
5. make -j$(nproc)

make完成后,如果不想安装,可以在build路径下使用./qemu-system-arm执行qemu。

注意:Ubuntu24.04下,使用默认configure,在make时可能会遇到下面错误:

...
during RTL pass: vartrack
../linux-user/linuxload.c: In function ‘memcpy_to_target’:
../linux-user/linuxload.c:24:1: internal compiler error: Segmentation fault
...
Please submit a full bug report, with preprocessed source (by using -freport-bug).
Please include the complete backtrace with any bug report.
See <file:///usr/share/doc/gcc-13/README.Bugs> for instructions.
ninja: build stopped: subcommand failed.
make: *** [Makefile:170: run-ninja] Error 1

这是 GCC 13 自身崩溃了(Internal Compiler Error,简称 ICE)。Ubuntu 24.04 默认搭载的 gcc-13 在特定优化级别下编译某些代码时会触发这个已知 bug。

解决方法可以是升级GCC到14;或者最省事的方法是指定目标只编译arm,也不会触发编译sh4eb-linux-user目标报错。

(4)安装
make运行结束后使用以下命令安装:
sudo make install

检查qemu版本:
qemu-system-arm --version

查看支持的开发板
qemu-system-arm -M help

2.3 删除QEMU

源码编译安装的qemu需要手动卸载:

可执行文件默认放在/usr/local/bin 
库文件默认存放在/usr/local/libexec
共享文件默认存放在/usr/local/share 
文档在 /usr/local/share/doc/qemu/

卸载源码只需将上面四个目录中相关文件或者目录删除

sudo rm -rf /usr/local/bin/qemu-* 
sudo rm -rf /usr/local/libexec/qemu-bridge-helper 
sudo rm -rf /usr/local/share/qemu
sudo rm -rf /usr/local/share/doc/qemu

三、交叉编译工具安装

在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,我们就称这种编译器支持交叉编译,这个编译过程就称为交叉编译。

简单地说,就是在一个平台上生成另一个平台上的可执行代码。这里需要注意的是所谓平台,实际上包含两个概念:体系结构(Architecture)和操作系统(Operating System)。同一个体系结构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系结构上运行。

要进行交叉编译,我们需要在主机平台上安装对应的交叉编译工具链,然后用这个交叉编译工具链编译我们的源代码,最终生成可在目标平台上运行的代码。例如适用于ARM平台的交叉编译工具链arm-linux-gcc(arm-none-eabi-gcc)。

3.1 apt-get命令安装

使用 Ubuntu 自带的 apt 工具安装 gcc-arm-none-eabi。

sudo apt-get install gcc-arm-none-eabi

安装完成后,输入命令获取版本号。

arm-none-eabi-gcc --version

为什么选 arm-none-eabi 而不是 arm-linux-gnueabihf

  • arm-none-eabi:面向裸机(bare-metal)开发,不依赖任何操作系统的 C 库
  • arm-linux-gnueabihf:面向 Linux 应用开发,依赖 glibc

所以做裸机开发,选择前者。

这种方法安装的工具链不包含arm-none-eabi-gdb调试工具,建议去官网下载手动安装。

3.2 手动下载安装

Arm GNU 工具链下载 – Arm 开发者](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads)
下载之后解压到指定目录:

sudo mkdir /opt/tool
sudo tar -jxf gcc-arm-none-eabi-xxxx-x86_64-linux.tar.bz2 -C /opt/tool/

添加到环境变量:

export PATH=$PATH:/opt/tool/gcc-arm-none-eabi-xxxx/bin

命令 “PATH=$PATH:路径”可以把这个路径加入环境变量,但是退出这个命令行窗口就失效了。

永久有效配置如下:

在/home/用户名下/.bashrc文件末尾中添加下面的内容:
export PATH=$PATH:/opt/tool/gcc-arm-none-eabi-xxxx/bin,然后保存。

最后执行:source .bashrc 使其生效。

输入命令获取版本号:arm-none-eabi-gcc –version,验证安装成功。

3.3 gdb调试工具

我们可以使用工具链自带的gdb来调试代码。

下面推荐一个好用的gdb工具:gdb-multiarch

sudo apt install gdb-multiarch

使用方法:

gdb-multiarch --tui u-boot

(gdb) set architecture arm
(gdb) target remote localhost:1234

至此,开发环境和交叉编译工具链配置等相关准备工作已完成。

使用下面的命令可以在qemu运行我们的裸机程序:

qemu-system-arm -M mcimx6ul-evk -cpu cortex-a7 -m 512M -kernel u-boot

QEMU 帮我们屏蔽了这些硬件初始化的复杂性,让我们可以专注于理解核心概念。等我们对 ARM 体系结构有了足够的理解后,再去攻克这些硬件细节,就会轻松很多。

请作者喝杯茶吧~
微信打赏
微信
支付宝打赏
支付宝