☰
没有开发板也能跑 ARM64 Linux:Ubuntu + QEMU + Buildroot 实战
2026/10/13 10:37:37 网站建设 项目流程

没有开发板也能学嵌入式 Linux:Ubuntu 20.04 + QEMU + Buildroot 跑通 ARM64

想学嵌入式 Linux,不一定要先买开发板。使用 QEMU 的virt虚拟平台和 Buildroot,可以在 x86_64 Ubuntu 主机上构建并启动一套 ARM64 Linux 系统。

验证链路:Ubuntu x86_64 主机 → QEMU 全系统模拟 → Buildroot 构建 Linux 和 rootfs → 登录 ARM64 shell → 交叉编译并运行测试程序。

本文没有使用实体开发板。文中的运行验证仅针对 QEMU 模拟环境,不代表真实板卡的 U-Boot、设备树、驱动或外设已经验证。

⚠️ Ubuntu 20.04 LTS 的标准维护已于 2025 年结束。本文以现有环境兼容为目的;继续联网使用时,请确认软件源和安全维护方案。

📅 本文实验记录于 2026 年 10 月,文中命令输出中的时间戳与版本号为当时实际运行结果,请以你所选 Buildroot 版本的输出为准。新项目建议评估仍处于标准维护期的 Ubuntu 版本。

一、目标效果

完成后,QEMU 终端中应能看到类似登录提示:

Welcome to Buildroot buildroot login: root # uname -m aarch64

Buildroot 默认通常允许 root 登录且不设置密码;如果提示输入密码,可直接回车。实际提示以所选 Buildroot 配置为准。


图注:QEMU 中的 Buildroot Linux 启动并登录成功,系统架构为 AArch64。

画面中的Welcome to Buildroot表示系统已进入登录阶段,使用root登录后出现的#是 root shell 提示符。执行uname -m得到aarch64,说明当前操作的是 QEMU 中的 ARM64 系统,而不是外层 x86_64 Ubuntu 主机。此结果验证了模拟系统的启动与登录,测试程序的交叉编译和运行将在后续步骤验证。

二、实验环境

项目要求或示例
宿主机Ubuntu 20.04 x86_64
系统 QEMU4.2.1,Ubuntu 软件包安装版本
权限可使用sudo安装依赖
内存建议至少 4 GB
磁盘构建目录建议预留至少 30 GB 可用空间;使用虚拟机时,虚拟硬盘建议 60 GB 起步
网络首次构建需要下载 Buildroot 及其源码包

确认宿主机架构:

uname-m

输出:

x86_64

三、安装依赖

更新软件包索引并安装 QEMU 与 Buildroot 构建依赖:

sudoaptupdatesudoaptinstall-y\qemu-system-arm\build-essentialmakegcc g++\bcbison flex\libncurses-dev libssl-dev libelf-dev\cpiounziprsyncfilewgetcurlgit\python3

Ubuntu 的qemu-system-arm软件包提供 ARM/AArch64 system emulator。检查 QEMU:

qemu-system-aarch64--version

Buildroot 会为所选目标构建交叉编译工具链,因此后续编译测试程序时优先使用 Buildroot 生成的编译器。这样可以让程序的 C 库和 ABI 与 Buildroot rootfs 保持一致。

embed@embedtest:~$ qemu-system-aarch64 --version QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.30)Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers

上述输出记录的是 Ubuntu 系统安装的 QEMU 4.2.1,本文手动启动命令明确使用/usr/bin/qemu-system-aarch64。Buildroot 也可能构建自己的主机侧 QEMU;该程序与系统 QEMU 是两份独立的安装,不能仅凭系统版本输出确定启动脚本实际使用的版本。

四、下载并解压 Buildroot

本文固定使用 Buildroot2025.02.8作为示例,便于复现;其他版本的配置菜单和内核版本可能不同。也可从 Buildroot 官方下载页 选择仍受支持的稳定版,并相应替换文件名。

cd"$HOME"wgethttps://buildroot.org/downloads/buildroot-2025.02.8.tar.gztarxf buildroot-2025.02.8.tar.gzcdbuildroot-2025.02.8

本文实际源码目录为~/buildroot-2025.02.8,后续相对路径命令均在此目录执行。

Buildroot 2025.02.8 解压后的源码目录。可以看到 configs、package、toolchain 和 Makefile 等内容,后续配置与编译均在此目录执行。

embed@embedtest:~/buildroot-2025.02.8$ ls arch board boot CHANGES Config.in Config.in.legacy configs COPYING DEVELOPERS docs fs linux Makefile Makefile.legacy package README support system toolchain utils

五、选择 QEMU ARM64 virt 配置

