2. 环境准备:宿主机Linux发行版选择、安装必要工具链、配置网络与SSH环境

做嵌入式Linux QEMU仿真,第一步就是搭好宿主机环境。这步要是没弄好,后面全是坑。我个人习惯用Ubuntu LTS版本,原因很简单——社区活跃,遇到问题搜一下就有答案,包管理也省心。

2.1 宿主机Linux发行版怎么选

其实主流发行版都能用,但咱们做QEMU仿真,有几个硬指标要考虑:

发行版 推荐版本 理由 避坑点
Ubuntu 22.04 LTS / 24.04 LTS 包最全,QEMU、交叉工具链直接apt装 别用非LTS版,半年一升太折腾
Debian 12 (Bookworm) 稳定,适合服务器长期跑仿真 有些新工具需要自己编译
Fedora 40+ 内核新,对ARMv8支持好 包名和Debian系不一样,得适应
Arch Linux 滚动更新 软件永远最新 不适合新手,配置成本高

我建议你直接用Ubuntu 22.04 LTS。为什么?因为咱们课程里所有例子我都在这上面跑过,不会出现「我这里能跑你那里不行」的尴尬。你想想看,要是环境不一致,调试时定位问题就变成猜谜游戏了。

我的习惯:宿主机装好第一件事就是配好apt源,换成国内镜像。不然下载工具链时那个速度……嗯,你会怀疑人生的。

2.2 安装必要工具链

工具链分两部分:一是QEMU本身,二是交叉编译工具链。咱们一个一个来。

2.2.1 安装QEMU

Ubuntu下安装QEMU很简单,一条命令搞定:

sudo apt update
sudo apt install qemu-system-arm qemu-system-aarch64 qemu-user-static

这里我解释一下这三个包的区别:

  • qemu-system-arm:仿真ARM架构的完整系统,包括外设
  • qemu-system-aarch64:仿真64位ARMv8架构
  • qemu-user-static:用户态仿真,可以直接运行ARM二进制文件

装完后验证一下:

qemu-system-aarch64 --version
# 输出类似:QEMU emulator version 8.2.2
注意:QEMU版本别太老。我曾经在Ubuntu 18.04上遇到过QEMU 4.2不支持某些ARMv8指令的问题,折腾了两天才发现是版本太旧。建议至少用QEMU 7.0以上。

2.2.2 安装交叉编译工具链

交叉编译,说白了就是在x86的电脑上编译出ARM能跑的程序。咱们需要两个工具链:

# ARM 32位工具链
sudo apt install gcc-arm-linux-gnueabihf

# ARM 64位工具链
sudo apt install gcc-aarch64-linux-gnu

装完检查一下:

aarch64-linux-gnu-gcc --version
arm-linux-gnueabihf-gcc --version

这里有个细节——为什么32位用gnueabihf而不是gnueabi?hf代表硬浮点,性能更好。现在主流ARM芯片都支持硬浮点,除非你搞的是上古硬件,否则一律用gnueabihf。

2.2.3 其他必备工具

除了QEMU和编译器,还有一些工具是少不了的:

sudo apt install git make cmake device-tree-compiler \
                 u-boot-tools flex bison libssl-dev \
                 libncurses-dev python3 python3-pip

这些工具的作用:

  • device-tree-compiler:编译设备树文件,QEMU仿真ARM设备必须
  • u-boot-tools:制作U-Boot镜像,后面部署内核要用
  • flex/bison:编译内核时需要
  • libssl-dev:内核签名和模块编译依赖

避坑指南:我曾经在编译内核时卡在flex: command not found,就是因为忘了装flex。建议你一次性把这些都装好,省得后面编译到一半报错,还得停下来装包。

2.3 配置网络环境

QEMU仿真出来的系统要联网,需要配置网络。这里有两种方式:

2.3.1 用户态网络(User Networking)

