第1章 开发环境搭建:工欲善其事,必先利其器

做内核移植这件事,我踩过最大的坑就是环境没搭好就急着动手。你想想看,代码写好了,烧进去跑不起来,你都不知道是代码问题还是环境问题。所以这一章,咱们先把地基打牢。

本章核心目标:搭建一套完整的内核开发调试环境,实现「代码修改 → 编译 → 网络加载 → 串口调试」的闭环工作流。

开发环境搭建知识体系 开发环境搭建 Ubuntu虚拟机安装 交叉编译工具链 TFTP/NFS服务 串口终端工具 VMware/VirtualBox Ubuntu 20.04 LTS gcc-arm-linux-gnueabihf tftp-hpa / nfs-kernel-server MobaXterm / SecureCRT 最终目标:PC端编译 → 网络加载到开发板 → 串口调试 形成高效的「修改-编译-调试」闭环

1.1 Ubuntu虚拟机安装

我个人习惯用 VMware Workstation,稳定,兼容性好。当然你用 VirtualBox 也行,免费嘛。但有一点要注意——虚拟机硬盘至少给 80GB。为什么?你后面编译内核、buildroot、yocto,动不动就几十个G。我刚开始做的时候只给了40G,结果编译到一半磁盘满了,那叫一个尴尬。

我的建议:Ubuntu 版本选 20.04 LTS 或 22.04 LTS。太新的版本(比如24.04)有些老工具链可能不兼容,太旧的(18.04以下)软件源都开始撤了。

安装步骤其实很简单,我快速过一下重点:

  1. 下载镜像:去 Ubuntu 官网下载桌面版 ISO,别用 server 版,桌面版自带图形工具,调试方便。
  2. 创建虚拟机:CPU 给 4 核以上,内存 8GB 以上,硬盘 80GB 以上。网络选 NAT 模式,方便上网。
  3. 安装系统:一路默认就行,分区选「清除整个磁盘并安装 Ubuntu」——别怕,它清的是虚拟磁盘。
  4. 安装后必做:
    • sudo apt update && sudo apt upgrade -y
    • 安装 VMware Tools 或 open-vm-tools,方便文件拖拽和自适应分辨率
    • 设置静态 IP(后面 TFTP/NFS 需要固定地址)

注意:虚拟机网络一定要用 NAT 或桥接模式。我见过有人用「仅主机模式」,结果开发板连不上虚拟机,折腾了半天才发现是网络不通。

1.2 交叉编译工具链配置

说白了,交叉编译就是在 PC 上编译出能在 ARM 开发板上运行的程序。你想想看,开发板那点性能,编译个内核得等到猴年马月?所以必须在 PC 上搞定。

工具链的选择,我推荐两种:

工具链 适用场景 安装方式
gcc-arm-linux-gnueabihf ARM 32位 Cortex-A系列 sudo apt install gcc-arm-linux-gnueabihf
gcc-aarch64-linux-gnu ARM 64位 Cortex-A系列 sudo apt install gcc-aarch64-linux-gnu
Linaro 官方工具链 需要特定版本或优化 官网下载后解压,配置 PATH

我个人习惯用 apt 直接安装,省事。但如果你做的是商业项目,建议用 Linaro 的官方工具链,版本更可控。

验证工具链是否安装成功:

# 32位工具链
arm-linux-gnueabihf-gcc --version

# 64位工具链
aarch64-linux-gnu-gcc --version

# 写个简单的测试程序
echo '#include <stdio.h>
int main() { printf("Hello, ARM!\n"); return 0; }' > test.c

arm-linux-gnueabihf-gcc -o test test.c
file test
# 输出应该显示:ELF 32-bit LSB executable, ARM

嗯,这里要注意一点:工具链版本要和内核版本匹配。比如你编译 Linux 5.10 内核,gcc 版本最好在 9.x 以上。版本太老,编译会报一些莫名其妙的错误。我曾经用 gcc 4.8 去编译 5.15 内核,结果一堆语法错误,后来才发现是工具链太旧了。

