第1章 开发环境搭建:工欲善其事,必先利其器
做内核移植这件事,我踩过最大的坑就是环境没搭好就急着动手。你想想看,代码写好了,烧进去跑不起来,你都不知道是代码问题还是环境问题。所以这一章,咱们先把地基打牢。
本章核心目标:搭建一套完整的内核开发调试环境,实现「代码修改 → 编译 → 网络加载 → 串口调试」的闭环工作流。
1.1 Ubuntu虚拟机安装
我个人习惯用 VMware Workstation,稳定,兼容性好。当然你用 VirtualBox 也行,免费嘛。但有一点要注意——虚拟机硬盘至少给 80GB。为什么?你后面编译内核、buildroot、yocto,动不动就几十个G。我刚开始做的时候只给了40G,结果编译到一半磁盘满了,那叫一个尴尬。
我的建议:Ubuntu 版本选 20.04 LTS 或 22.04 LTS。太新的版本(比如24.04)有些老工具链可能不兼容,太旧的(18.04以下)软件源都开始撤了。
安装步骤其实很简单,我快速过一下重点:
- 下载镜像:去 Ubuntu 官网下载桌面版 ISO,别用 server 版,桌面版自带图形工具,调试方便。
- 创建虚拟机:CPU 给 4 核以上,内存 8GB 以上,硬盘 80GB 以上。网络选 NAT 模式,方便上网。
- 安装系统:一路默认就行,分区选「清除整个磁盘并安装 Ubuntu」——别怕,它清的是虚拟磁盘。
- 安装后必做:
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