Buildroot 为 QEMU 通用virt平台提供了预设配置:

makeqemu_aarch64_virt_defconfig

该配置会为 ARM64 QEMU virt 平台选择内核、rootfs 和相应启动设置。Buildroot 不同版本的默认文件系统格式或生成文件可能略有差异;后续命令以实际output/images/内容为准。

省略配置工具的构建输出,关键结果如下:

embed@embedtest:~/buildroot-2025.02.8$ make qemu_aarch64_virt_defconfig # # configuration written to /home/embed/buildroot-2025.02.8/.config #

上述提示说明预设配置已成功写入.config,并不代表内核和根文件系统已经编译完成。接下来再执行系统编译。

六、编译系统

首次构建会下载并编译大量源码包,耗时取决于网络、CPU 和磁盘性能:

make-j"$(nproc)"

如果内存不足或系统开始大量使用 swap,降低并行度,例如:

make-j2

成功后查看生成物:

ls-lhoutput/images/

本次构建生成的文件如下:

embed@embedtest:~/buildroot-2025.02.8$ ls -lh output/images/ total 21M -rw-r--r-- 1 embed embed 12M Oct 12 06:25 Image -rw-r--r-- 1 embed embed 60M Oct 12 06:25 rootfs.ext2 lrwxrwxrwx 1 embed embed 11 Oct 12 06:25 rootfs.ext4 -> rootfs.ext2 -rwxr-xr-x 1 embed embed 832 Oct 12 06:25 start-qemu.sh

这些文件各有用途:

文件作用
ImageARM64 Linux 内核,启动后负责管理 QEMU 模拟的硬件
rootfs.ext2根文件系统镜像,包含 shell、基本命令、运行库和系统配置
rootfs.ext4指向rootfs.ext2的符号链接,与它使用同一份镜像,不是另一份磁盘文件,无需手动复制
start-qemu.shBuildroot 生成的启动脚本,负责将内核和根文件系统交给 QEMU 启动

rootfs.ext2的文件名并不能单独确定内部文件系统格式,可用file output/images/rootfs.ext2检查。这里的rootfs.ext4链接是 Buildroot 生成的,不是通过改名转换文件系统。

输出中的total 21M表示这些文件实际占用的磁盘块总量,而60M是 rootfs 镜像的逻辑大小。稀疏镜像中未分配的区域不占用相应磁盘块,因此两者可能不同。

看到这些文件说明关键构建产物已生成;还需确认make正常结束、没有错误,并完成下一节的启动和登录验证,才能确认系统可运行。

七、启动 ARM64 Linux

方式一:使用 Buildroot 启动脚本

先查看脚本中调用的 QEMU 路径。如果使用output/host/bin/下的程序,应另行记录其版本,不要将前面的系统 QEMU 4.2.1 作为脚本运行版本:

catoutput/images/start-qemu.sh

确认后启动:

./output/images/start-qemu.sh

脚本会使用与该 defconfig 对应的 QEMU 参数和镜像。等待内核启动完成,在提示符处输入root登录;如出现密码提示,按当前 Buildroot 配置输入,默认无密码时直接回车。出现#提示符即表示已进入 Buildroot shell,启动和登录效果见文章开头的“目标效果”部分。

方式二:手动启动 QEMU

如果输出目录里有Image和rootfs.ext2,可以参考下面的命令手动启动:

/usr/bin/qemu-system-aarch64\-Mvirt\-cpucortex-a53\-smp2\-m1G\-nographic\-kerneloutput/images/Image\-append"rootwait root=/dev/vda console=ttyAMA0"\-drivefile=output/images/rootfs.ext2,if=none,format=raw,id=hd0\-devicevirtio-blk-device,drive=hd0

此命令假定内核和 rootfs 的文件名、块设备驱动及串口配置与当前 Buildroot 配置一致。如果手动启动失败,先使用 Buildroot 生成的start-qemu.sh;脚本通常包含该预设所需的完整参数。不要将示例文件名或参数当作所有版本的固定接口。

手动命令启动成功后,登录界面与文章开头的“目标效果”一致,此处不再重复放图。请实际执行手动命令,确认能够登录并运行uname -m,输出应为aarch64;启动脚本运行成功不等于手动命令也已验证通过。

八、理解常见 QEMU 参数

参数含义
-M virt使用 QEMU ARM 通用虚拟平台,不对应某一块真实开发板
-cpu cortex-a53模拟 Cortex-A53 CPU 型号
-smp 2提供 2 个虚拟 CPU
-m 1G分配 1 GB 内存
-nographic不创建图形窗口,将串口控制台连接到当前终端
-kernel指定内核镜像
-append设置传给内核的启动参数
rootwait等待根设备就绪后再挂载
root=/dev/vda指定 virtio 块设备上的根文件系统
console=ttyAMA0将控制台输出到 ARM PL011 串口
-drive定义虚拟磁盘镜像
-device virtio-blk-device将磁盘连接到 virtio 总线

