2. 开发环境准备:安装交叉编译工具链、配置主机环境、创建项目目录结构

做嵌入式Linux开发,第一件事就是把开发环境搭好。这步要是没弄对,后面编译出来的东西跑不起来,你都不知道问题出在哪。我刚开始做嵌入式那会儿,就吃过这个亏——交叉编译工具链版本不对,折腾了两天才发现是glibc不兼容。

说白了,嵌入式开发环境和PC开发最大的区别就是:你得在PC上编译,在目标板上运行。这就需要一个叫「交叉编译工具链」的东西。咱们一步步来。

2.1 主机环境要求

我个人习惯用Ubuntu 20.04 LTS或22.04 LTS做宿主机。为什么?因为社区支持好,包管理方便,遇到问题搜一下就有答案。

项目 推荐配置 最低要求
操作系统 Ubuntu 22.04 LTS (64-bit) Ubuntu 20.04 LTS
CPU 4核及以上 双核
内存 8GB及以上 4GB
磁盘空间 50GB空闲 20GB
网络 稳定互联网连接 可下载软件包
小提示:如果你用虚拟机,记得给磁盘分配动态扩展。我见过有人只给了20GB固定大小,编译到一半磁盘满了,那叫一个尴尬。

2.2 安装交叉编译工具链

交叉编译工具链,你可以理解成「翻译官」——它把你的x86指令翻译成ARM指令。咱们课程用的是ARM Cortex-A7架构,所以需要安装arm-linux-gnueabihf工具链。

安装方式有两种,我推荐第二种:

方式一:apt直接安装(简单但版本旧)

sudo apt update
sudo apt install gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf

这种方式装完就能用,但版本通常比较老。我记得有一次用apt装了个gcc 7.x,结果编译新版本内核时一堆语法错误……从那以后我就改用第二种方式了。

方式二:Linaro工具链(推荐)

Linaro的ARM工具链更新及时,优化也好。咱们用gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf这个版本,稳定且兼容性好。

# 下载工具链
wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz

# 解压到指定目录
sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz -C /opt/

# 添加环境变量
echo 'export PATH=$PATH:/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin' >> ~/.bashrc
source ~/.bashrc
注意:解压路径不要有中文或空格。我曾经把工具链解压到「我的工具」文件夹下,结果makefile里路径解析直接崩了。

验证安装

装完之后,跑一下这个命令:

arm-linux-gnueabihf-gcc --version

如果看到类似下面的输出,就说明装好了:

arm-linux-gnueabihf-gcc (Linaro GCC 7.5-2019.12) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.

2.3 安装必要的主机工具

除了交叉编译器,咱们还需要一些辅助工具。这些工具在构建根文件系统和调试时都会用到。

sudo apt install -y \
    build-essential \
    git \
    vim \
    curl \
    wget \
    libncurses5-dev \
    libssl-dev \
    bison \
    flex \
    u-boot-tools \
    device-tree-compiler \
    qemu-user-static \
    debootstrap

这里我重点说几个:

  • libncurses5-dev:编译内核时make menuconfig必须的
  • device-tree-compiler:编译设备树.dtb文件用的
  • qemu-user-static:可以在PC上模拟运行ARM程序,调试利器
避坑指南:我曾经在Ubuntu 22.04上装libncurses5-dev时发现包名变成了libncurses-dev。如果你遇到「无法定位软件包」的错误,试试用apt search找一下正确的包名。

2.4 创建项目目录结构

好,工具链和主机环境都准备好了。接下来咱们搭项目骨架。一个清晰的项目结构,能让你少走很多弯路。我见过太多人把所有文件堆在一个目录里,最后自己都找不着北。

我个人习惯用这样的结构:

~/embedded-linux-course/
├── toolchain/              # 交叉编译工具链(或软链接)
├── kernel/                 # Linux内核源码
├── bootloader/             # U-Boot源码
├── rootfs/                 # 根文件系统构建目录
│   ├── source/             # 源码包(BusyBox、glibc等)
│   ├── output/             # 编译输出
│   └── target/             # 目标根文件系统目录
├── images/                 # 最终镜像文件
├── scripts/                # 自动化构建脚本
└── docs/                   # 笔记和文档

创建命令:

mkdir -p ~/embedded-linux-course/{toolchain,kernel,bootloader,rootfs/{source,output,target},images,scripts,docs}

你可能会问:为什么要把rootfs拆成source、output、target三个子目录?

嗯,这里解释一下:

  • source:放BusyBox、glibc等源码包,保持原始状态
  • output:编译产生的中间文件,随时可以删掉重来
  • target:最终组装好的根文件系统目录,直接打包就能用

这样分层,你想想看——调试时只需要重新编译某个组件,其他部分不受影响。

2.5 验证环境:写个Hello World

环境搭没搭好,跑个程序就知道了。咱们写个简单的C程序,用交叉编译器编译,再用qemu模拟运行。

# 创建测试文件
cat > ~/embedded-linux-course/test_arm.c << 'EOF'
#include <stdio.h>

int main() {
    printf("Hello from ARM!\n");
    printf("Cross-compilation works!\n");
    return 0;
}
EOF

# 交叉编译
arm-linux-gnueabihf-gcc -static -o test_arm test_arm.c

# 查看文件信息
file test_arm

如果输出是ELF 32-bit LSB executable, ARM,说明交叉编译成功了。

再用qemu跑一下:

qemu-arm-static ./test_arm

看到Hello from ARM!,恭喜你,环境全部就绪。

小技巧:编译时加-static参数,会把所有库静态链接进去。这样在qemu里跑就不用额外挂载动态库了,调试起来特别方便。

2.6 本章知识结构图

下面这张图帮你理清整个开发环境的脉络:

嵌入式Linux开发环境准备 — 知识结构 主机环境 交叉编译工具链 主机工具 Ubuntu 20.04/22.04 4核CPU / 8GB内存 50GB磁盘空间 Linaro gcc 7.5.0 arm-linux-gnueabihf 环境变量配置 build-essential device-tree-compiler qemu-user-static 项目目录结构 kernel/ rootfs/ images/ scripts/ docs/ source/ output/ target/ 验证:交叉编译Hello World + qemu运行

2.7 常见问题与解决

最后,我把这些年遇到的环境问题整理了一下:

问题现象 原因 解决办法
arm-linux-gnueabihf-gcc: command not found 环境变量没配置或路径不对 检查PATH是否包含工具链bin目录,重新source ~/.bashrc
编译时报错:/usr/bin/ld: cannot find -lc 缺少C库或库路径不对 检查工具链是否完整,重新解压安装
qemu运行报错:Invalid ELF image for this architecture 编译架构和qemu模拟架构不匹配 确认编译时用的是arm-linux-gnueabihf-gcc,不是gcc
make menuconfig报错:Unable to find the ncurses libraries 缺少libncurses5-dev sudo apt install libncurses5-dev(22.04用libncurses-dev)
重要提醒:如果你用的是Windows系统,建议装WSL2(Windows Subsystem for Linux 2),体验和原生Linux几乎一样。别用Cygwin,坑太多,我当年被它折腾得够呛。