1.3 TFTP/NFS 服务搭建

这两个服务是内核调试的「高速公路」。TFTP 用来快速下载内核镜像和设备树,NFS 用来挂载根文件系统。说白了,你改完代码,编译好,通过 TFTP 传到开发板上启动,根文件系统通过 NFS 共享 PC 上的目录——这样调试效率最高。

1.3.1 TFTP 服务

# 安装 TFTP 服务器
sudo apt install tftp-hpa tftpd-hpa

# 创建 TFTP 根目录
sudo mkdir -p /tftpboot
sudo chmod 777 /tftpboot

# 修改配置文件 /etc/default/tftpd-hpa
# 内容如下:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure -c -s"

# 重启服务
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa

测试 TFTP 是否正常:在 /tftpboot 下放一个文件,然后在开发板的 U-Boot 里执行 tftp 0x82000000 zImage,如果能下载成功,说明 TFTP 通了。

1.3.2 NFS 服务

# 安装 NFS 服务器
sudo apt install nfs-kernel-server

# 创建 NFS 共享目录
sudo mkdir -p /nfsroot
sudo chmod 777 /nfsroot

# 编辑 /etc/exports,添加一行:
/nfsroot *(rw,sync,no_subtree_check,no_root_squash)

# 重启服务
sudo systemctl restart nfs-kernel-server
sudo exportfs -av

注意:no_root_squash 这个选项很重要。不加的话,开发板上的 root 用户会被映射成 nobody,导致权限问题。我刚开始做的时候没加这个,结果挂载根文件系统后连 ls 都报权限错误,排查了半天才发现是这个问题。

1.4 串口终端工具使用

串口是嵌入式开发者的「眼睛」。内核启动信息、控制台交互,全得靠它。我个人最常用的是 MobaXterm,因为它集成了串口、SSH、FTP 等多种功能,一个工具搞定所有。

串口参数设置,记住这个「黄金组合」:

参数
波特率 115200
数据位 8
停止位 1
校验位
流控制

其他常用工具还有:

  • SecureCRT:老牌工具,功能强大,但要付费
  • PuTTY:免费轻量,但界面简陋
  • minicom:Linux 下的命令行工具,适合脚本自动化
  • screen:更轻量,screen /dev/ttyUSB0 115200 一行搞定

快速检查串口设备:

# 查看串口设备
ls -l /dev/ttyUSB*
ls -l /dev/ttyACM*

# 如果没看到设备,检查驱动
lsmod | grep usb_serial

# 用 screen 连接(Linux 下)
sudo screen /dev/ttyUSB0 115200

# 退出 screen:Ctrl+A 然后按 K

嗯,这里有个小技巧:串口线一定要用原装的。我遇到过好几次,用便宜的 USB 转串口线,丢数据、乱码,折腾半天发现是线的问题。PL2303 和 CH340 芯片的线都还行,但 CP2102 的稳定性最好。

我的习惯:每次连接开发板前,先用串口工具发送一个回车,看能不能收到 U-Boot 的提示符。如果没反应,先检查串口线,再检查波特率设置,最后检查开发板是否上电。按这个顺序排查,90% 的问题都能解决。

好了,环境搭建这部分就这些。这些东西看起来琐碎,但每一样都是后面工作的基础。你花半天时间把环境搭好,后面能省下好几天的排查时间。我个人觉得,这是整个内核移植过程中性价比最高的一步。

本章小结:

  • Ubuntu 虚拟机:硬盘至少 80GB,网络用 NAT 或桥接
  • 交叉编译工具链:apt 安装最方便,注意版本匹配
  • TFTP:用于快速下载内核镜像,根目录权限要放开
  • NFS:用于共享根文件系统,记得加 no_root_squash
  • 串口终端:115200 8N1 是黄金参数,线材质量很重要

公众号:蓝海资料掘金营,微信deep3321