九、在模拟系统中检查环境

登录 QEMU 中的 Buildroot 后执行:

uname-auname-m

uname -m应显示aarch64。内核版本取决于 Buildroot 配置,不要把示例中的版本号当作固定值。

本次运行输出如下:

# uname -a Linux buildroot 6.12.27 #1 SMP Mon Oct 12 06:24:57 UTC 2026 aarch64 GNU/Linux # uname -m aarch64

检查 CPU、内存和根目录:

cat/proc/cpuinfofree-hls/

QEMU 显示的是模拟硬件信息;这只能确认当前虚拟机配置,不代表真实开发板的 CPU、内存或外设情况。

# cat /proc/cpuinfo processor : 0 BogoMIPS : 125.00 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 1 BogoMIPS : 125.00 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 # free -h total used free shared buff/cache available Mem: 990.9M 16.6M 970.6M 44.0K 3.7M 939.4M Swap: 0 0 0 # ls / bin lib media root tmp crond.reboot lib64 mnt run usr dev linuxrc opt sbin var etc lost+found proc sys

十、交叉编译并运行测试程序

1. 在宿主机编写程序

退出或暂时挂起 QEMU 会话后,在 Buildroot 源码目录所在的宿主机终端创建测试程序:

cd"$HOME/buildroot-2025.02.8"cat>hello.c<<'EOF' #include <stdio.h> int main(void) { puts("Hello from ARM64 Linux on QEMU!"); return 0; } EOF

2. 使用 Buildroot 生成的交叉编译器

Buildroot 交叉编译器位于output/host/bin/。先查找实际编译器名称:

findoutput/host/bin-maxdepth1-name'aarch64-buildroot-linux-*-gcc'-print

自动找到 Buildroot 生成的交叉编译器并编译。使用 Buildroot 自己的工具链能避免 Ubuntu 系统交叉工具链与 rootfs 的 libc 或 ABI 不匹配:

CROSS_GCC=$(findoutput/host/bin-maxdepth1-name'aarch64-buildroot-linux-*-gcc'-print-quit)test-n"$CROSS_GCC"||{echo"Buildroot AArch64 compiler not found";exit1;}"$CROSS_GCC"hello.c-ohellofilehello

file应显示 64 位 ARM AArch64 ELF。不要直接用 Ubuntu 的aarch64-linux-gnu-gcc编译后就假定它能在 Buildroot rootfs 运行;不同工具链的动态加载器和 C 库可能不兼容。

embed@embedtest:~/buildroot-2025.02.8$ file hello hello: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 6.12.0, not stripped

输出中的ARM aarch64确认了目标架构,动态加载器为/lib/ld-linux-aarch64.so.1。shared object可能是当前file版本对 PIE(位置无关可执行文件)的识别结果,不一定表示生成了共享库;能否正常运行仍需在 QEMU 中验证。

3. 将程序放入 rootfs 镜像

挂载并修改镜像前,必须先关闭使用同一 rootfs 镜像的 QEMU。可在 Buildroot 中执行poweroff,若 QEMU 未自动退出,再按Ctrl+A,松开后按X。仅暂停 QEMU 不够;不要让 QEMU 和宿主机同时写入镜像,以免损坏文件系统。

先确认 rootfs 镜像格式:

ls-lhoutput/images/rootfs.*fileoutput/images/rootfs.*

若生成的是rootfs.ext2,可在宿主机临时挂载镜像并复制程序:

sudomkdir-p/mnt/buildroot-rootfssudomount-oloop,rw output/images/rootfs.ext2 /mnt/buildroot-rootfssudoinstall-m0755 hello /mnt/buildroot-rootfs/root/hellosudoumount/mnt/buildroot-rootfs

这里只修改生成的 rootfs 镜像,不要把文件复制到output/target后就认为已有镜像会自动更新。若使用其他文件系统格式,请按相应工具和格式处理。

4. 在 QEMU 中运行

重新启动 QEMU:

./output/images/start-qemu.sh

登录后运行:

/root/hello

本次运行输出:

Hello from ARM64 Linux on QEMU!

这验证了 Buildroot 工具链、该 Buildroot rootfs 和当前 QEMU 虚拟平台组成的交叉编译运行闭环;仍不等于在实体开发板上验证通过。

图注:交叉编译的 hello 程序在 QEMU ARM64 Linux 中运行成功。

十一、退出 QEMU

