概述
本指南用于建立一套轻量、清晰、适合课堂展示的嵌入式 Linux 教学环境。其核心原则是把“开发主机(HOST)”与“目标系统(TARGET)”分离:A 窗口采用独立的 Ubuntu 18.04 LTS 虚拟机进行源码编辑、交叉编译与构建;B 窗口采用 Windows 原生 QEMU 11.1.0 模拟 ARM VExpress-A9 开发板,负责 U-Boot、Linux、串口、网络等目标端实验。
本指南以已经验证成功的实际部署结果为基线:Ubuntu 18.04 能正常运行 Arm GNU Toolchain 12.3.Rel1,U-Boot 2026.07 可成功编译并在 Windows QEMU VExpress-A9 上启动。
说明:Ubuntu 18.04 已属于较老发行版。本方案的使用定位是“固定、轻量的教学 HOST”,不建议把它作为对公网开放的服务器或日常互联网工作站。关键交叉工具链采用 Arm 官方独立工具链,以避免受 18.04 软件仓库中旧版 GCC 的限制。
一、系统总体架构
建议课堂中统一使用以下术语:
- 窗口 A / HOST:Ubuntu 18.04 LTS 虚拟机。负责源代码、Make 构建、交叉编译、生成镜像。
- 窗口 B / TARGET:Windows + QEMU 11.1.0。模拟 VExpress-A9 / Cortex-A9 开发板,运行 U-Boot 和 Linux。
- 部署(Deploy):把 HOST 产生的 u-boot、zImage、DTB、rootfs 等文件送到 Windows 目标目录,再由 QEMU 加载。
二、推荐软件版本与目录规范
| 组件 | 推荐版本 | 安装位置 | 作用 |
|---|---|---|---|
| Ubuntu | 18.04 LTS x86_64 | 虚拟机 | HOST 开发主机 |
| Arm GNU Toolchain | 12.3.Rel1 | /opt/arm/gcc-12.3-arm32 | ARM32 GNU/Linux 交叉编译 |
| U-Boot | 2026.07 | ~/EmbeddedLinuxLab/src/u-boot-2026.07 | Bootloader 实验 |
| Code::Blocks | 16.01 | Ubuntu 软件仓库 | C/C++ 教学、源码浏览和小程序编译 |
| QEMU for Windows | 11.1.0 | C:\Program Files\qemu | TARGET / VExpress-A9 仿真 |
2.1 HOST 目录
~/EmbeddedLinuxLab/ ├── src/ # U-Boot、Linux、Buildroot 等源码 ├── build/ # 构建输出或临时目录 ├── tools/ # 可选:自定义工具 └── env-arm32.sh # ARM32 交叉编译环境脚本2.2 TARGET 目录
E:\EmbeddedLinuxLab\ ├── images\ # u-boot / zImage / dtb / rootfs ├── scripts\ # QEMU 启动脚本 └── logs\ # 启动与串口日志三、Ubuntu 18.04 HOST 基础准备
进入 Ubuntu 18.04 后,先确认系统与架构:
lsb_release-auname-m应确认系统为 Ubuntu 18.04.x LTS,主机架构为 x86_64。随后建立实验目录:
cd~mkdir-p~/EmbeddedLinuxLab/{src,build,tools}更新软件索引并安装 U-Boot / Kernel 常用依赖:
sudoaptupdatesudoaptinstall-y\build-essentialgitmakewgetcurlbcbison flex pkg-config\libssl-dev libncurses5-dev libelf-dev python3 python3-dev\python3-setuptools python3-pyelftools swig device-tree-compiler xz-utils说明:不要在 Ubuntu 18.04 中尝试通过 apt 安装 gcc-12-arm-linux-gnueabihf。18.04 的官方仓库没有该软件包。本方案采用 Arm 官方独立工具链。
四、安装 Arm GNU Toolchain 12.3.Rel1
需要的工具链文件名:
arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz其含义:Linux x86_64 HOST → AArch32 GNU/Linux hard-float TARGET。编译器前缀为:
arm-none-linux-gnueabihf-官方入口:Arm GNU Toolchain Downloads。浏览器下载速度若明显高于 wget,可直接通过浏览器下载,然后在 Ubuntu 中从“下载”目录安装。
4.1 解压到 /opt/arm
cd~/下载# 中文桌面常见目录;若为英文系统请使用 ~/Downloadssudomkdir-p/opt/armsudotar-xJfarm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz\-C/opt/arm建立固定的短路径软链接:
sudoln-sfn\/opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf\/opt/arm/gcc-12.3-arm324.2 验证工具链本体
/opt/arm/gcc-12.3-arm32/bin/arm-none-linux-gnueabihf-gcc--version/opt/arm/gcc-12.3-arm32/bin/arm-none-linux-gnueabihf-readelf--version已经验证成功的典型输出为:
arm-none-linux-gnueabihf-gcc ... 12.3.1 20230626 GNU readelf ... 2.40.0.20230627五、建立 ARM32 交叉编译环境脚本
不建议把 ARCH 和 CROSS_COMPILE 永久写死在 ~/.bashrc 中,因为后续还可能进行 ARM64、RISC-V 或本机 x86 实验。建议使用可按需加载的环境脚本。
nano~/EmbeddedLinuxLab/env-arm32.sh写入:
#!/bin/bashexportARCH=armexportARM_GCC_HOME=/opt/arm/gcc-12.3-arm32exportPATH=${ARM_GCC_HOME}/bin:${PATH}exportCROSS_COMPILE=arm-none-linux-gnueabihf-echo"=========================================="echo" ARM32 Cross Compile Environment"echo" ARCH =${ARCH}"echo" CROSS_COMPILE =${CROSS_COMPILE}"echo" GCC HOME =${ARM_GCC_HOME}"echo"=========================================="赋予执行权限并加载:
chmod+x ~/EmbeddedLinuxLab/env-arm32.shsource~/EmbeddedLinuxLab/env-arm32.sh验证:
whicharm-none-linux-gnueabihf-gcc arm-none-linux-gnueabihf-gcc--versionecho$ARCHecho$CROSS_COMPILE预期路径:
/opt/arm/gcc-12.3-arm32/bin/arm-none-linux-gnueabihf-gcc六、编译 U-Boot 2026.07
假定源码目录已经准备为:
~/EmbeddedLinuxLab/src/u-boot-2026.07每次开始 ARM32 构建前先加载环境:
source~/EmbeddedLinuxLab/env-arm32.shcd~/EmbeddedLinuxLab/src/u-boot-2026.076.1 清理旧构建结果
makedistclean6.2 生成 VExpress-A9 配置
makevexpress_ca9x4_defconfig检查目标配置:
grepCONFIG_TARGET_VEXPRESS .config应出现:
CONFIG_TARGET_VEXPRESS_CA9X4=y6.3 正式编译
make-j$(nproc)编译完成后验证:
ls-lhu-boot u-boot.binfileu-boot arm-none-linux-gnueabihf-readelf-hu-boot|grepMachine关键判据:file 输出应包含 “ELF 32-bit … ARM”,readelf 应显示 “Machine: ARM”。
七、部署 U-Boot 到 Windows QEMU TARGET
如果采用虚拟机共享目录、SMB、SCP 或手工复制,都可以完成部署。最终目标是把 u-boot 放入:
E:\EmbeddedLinuxLab\images\u-boot在 Windows B 窗口中进入:
E: cd \EmbeddedLinuxLab\images启动 VExpress-A9:
"C:\Program Files\qemu\qemu-system-arm.exe" ^ -machine vexpress-a9 ^ -m 512M ^ -nographic ^ -no-reboot ^ -kernel u-boot成功时应看到类似:
U-Boot 2026.07 (...) DRAM: 512 MiB Flash: 128 MiB MMC: mmci@5000: 0 In: uart@9000 Out: uart@9000 Err: uart@9000 Net: eth0: ethernet@3,02000000 =>说明:“*** Warning - bad CRC, using default environment”在当前阶段不表示 U-Boot 损坏,只表示虚拟 Flash 中尚未保存有效的持久化环境变量。若未及时中断 autoboot,后续出现 MMC、TFTP、PXE、bootm 等失败信息,也只是因为 Kernel/SD/TFTP 尚未配置;只要最终返回 “=>” 即说明 U-Boot 正常工作。
八、安装与配置 Code::Blocks 16.01
Code::Blocks 的角色定位:用于 C/C++ 教学、源码浏览、小型 ARM 应用程序交叉编译;U-Boot、Linux Kernel、Buildroot 仍使用各自原生 Make/Kbuild 构建系统。
sudoadd-apt-repository universesudoaptupdatesudoaptinstall-ycodeblocks codeblocks-contrib8.1 保留默认本机编译器
默认 “GNU GCC Compiler” 保持 /usr/bin/gcc,用于生成 Ubuntu x86_64 本机程序。
8.2 新建 ARM GCC 12.3 编译器配置
打开 Settings → Compiler…,在 Selected compiler 中选 GNU GCC Compiler,点击 Copy。新名称设为 “ARM GCC 12.3 - Cortex-A9”。进入 Toolchain executables,将 Compiler’s installation directory 设置为 /opt/arm/gcc-12.3-arm32。
| 项目 | 填写内容 |
|---|---|
| C compiler | arm-none-linux-gnueabihf-gcc |
| C++ compiler | arm-none-linux-gnueabihf-g++ |
| Linker for dynamic libs | arm-none-linux-gnueabihf-g++ |
| Linker for static libs | arm-none-linux-gnueabihf-ar |
| Make program | make |
| Resource compiler | 留空 |
| Debugger | 先保持 GDB/CDB debugger : Default |
说明:Code::Blocks 16.01 的 Debugger 栏是下拉选择框,不能直接输入 arm-none-linux-gnueabihf-gdb。当前只做编译时保持 Default 即可;真正的 ARM 调试应以后通过 Settings → Debugger 建立独立 GDB 配置,并结合 QEMU GDB Remote 使用。
九、建议的基础验证实验:本机编译与交叉编译对比
可用同一份 hello.c 分别生成 x86_64 和 ARM 可执行文件,以直观讲清“本机编译”和“交叉编译”的区别。
#include<stdio.h>intmain(void){printf("Hello Embedded Linux!\n");return0;}gcc hello.c-ohello_x86 arm-none-linux-gnueabihf-gcc hello.c-ohello_armfilehello_x86filehello_arm预期:hello_x86 为 x86-64 ELF;hello_arm 为 ARM 32-bit ELF。ARM 程序不能直接在 x86_64 Ubuntu 上运行,应在 ARM TARGET(例如 QEMU Linux)中执行。
十、常见问题与排查
| 现象 | 原因 | 处理方法 |
|---|---|---|
| apt 找不到 gcc-12-arm-linux-gnueabihf | Ubuntu 18.04 仓库没有该包 | 不要混装新发行版 .deb;使用 /opt/arm 下的独立 Arm GNU Toolchain |
| arm-none-linux-gnueabihf-gcc: command not found | PATH 或环境脚本未加载 | source ~/EmbeddedLinuxLab/env-arm32.sh;再用 which 检查路径 |
| U-Boot 编译结果不是 ARM | 误用了 HOST gcc | 检查 CROSS_COMPILE 和 which arm-none-linux-gnueabihf-gcc |
| Code::Blocks 看不到 ARM GCC | IDE 不会自动扫描 /opt 下工具链 | 复制 GNU GCC 编译器配置,并手工填写 Toolchain executables |
| Debugger 无法输入路径 | 16.01 版本此处是下拉配置项 | 先保留 Default;需要调试时到 Settings → Debugger 单独配置 |
| QEMU 出现 bad CRC | 未初始化 U-Boot 持久化环境 | 当前阶段可忽略,使用默认 environment |
| QEMU 自动启动后出现 MMC/TFTP/bootm 错误 | 尚未配置 SD、Kernel 或 TFTP | 在 Hit any key 阶段按键进入 =>;后续实验逐项配置 |
十一、实验室批量部署建议
- 制作一台配置好的 Ubuntu 18.04 HOST 母机:安装基础依赖、Arm GNU Toolchain 12.3.Rel1、Code::Blocks 16.01、env-arm32.sh。
- 在虚拟机关闭状态下复制完整虚拟机目录作为教学模板;学生首次启动后再修改主机名与用户名。
- 不要把大量 Kernel/Buildroot 编译中间产物预置进母机,以免虚拟磁盘膨胀。
- Windows 宿主机统一安装 QEMU 11.1.0,并统一建立 E:\EmbeddedLinuxLab\images、scripts、logs 目录。
- 课堂上固定叫法:左侧 HOST / 开发主机,右侧 TARGET / 虚拟开发板;教师给出的命令必须明确标注在哪个窗口执行。
- 如需要联网,只开放必要的 NAT/桥接/Host-only 网络;Ubuntu 18.04 不作为公网服务器使用。
十二、最终验收清单
| 验收项 | 状态 |
|---|---|
| Ubuntu 18.04 LTS 启动正常,uname -m = x86_64 | □ |
| /opt/arm/gcc-12.3-arm32 存在 | □ |
| arm-none-linux-gnueabihf-gcc --version 显示 12.3.1 | □ |
| env-arm32.sh 可正常 source | □ |
| U-Boot 2026.07 可完成 vexpress_ca9x4_defconfig + make | □ |
| file u-boot 显示 ARM 32-bit ELF | □ |
| Windows QEMU vexpress-a9 可启动 u-boot 并进入 => | □ |
| Code::Blocks 16.01 已建立 ARM GCC 12.3 - Cortex-A9 配置 | □ |
| 默认 GNU GCC 与 ARM GCC 两套配置明确区分 | □ |
附录 A:常用命令速查
# 进入 ARM32 环境source~/EmbeddedLinuxLab/env-arm32.sh# 验证工具链whicharm-none-linux-gnueabihf-gcc arm-none-linux-gnueabihf-gcc--version# 编译 U-Bootcd~/EmbeddedLinuxLab/src/u-boot-2026.07makedistcleanmakevexpress_ca9x4_defconfigmake-j$(nproc)# 验证输出fileu-boot arm-none-linux-gnueabihf-readelf-hu-boot|grepMachine附录 B:Windows QEMU 启动命令
"C:\Program Files\qemu\qemu-system-arm.exe" ^ -machine vexpress-a9 ^ -m 512M ^ -nographic ^ -no-reboot ^ -kernel E:\EmbeddedLinuxLab\images\u-boot实验基线:Ubuntu 18.04 LTS + Arm GNU Toolchain 12.3.Rel1 + Code::Blocks 16.01 + Windows QEMU 11.1