这是QEMU默认的网络模式,不需要宿主机做任何配置。虚拟机通过QEMU内置的NAT访问外网,但外部不能主动访问虚拟机。

qemu-system-aarch64 \
    -netdev user,id=net0,hostfwd=tcp::2222-:22 \
    -device virtio-net-device,netdev=net0

上面这个命令把宿主机的2222端口映射到虚拟机的22端口,这样就能通过SSH连接了。

2.3.2 桥接网络(Bridge Networking)

如果你需要虚拟机跟宿主机在同一网段,或者需要外部设备直接访问虚拟机,就得用桥接模式。

配置桥接网络步骤:

  1. 安装桥接工具:sudo apt install bridge-utils
  2. 创建桥接接口:sudo brctl addbr br0
  3. 把物理网卡加入桥接:sudo brctl addif br0 eth0
  4. 启动QEMU时指定桥接网络

说实话,桥接网络配置起来有点麻烦,而且需要root权限。我个人建议初学者先用用户态网络,等后面需要调试网络服务时再切桥接。

2.4 配置SSH环境

SSH是咱们跟QEMU虚拟机交互的主要方式。配置分两步:宿主机装SSH客户端,虚拟机里装SSH服务端。

2.4.1 宿主机SSH客户端

Ubuntu默认装了OpenSSH客户端,验证一下:

ssh -V
# 输出类似:OpenSSH_8.9p1 Ubuntu-3ubuntu0.6

如果没有,装一下:

sudo apt install openssh-client

2.4.2 生成SSH密钥对

为了方便登录,我建议用密钥认证而不是密码:

ssh-keygen -t ed25519 -f ~/.ssh/qemu_key -N ""
cat ~/.ssh/qemu_key.pub

这里用ed25519算法,比RSA快,安全性也够。后面咱们做根文件系统时,把这个公钥放进去,就能免密登录了。

2.4.3 测试SSH连接

等虚拟机启动后,用端口映射的方式连接:

ssh -p 2222 root@localhost -i ~/.ssh/qemu_key
小技巧:在~/.ssh/config里配个别名,省得每次敲一长串:
Host qemu-vm
  HostName localhost
  Port 2222
  User root
  IdentityFile ~/.ssh/qemu_key

之后直接ssh qemu-vm就行。

2.5 本章知识体系总览

下面这张图把咱们这章的内容串起来了:

环境准备知识体系 宿主机环境准备 发行版选择 工具链安装 网络配置 SSH环境配置 Ubuntu 22.04 LTS(推荐) Debian 12 / Fedora 40+ QEMU 7.0+ gcc-aarch64-linux-gnu dtc / u-boot-tools / flex/bison 用户态NAT(默认) 桥接模式(高级) 密钥认证 + 端口映射

2.6 验证环境是否就绪

所有东西装完后,跑个快速验证脚本,确保环境没问题:

#!/bin/bash
echo "=== 环境验证 ==="

# 检查QEMU
qemu-system-aarch64 --version &>/dev/null
if [ $? -eq 0 ]; then
    echo "[OK] QEMU 已安装"
else
    echo "[FAIL] QEMU 未安装"
fi

# 检查交叉编译器
aarch64-linux-gnu-gcc --version &>/dev/null
if [ $? -eq 0 ]; then
    echo "[OK] ARM64 交叉编译器已安装"
else
    echo "[FAIL] ARM64 交叉编译器未安装"
fi

# 检查SSH
ssh -V &>/dev/null
if [ $? -eq 0 ]; then
    echo "[OK] SSH 客户端已安装"
else
    echo "[FAIL] SSH 客户端未安装"
fi

echo "=== 验证完成 ==="

把上面内容保存为check_env.sh,然后bash check_env.sh跑一下。三个都是OK的话,恭喜你,环境准备好了。

最后提醒一句:别急着往下走。我见过太多人环境没配好就急着编译内核,结果报错时根本分不清是代码问题还是环境问题。花半小时把环境搞扎实,后面能省你半天时间。