副标题:一个新手如何在 48 小时内亲手构建并登录自己的 ARM Linux 系统


《Buildroot + QEMU (ARM VersatilePB) 填坑实录》


🎯 项目目标(初心)

用VM+Ubuntu 18.04.6:

  • 使用 Buildroot 构建一个最小 ARM Linux 系统
  • 在 QEMU 模拟器中运行它
  • 实现 网络通信 和 SSH 远程登录
  • 全程不依赖预编译镜像,一切从源码构建

🧱 起点:一无所知的新手状态

  • 不清楚 Buildroot 是什么(以为是“编译工具”)
  • 不知道 QEMU 的 -M versatilepb 到底模拟了什么硬件
  • 对 “initrd”、“dtb”、“virtio”、“SMC91x” 等术语完全陌生
  • 第一次看到 make qemu 编译半小时,以为电脑卡死了 😅

⚔️ 完整闯关记录(含起步阶段)

第〇关:认知觉醒 —— “原来 Buildroot 不是直接跑 QEMU”

现象
第一次运行 make qemu,等了 20 分钟,终端还在刷 .o 文件。

困惑

“不是说 make qemu 就能启动吗?怎么一直在编译?”

关键领悟
make qemu = 先全量编译整个系统(内核 + 工具链 + 根文件系统),再启动 QEMU。
✅ 后续开发应使用 make linux-rebuild + 手动 qemu-system-arm 来加速迭代。

🌱 这是你迈出的第一步:理解“构建”与“运行”的分离


第一关:环境与依赖之战

现象
编译中途报错:

ERROR: Subproject zlib is buildable: NO

分析
Buildroot 尝试构建某个图形库(如 libgl2),但宿主机缺少 zlib 开发头文件。

sudo apt install -y zlib1g-dev libssl-dev libncurses5-dev

同时,手动下载 Linux 内核(因网络慢/被墙):

wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.32.tar.xz
mv linux-6.6.32.tar.xz buildroot/dl/

从此学会:嵌入式构建依赖宿主机开发环境


第二关:消失的软件包(Buildroot 配置迷雾)

现象
make menuconfigTarget packages → 找不到 openssh

深入排查

  • 默认 toolchain 是 musl + static-only,而 OpenSSH 需要 动态链接 + glibc
  • 即使强行在 .config 中写 BR2_PACKAGE_OPENSSH=y,也会因依赖缺失被忽略

解决

  1. Toolchain → C library → glibc
  2. Toolchain → [*] Enable C++ support(某些包间接依赖)
  3. 此时 openssh 才在 Networking applications 中出现!

领悟:Buildroot 的包可见性由 toolchain 和依赖链动态决定


第三关:启动崩溃(Kernel Panic)

现象
QEMU 启动后卡在:

Unable to mount root fs on unknown-block(0,0)

原理

  • Buildroot 生成的是 cpio initramfs(内存盘)
  • 但内核未启用 Initial RAM filesystem 支持
  • 也未开启 RAM block device(旧版内核需要)

解决(内核配置):

General setup --->
  [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

Device Drivers --->
  Block devices --->
    <*> RAM block device support
    (16384) Default number of RAM disks

从此明白:根文件系统类型必须与内核能力匹配


第四关:驱动迷宫(网络驱动三连败)

这是最艰难的一关,经历了三次尝试:

❌ 方案 A:Virtio PCI(经典误区)
  • 开启 PCI support + Virtio network driver
  • QEMU 参数:-device virtio-net-pci
  • 失败原因versatilepb 平台 没有 PCI 总线!日志显示 deferred probe pending
❌ 方案 B:Virtio MMIO(看似合理)
  • 开启 Platform bus driver for memory mapped virtio
  • QEMU 参数:-device virtio-net-device
  • 失败原因:Linux 6.6+ 虽支持 Virtio-MMIO,但 QEMU 的 versatilepb 机器模型未注册 Virtio 设备,内核根本看不到网卡
✅ 方案 C:原生 SMC91x(回归硬件本质)
  • 查阅 QEMU 源码确认:versatilepb 板载网卡是 SMSC LAN91C111(SMC91x 系列)
  • 内核配置:
    Device Drivers --->
      GPIO Support ---> [*] GPIO Support   # 隐藏依赖!
      Network device support --->
        Ethernet driver support --->
          [*] SMC (SMSC) devices --->
            <*> SMC 91C9x/91C1xxx support
  • QEMU 启动参数:
    -net nic,model=smc91c111,netdev=net0

最终成功ip a 显示 eth0,DHCP 获取 10.0.2.15

🌟 关键教训:不要盲目套用“现代方案”,要尊重目标平台的真实硬件


第五关:最后一道门(SSH 权限)

现象
SSH 连接建立,但密码被拒绝(即使密码正确)。

排查

  • 查看 /var/log/auth.log(若存在)或 journalctl(但 busybox 无)
  • 最终发现:OpenSSH 默认 禁止 root 密码登录

解决

  1. 在 Buildroot 中启用 overlay 机制(或手动挂载后修改)
    echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
  2. 重启 sshd
    /etc/init.d/S50sshd restart

从此记住:安全策略是功能的最后一道锁


🗝️ 黄金配置清单(完整版)

1. Buildroot Menuconfig (make menuconfig

Target options --->
  Target Architecture: ARM (little endian)
  Target Architecture Variant: arm926t

Toolchain --->
  C library: glibc
  [*] Enable C++ support

System configuration --->
  Root password: 123456

Filesystem images --->
  [*] cpio the root filesystem (for use as an initial RAM filesystem)
  [*] gzip compression

Target packages --->
  Networking applications --->
    [*] openssh

2. Linux Kernel Menuconfig (make linux-menuconfig)

General setup --->
  [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

Device Drivers --->
  GPIO Support --->
    [*] GPIO Support

  Block devices --->
    <*> RAM block device support
    (16384) Default number of RAM disks

  Network device support --->
    [*] Network core
    Ethernet driver support --->
      [*] SMC (SMSC) devices --->
        <*> SMC 91C9x/91C1xxx support

3. 最终启动脚本 (run_qemu.sh)

#!/bin/bash
qemu-system-arm -M versatilepb \
  -kernel output/images/zImage \
  -dtb output/images/versatile-pb.dtb \
  -initrd output/images/rootfs.cpio.gz \
  -append "console=ttyAMA0,115200 root=/dev/ram0" \
  -nographic \
  -netdev user,id=net0,hostfwd=tcp::2222-:22 \
  -net nic,model=smc91c111,netdev=net0

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