优先在 QEMU 的 Buildroot shell 中执行正常关机,让系统完成文件写入并卸载文件系统:

poweroff

若关机完成后 QEMU 没有自动退出,使用-nographic启动时可按Ctrl+A,松开后按X,返回 Ubuntu 终端。该快捷键直接退出 QEMU,不应作为正常关机的替代,以免正在写入的文件丢失或损坏。

如果快捷键被终端拦截,先查看当前 QEMU 的控制台设置或使用start-qemu.sh对应的退出方式;不要直接关闭宿主机。

十二、常见问题

1. qemu-system-aarch64: command not found

确认安装了 Ubuntu 的 ARM system emulator 包:

sudoaptinstallqemu-system-arm

2. 启动后停在 Booting the kernel.

先用 Buildroot 生成的start-qemu.sh启动,并确认内核串口控制台配置与 QEMU 的console=ttyAMA0一致。手动命令中的内核文件、机器类型或启动参数与当前配置不匹配,也可能导致没有控制台输出。

3. Kernel panic,无法挂载 rootfs

检查以下内容是否彼此匹配:

  • QEMU 的磁盘镜像路径和实际文件名
  • 内核是否包含 virtio 块设备及所用文件系统驱动
  • root=/dev/vda是否与磁盘设备类型相符
  • Buildroot 生成的启动脚本使用了哪些实际参数

4. 交叉编译程序启动失败

常见原因是使用的宿主机交叉编译器与 Buildroot rootfs 使用了不同 libc、动态加载器或 ABI。优先使用output/host/bin/下 Buildroot 生成的交叉编译器重新编译。

5. 运行 /root/hello 提示 not found

本次曾出现如下错误:

# /root/hello -sh: /root/hello: not found

先在 QEMU 的 Buildroot shell 中检查程序和它请求的动态加载器:

ls-l/root/hellols-l/lib/ld-linux-aarch64.so.1

本次检查结果是/root/hello不存在,而动态加载器存在。因此直接的问题是程序没有出现在当前启动的 rootfs 中,并非已证明交叉编译器或运行库不兼容。

关闭 QEMU 后,回到 Ubuntu 的 Buildroot 源码目录,按第十节重新挂载实际使用的 rootfs 镜像;确认挂载成功,再复制hello,用sudo ls -l /mnt/buildroot-rootfs/root/hello检查文件是否存在。卸载成功后,使用同一份镜像重新启动 QEMU。不要在 QEMU 运行时修改镜像,也不要在手动复制后立即运行make,以免重新生成 rootfs 覆盖文件。

如果程序存在但动态加载器缺失,shell 也可能报告not found。此时应根据程序实际请求的加载器路径检查工具链与 rootfs 是否匹配;不要随意复制宿主机的 x86_64 库或关闭校验来解决。

6. Buildroot 报 Python 版本或依赖错误

核对所用 Buildroot 版本的宿主机依赖说明,并安装缺少的依赖。Ubuntu 20.04 的系统 Python 版本通常可满足本文固定的 Buildroot 版本;若实际检查不满足要求,应使用独立安装的 Python 环境或选择兼容的 Buildroot 版本,不要替换系统 Python,以免影响系统工具。

十三、这次实验验证了什么

项目本文验证范围
QEMU ARM64 全系统模拟在 x86_64 Ubuntu 上启动 QEMU virt
Buildroot构建 ARM64 Linux 内核和 rootfs
交叉编译使用 Buildroot 工具链生成 ARM64 程序
运行程序在对应 Buildroot rootfs 的 QEMU 系统中执行程序
实体板启动未验证;需要真实开发板、对应 U-Boot、设备树、内核配置及硬件测试

十四、总结与后续

没有开发板也可以先熟悉交叉编译、Linux 启动和 rootfs 的基本关系。QEMUvirt是通用模拟平台,不是具体产品板卡;模拟器中运行正常,不能证明某块板子的 U-Boot、设备树、驱动、网络 PHY 或外设都能工作。

程序已经跑起来了,但如果结果不对,该怎么知道它在哪一步出了问题?没有开发板,也能继续练习嵌入式开发中常用的断点、单步和变量检查。

下一篇预告:《没有开发板也能调试 ARM64 程序:QEMU + GDB 远程调试实战》

下一篇计划为 Buildroot 添加gdbserver,建立 Ubuntu 与 QEMU 中 ARM64 Linux 的调试连接,再用一个小程序练习设置断点、单步执行、查看变量和调用栈。

从“程序能运行”到“知道程序为什么这样运行”,我们继续在 QEMU 中把这个过程走一遍。关注这个系列,后续还会实践 QEMU 网络配置和 Buildroot rootfs 定制,不用等开发板到手再开始。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询