2. 开发环境搭建:Ubuntu系统安装、交叉编译工具链配置、TFTP/NFS服务搭建
做嵌入式Linux开发,第一步就是把“窝”搭好。我见过不少新手,上来就急着写代码,结果编译报错、烧录失败,折腾半天发现是环境问题。说白了,环境搭不好,后面全是坑。
这一章,咱们就把RK3568的开发环境从头捋一遍。Ubuntu系统怎么装、交叉编译链怎么配、TFTP和NFS服务怎么搭,一步到位。
本章核心目标:在Windows宿主机上通过虚拟机运行Ubuntu 20.04,配置RK3568专用的交叉编译工具链,并搭建TFTP/NFS服务用于内核和根文件系统的网络加载。
2.1 Ubuntu系统安装与基础配置
我个人习惯用Ubuntu 20.04 LTS做开发。为什么?因为瑞芯微官方SDK对这个版本支持最好,踩过的坑最少。你想想看,如果选个太新的版本,库依赖可能不兼容;太老的版本,工具链又跟不上。
2.1.1 虚拟机 vs 双系统
| 方案 | 优点 | 缺点 | 我的建议 |
|---|---|---|---|
| VMware/VirtualBox虚拟机 | 与Windows无缝切换,快照备份方便 | 性能有损耗,磁盘IO稍慢 | 新手首选,省心 |
| WSL2 | 启动快,资源占用低 | USB设备直通麻烦,图形化支持弱 | 不推荐做驱动开发 |
| 双系统 | 性能最好,硬件直通 | 切换系统麻烦,容易搞坏引导 | 有经验后再考虑 |
嗯,这里要注意:如果你用虚拟机,磁盘空间至少给80GB。RK3568的SDK解压完就20多G,编译一次内核又占不少空间。我曾经因为磁盘不够,编译到一半报错,气得不行。
2.1.2 安装后的基础配置
装完系统后,有几件事必须做:
- 更换软件源——用国内的镜像源,比如清华、阿里、中科大。不然下载包能等到你怀疑人生。
- 安装基础开发工具——gcc、g++、make、git、vim、ssh等。
- 配置静态IP——开发板通过网线直连电脑时,固定IP能省很多麻烦。
# 更换软件源(以清华源为例)
sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo apt update
# 安装基础工具
sudo apt install -y build-essential git vim openssh-server net-tools
# 配置静态IP(以Ubuntu 20.04 netplan为例)
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]
小技巧:配置完netplan后,执行 sudo netplan apply 生效。如果连不上网,检查一下网卡名称是不是ens33,可以用 ip a 查看。
2.2 交叉编译工具链配置
交叉编译,说白了就是在PC上编译出能在ARM开发板上运行的程序。PC是x86架构,开发板是ARM架构,编译器得“跨”过去。
RK3568是ARMv8架构,64位。所以我们需要aarch64(ARM 64位)的交叉编译工具链。
2.2.1 获取工具链
瑞芯微官方SDK里自带工具链,路径在 prebuilts/gcc/linux-x86/aarch64/ 下。你也可以从Linaro官网下载。
我个人习惯用官方SDK里的,版本匹配,省心。
# 解压工具链(假设SDK在~/rk3568_sdk目录下)
cd ~/rk3568_sdk/prebuilts/gcc/linux-x86/aarch64/
ls -l
# 你会看到类似 gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz 的文件
# 解压
tar -xvf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
2.2.2 配置环境变量
解压完,需要把工具链的bin目录加到PATH里。这样你在任何目录下都能直接调用交叉编译器。
# 编辑 ~/.bashrc
vim ~/.bashrc
# 在文件末尾添加:
export PATH=$PATH:~/rk3568_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin
# 保存退出后,使配置生效
source ~/.bashrc
# 验证是否配置成功
aarch64-none-linux-gnu-gcc --version
# 如果显示版本信息,说明配置成功
避坑指南:我曾经遇到过PATH配置正确,但编译时提示“找不到命令”。后来发现是64位系统缺少32位库。执行 sudo apt install -y lib32z1 lib32ncurses5 解决。
2.2.3 测试交叉编译
写一个简单的Hello World程序,验证工具链是否正常工作。
# 创建测试文件
vim hello.c
#include <stdio.h>
int main() {
printf("Hello, RK3568!\n");
return 0;
}
# 交叉编译
aarch64-none-linux-gnu-gcc hello.c -o hello_arm
# 查看生成的文件信息
file hello_arm
# 输出应该包含:ELF 64-bit LSB executable, ARM aarch64
看到“ARM aarch64”字样,说明编译成功。这个程序不能在PC上直接运行,得放到开发板上跑。
2.3 TFTP/NFS服务搭建
驱动开发过程中,需要频繁地把内核镜像、设备树、根文件系统传到开发板上。用U盘拷?太慢了。用串口传?更慢。
TFTP和NFS就是干这个的。TFTP用来传内核和设备树,NFS用来挂载根文件系统。两者配合,开发效率翻倍。
2.3.1 TFTP服务搭建
TFTP(Trivial File Transfer Protocol)是个轻量级的文件传输协议。说白了,就是让开发板能从PC上下载文件。
# 安装TFTP服务
sudo apt install -y tftpd-hpa
# 创建TFTP根目录
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
# 配置TFTP服务
sudo vim /etc/default/tftpd-hpa
# 修改为以下内容:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"
# 重启服务
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa
# 测试:在/srv/tftp目录下放一个文件,然后在开发板上用tftp命令下载
echo "test file" | sudo tee /srv/tftp/test.txt
小技巧:TFTP默认端口是69。如果开发板连不上,检查防火墙:sudo ufw allow 69/udp。我在项目中遇到过好几次防火墙没关导致TFTP超时的情况。
2.3.2 NFS服务搭建
NFS(Network File System)能让开发板把PC上的一个目录挂载成自己的根文件系统。这样你修改PC上的文件,开发板上立即可见,不用反复烧录。
# 安装NFS服务
sudo apt install -y nfs-kernel-server
# 创建NFS共享目录(存放根文件系统)
sudo mkdir -p /srv/nfs/rootfs
sudo chmod 777 /srv/nfs/rootfs
# 配置NFS导出
sudo vim /etc/exports
# 添加以下内容:
/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
# 参数说明:
# * :允许所有IP访问(开发环境用,生产环境要限制)
# rw :读写权限
# sync :同步写入
# no_root_squash:允许root用户操作(重要!)
# 重启NFS服务
sudo systemctl restart nfs-kernel-server
sudo systemctl enable nfs-kernel-server
# 验证NFS是否正常工作
showmount -e localhost
# 应该显示:/srv/nfs/rootfs *
避坑指南:no_root_squash 这个参数一定要加。如果不加,开发板上的root用户会被映射成nobody,导致无法创建文件。我曾经因为这个参数,调试了整整一个下午。
2.3.3 开发板端配置
在U-Boot启动时,设置从TFTP下载内核,并用NFS挂载根文件系统。
# 在U-Boot命令行中设置环境变量
setenv serverip 192.168.1.100 # PC的IP
setenv ipaddr 192.168.1.101 # 开发板的IP
setenv netmask 255.255.255.0
# 从TFTP下载内核和设备树
tftp 0x02000000 Image
tftp 0x06000000 rk3568-evb.dtb
# 设置NFS根文件系统
setenv bootargs "root=/dev/nfs nfsroot=192.168.1.100:/srv/nfs/rootfs,v3,tcp rw ip=192.168.1.101:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off"
# 启动内核
booti 0x02000000 - 0x06000000
2.4 本章知识体系
下面这张图,把本章的核心内容串起来了。你一看就明白各个组件之间的关系。
2.5 常见问题与排查
搭建环境时,总会遇到各种问题。我把最常见的几个列出来,你遇到了直接对照排查。
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| 交叉编译器找不到 | PATH未配置或配置错误 | 检查 ~/.bashrc 中的PATH路径是否正确,执行 source ~/.bashrc |
| TFTP下载超时 | 防火墙未放行69端口 | sudo ufw allow 69/udp 或关闭防火墙 |
| NFS挂载失败 | 缺少 no_root_squash 参数 |
检查 /etc/exports 配置,重启NFS服务 |
| 开发板ping不通PC | IP不在同一网段或网线问题 | 检查IP配置,确认网线是直连(非交叉线) |
| 编译报错:无法找到头文件 | 工具链版本与内核不匹配 | 使用SDK自带的工具链,不要混用版本 |
总结一下:环境搭建是嵌入式开发的第一步,也是最容易出问题的一步。别急,按照上面的步骤一步步来。遇到问题先看日志,再看网络,最后看权限。这三板斧能解决90%的问题。