前言最近想系统学习嵌入式 Linux但苦于预算有限买不起开发板二手也很贵/(ㄒoㄒ)/~~于是决定尝试使用 QEMU 作为替代方案。一、QEMU目前中文互联网上适合新手入门的 QEMU 资料较少要么过于简略要么过于深奥。幸运的是作为入门学习阶段实体开发板的替代品只要能顺利启动并使用 QEMU 进行模拟就足够了。在这里只需要知道QEMU的作用就是在你现有的平台上如x86模拟你目标平台如ARM的一个工具和我们使用VMware模拟整个操作系统是类似的原理。二、环境准备1.搭建 Linux 环境对于qemu可以有几种不同的安装使用方式可以在windows或Linux上安装官方程序也可以自己下载源码进行编译。在这我们的学习重点不是qemu所以尽可能简单快速的完成基础环境搭建就可以了。如果你已经在使用 Linux 系统可以跳过此步。 对于 Windows 用户可以通过以下方式获得 Linux 环境VMware Workstation Player(当前有免费版本) 或VirtualBox创建 Ubuntu 虚拟机。WSL2 (Windows Subsystem for Linux 2)微软提供的 Linux 子系统。目前安装非常简便只需在 Microsoft Store 中搜索并安装 “Ubuntu 22.04 LTS” 即可。安装后启动 Ubuntu 并按提示完成初始化设置。如果找不到 WSL 选项可能需要参考官方文档启用 WSL 功能。如果实在不行可能需要自行百度一下或者选用VM。安装好后启动根据提示启动即可未安装WSL会弹窗提示你安装。2.安装 QEMU 及相关工具启动后在命令行中使用apt安装所需工具。# 安装 QEMU 和 ARM 工具链 sudo apt update sudo apt install -y qemu-system-arm gcc-arm-none-eabi gdb-multiarch # 验证 QEMU 版本必须 5.2 qemu-system-arm --version # 可能显示: QEMU emulator version 7.2.0 (Debian 1:7.2dfsg-7ubuntu1)成功后可以进一步确认 QEMU 对目标平台的支持。# 查看 QEMU 支持的 i.MX6ULL 机器类型 qemu-system-arm -M help | grep imx # 输出imx6ul-evk i.MX6UL Evaluation Kit # 查看机器详细信息 qemu-system-arm -machine imx6ul-evk,help # 查看 CPU 信息 qemu-system-arm -cpu cortex-a7,help # 查看内存映射 echo info mtree | qemu-system-arm -machine imx6ul-evk -monitor stdio -nographic如果有需要可以下载对应的资源。# 查看 QEMU 如何定义 i.MX6ULL 的内存布局 # 需要下载 QEMU 源码 git clone https://gitlab.com/qemu-project/qemu.git cd qemu # 查看 i.MX6ULL 的硬件描述 grep -r imx6ul-evk hw/arm/ # 主要文件hw/arm/fsl-imx6ul.c, hw/arm/imx6ul_evk.c # 查看具体内存映射 cat hw/arm/fsl-imx6ul.c | grep -A 20 memory_region_init_ram至此QEMU 环境已准备就绪。2.QEMU 启动流程解析物理芯片启动流程QEMU 模拟流程1上电复位QEMU 进程启动2读取 BOOT 引脚状态创建虚拟 i.MX6ULL 实例3执行内部 BootROM跳过 BootROM执行 (默认行为)4BootROM 读取启动设备初始化内存控制器虚拟5加载 IVT、DCD 等头部将用户提供的 ELF/二进制文件直接加载到指定地址 (如 0x87800000)6配置 DDR、时钟设置程序计数器 (PC) 为加载地址7跳转到应用程序入口开始执行第一条指令通过表格可以看出使用qemu模拟并不是一比一复刻硬件的启动流程虽然 QEMU 默认跳过 BootROM但我们可以模拟不同的启动源内存SD卡SPI Flash等。这里我们采用默认方式从内存加载启动。3.启动 QEMU 进行模拟准备好你的 ARM 程序例如编译链接生成的imx6ull_qemu.elf文件使用以下命令启动 QEMU# 启动 QEMU 模拟器模拟 ARM 平台 qemu-system-arm \ -M mcimx6ul-evk \ # 指定机器类型为 i.MX6UL EVK 开发板 -cpu cortex-a7 \ # 设置 CPU 类型为 ARM Cortex-A7 -nographic \ # 禁用图形输出所有交互通过命令行进行 -serial mon:stdio \ # 将串口重定向到标准输入输出便于调试和控制 -S -s \ # -S: 启动时暂停 CPU等待调试器连接-s: 启用 GDB 调试服务器默认监听端口 1234 -kernel imx6ull_qemu.elf # 加载内核镜像文件 imx6ull_qemu.elf这里加载的imx6ull_qemu.elf文件就是你使用arm-none-eabi-gcc等工具编译、链接你的汇编和 C 代码后生成的可执行文件 (ELF 格式)。qemu内置了GDB服务器方便我们进行程序的调试默认监听的端口时1234。我们可以在运行后新开一个窗口并启动GDB对我们的程序进行调试。# 启动 GDB 并加载你的程序符号 gdb-multiarch imx6ull_qemu.elf # 设置目标架构为 ARM (gdb) set architecture arm # 连接到 QEMU 的 GDB 服务器 (默认端口 1234) (gdb) target remote localhost:1234成功后可以看到此时你可以像调试本地程序一样使用 GDB 命令进行调试。