第2章:开发环境搭建——Ubuntu 22.04配置、交叉编译工具链与TFTP/NFS服务
做嵌入式Linux开发,环境搭建是第一步。这一步要是没走稳,后面全是坑。我见过不少新手,花了一周时间调驱动,最后发现是交叉编译工具链版本不对——这种冤枉路,咱们不走。
这一章,我会带你从零搭建一套完整的Rockchip开发环境。咱们用Ubuntu 22.04,配gcc-arm-10.3交叉编译器,再搭好TFTP和NFS服务。说白了,就是让你的PC能编译ARM代码,能让开发板通过网络加载内核和设备树,还能把根文件系统挂载到开发板上。
本章核心目标: 完成一套可复用的嵌入式开发环境,后续所有驱动实验都基于此环境运行。
2.1 Ubuntu 22.04 基础配置
我个人习惯用Ubuntu 22.04 LTS作为开发主机。为什么选这个版本?因为它的软件源稳定,对ARM交叉编译工具链的支持最友好。你如果还在用18.04,建议升级——有些新版本的GCC和工具链在旧系统上编译会报奇奇怪怪的错。
2.1.1 系统更新与基础软件包
装好系统后,第一件事就是更新软件源。别跳过这步,我遇到过有人直接装工具链,结果依赖库版本不对,折腾了两天。
sudo apt update
sudo apt upgrade -y
sudo apt install -y build-essential git vim curl wget \
net-tools openssh-server nfs-kernel-server tftpd-hpa \
python3 python3-pip device-tree-compiler \
libncurses5-dev libssl-dev flex bison
这里面有几个关键包:
- build-essential:编译必备,gcc、make都在里面
- device-tree-compiler:编译设备树用的dtc工具
- nfs-kernel-server 和 tftpd-hpa:后面要搭的服务
- libncurses5-dev:内核menuconfig配置界面需要它
小技巧: 我习惯装完系统先做个快照。万一后面装坏了,直接回滚,不用重装系统。
2.1.2 配置SSH与静态IP
开发板跟PC之间频繁通信,静态IP是必须的。我一般这样配:
# 编辑网络配置文件
sudo vim /etc/netplan/01-netcfg.yaml
# 内容示例(根据你的网卡名调整)
network:
version: 2
ethernets:
ens33:
dhcp4: no
addresses:
- 192.168.1.100/24
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 114.114.114.114]
# 应用配置
sudo netplan apply
配完以后,用 ip addr 确认IP生效。然后开启SSH服务,这样你就能从笔记本远程连到开发主机了。
sudo systemctl enable ssh
sudo systemctl start ssh
2.2 交叉编译工具链安装(gcc-arm-10.3)
交叉编译,说白了就是在x86的PC上编译出ARM架构能跑的代码。你想想看,开发板那点算力,编译个内核得等到天荒地老。所以咱们用PC来干这活。
2.2.1 下载与解压
Rockchip官方推荐用gcc-arm-10.3-2021.07版本。我试过好几个版本,这个对RK3568/RK3588的支持最稳。
# 下载(如果网速慢,可以用国内镜像)
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
# 解压到 /opt 目录
sudo tar -xvf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/
# 重命名(方便记忆)
sudo mv /opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu /opt/gcc-arm-10.3
2.2.2 配置环境变量
解压完不算完,你得让系统能找到这些工具。我习惯把环境变量写到 ~/.bashrc 里:
vim ~/.bashrc
# 在文件末尾添加
export PATH=$PATH:/opt/gcc-arm-10.3/bin
export CROSS_COMPILE=aarch64-none-linux-gnu-
export ARCH=arm64
# 使配置生效
source ~/.bashrc
验证一下是否装好了:
aarch64-none-linux-gnu-gcc --version
# 输出应该类似:
# aarch64-none-linux-gnu-gcc (GNU Toolchain for the A-profile architecture 10.3-2021.07) 10.3.1 20210621
# Copyright (C) 2020 Free Software Foundation, Inc.
注意: 如果你用的是RK3288或RK3399这类32位兼容的芯片,编译32位代码时需要用 arm-none-linux-gnueabihf- 前缀。别搞混了,我见过有人用64位工具链编译32位内核,链接阶段报一堆错。
2.2.3 测试编译
写个简单的测试程序,确认工具链能正常工作:
# 创建测试文件
cat > hello.c << EOF
#include <stdio.h>
int main(void)
{
printf("Rockchip Embedded Linux!\n");
return 0;
}
EOF
# 交叉编译
aarch64-none-linux-gnu-gcc -o hello hello.c
# 查看生成的文件类型
file hello
# 输出:hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV)
看到 ARM aarch64 就对了。这个程序在x86的PC上跑不了,得放到开发板上执行。
2.3 TFTP服务搭建
TFTP这玩意儿,说白了就是一个极简的文件传输协议。开发板在uboot阶段,网卡驱动已经初始化了,但文件系统还没挂载。这时候想从PC上拿内核镜像、设备树文件,就得靠TFTP。
2.3.1 安装与配置
# 安装tftp服务端
sudo apt install tftpd-hpa -y
# 创建tftp根目录
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
# 修改配置文件
sudo vim /etc/default/tftpd-hpa
配置文件内容如下:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure --create"
注意那个 --create 选项,加上它之后,开发板才能通过TFTP往PC上传文件。调试的时候很有用。
2.3.2 启动与测试
# 重启服务
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa
# 放一个测试文件
echo "TFTP Test" > /srv/tftp/test.txt
# 本地测试(安装tftp客户端)
sudo apt install tftp -y
tftp localhost
tftp> get test.txt
tftp> quit
# 查看是否下载成功
cat test.txt
避坑指南: 我曾经在RK3568的板子上,uboot死活从TFTP下载不了内核。查了半天,发现是防火墙把69端口封了。执行 sudo ufw allow 69/udp 就解决了。
2.4 NFS服务搭建
NFS的作用跟TFTP正好互补。TFTP用于uboot阶段传小文件,NFS用于内核启动后挂载根文件系统。开发阶段,你不需要每次修改都烧写根文件系统到开发板的Flash里,直接通过网络挂载PC上的目录就行了。
2.4.1 安装与配置
# 安装NFS服务端
sudo apt install nfs-kernel-server -y
# 创建共享目录
sudo mkdir -p /srv/nfs/rootfs
sudo chmod 777 /srv/nfs/rootfs
# 编辑导出配置文件
sudo vim /etc/exports
在文件末尾添加:
/srv/nfs/rootfs 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
参数说明:
| 参数 | 含义 |
|---|---|
| rw | 读写权限 |
| sync | 同步写入,保证数据一致性 |
| no_subtree_check | 关闭子树检查,提升性能 |
| no_root_squash | 允许开发板以root权限访问,这个很重要 |
2.4.2 启动与挂载测试
# 导出共享目录
sudo exportfs -a
# 重启NFS服务
sudo systemctl restart nfs-kernel-server
# 本地挂载测试
sudo mount -t nfs 192.168.1.100:/srv/nfs/rootfs /mnt
# 写入测试文件
echo "NFS Test" | sudo tee /mnt/nfs_test.txt
# 卸载
sudo umount /mnt
注意: 开发板通过NFS挂载根文件系统时,uboot的bootargs里要传 root=/dev/nfs nfsroot=192.168.1.100:/srv/nfs/rootfs。IP地址要跟你PC的静态IP一致。我刚开始做的时候,IP写错了,板子启动到一半就卡住了。
2.5 本章知识体系总览
下面这张图,把整个开发环境的结构画清楚了。你可以对照着检查自己配到哪一步了。
2.6 环境验证清单
配完环境别急着往下走。我列了个检查清单,每项都过一遍,确保后面不出幺蛾子。
| 检查项 | 验证方法 | 预期结果 |
|---|---|---|
| 交叉编译器 | aarch64-none-linux-gnu-gcc --version |
显示10.3.1版本信息 |
| TFTP服务 | systemctl status tftpd-hpa |
active (running) |
| TFTP传输 | 本地tftp get测试文件 | 成功下载文件 |
| NFS服务 | systemctl status nfs-kernel-server |
active (exited) |
| NFS挂载 | 本地mount测试 | 成功挂载并读写文件 |
| SSH服务 | ssh localhost |
成功登录 |
| 静态IP | ip addr |
IP为配置的静态地址 |
我的经验: 环境搭建这一步,宁可多花一小时验证,也别省。我见过有人TFTP配错了路径,uboot下载内核时一直报"File not found",查了三天才发现是目录权限问题。嗯,这种坑踩过一次就记住了。