2. 开发环境搭建:Ubuntu虚拟机安装、交叉编译工具链配置、TFTP/NFS服务搭建
做嵌入式Linux开发,环境搭建是绕不开的第一道坎。我见过不少新手,一上来就急着写代码,结果编译报错、烧录失败,折腾半天才发现是环境没配好。说白了,开发环境就是你的“作战基地”,基地没建好,仗就没法打。
这一章,我会带你一步步把Ubuntu虚拟机、交叉编译工具链、TFTP和NFS服务都搭起来。这些都是我这些年反复用、反复踩坑后总结出来的经验,跟着走,能省不少时间。
2.1 Ubuntu虚拟机安装
为什么选虚拟机?因为方便。你可以在Windows或macOS上直接跑Linux,不用双系统切换,也不用担心搞坏宿主机。我个人习惯用VMware Workstation,当然VirtualBox也行,看个人喜好。
2.1.1 下载与安装VMware
- 去VMware官网下载Workstation Pro(有30天试用期)
- 或者用VMware Workstation Player(免费版,功能够用)
- 安装过程一路Next就行,没什么特别的
2.1.2 创建Ubuntu虚拟机
我建议用Ubuntu 20.04 LTS或22.04 LTS,这两个版本对嵌入式开发支持最好,软件源也稳定。
- 打开VMware,点击“创建新的虚拟机”
- 选择“典型(推荐)”
- 选择“稍后安装操作系统”
- 客户机操作系统选“Linux”,版本选“Ubuntu 64位”
- 虚拟机名称随便起,位置选个磁盘空间大的盘
- 磁盘大小建议给80GB以上,选“将虚拟磁盘存储为单个文件”
- 点击“自定义硬件”,内存给8GB以上,处理器至少2核
- 网络适配器选“NAT模式”(方便上网)
小提示: 我给虚拟机分配了16GB内存和4核CPU,编译内核时明显快很多。如果你宿主机内存够大,尽量多给点。
2.1.3 安装Ubuntu系统
挂载你下载好的Ubuntu ISO镜像,启动虚拟机,按提示安装就行。这里说几个关键点:
- 分区时选“清除整个磁盘并安装Ubuntu”(虚拟机里无所谓)
- 用户名和密码记好,后面SSH、sudo都要用
- 安装完成后先执行
sudo apt update && sudo apt upgrade -y更新系统
2.2 交叉编译工具链配置
交叉编译,说白了就是在PC上编译出能在ARM板子上运行的程序。为什么不能直接在板子上编译?因为板子性能太弱,编译个内核可能要几个小时,PC上几分钟就搞定了。
2.2.1 什么是交叉编译工具链
工具链包含编译器、链接器、库文件等。比如针对ARM架构的,常用的有:
| 工具链名称 | 目标架构 | 适用场景 |
|---|---|---|
| gcc-arm-linux-gnueabihf | ARM 32位 | 老款ARM板子(如Cortex-A8/A9) |
| aarch64-linux-gnu-gcc | ARM 64位 | 新款ARM板子(如Cortex-A53/A72) |
| arm-none-eabi-gcc | ARM裸机 | 无操作系统的裸机程序 |
我项目中用的最多的是gcc-arm-linux-gnueabihf,因为手头的i.MX6ULL和STM32MP157都是32位ARM。
2.2.2 安装交叉编译工具链
有两种方式:
方式一:apt安装(推荐)
sudo apt install gcc-arm-linux-gnueabihf
安装完成后验证:
arm-linux-gnueabihf-gcc --version
方式二:下载Linaro工具链
如果apt源里的版本太老,可以去Linaro官网下载最新版:
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
tar -xvf gcc-linaro-*.tar.xz
sudo mv gcc-linaro-* /opt/
然后配置环境变量:
export PATH=$PATH:/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin
注意: 我曾经因为工具链版本不匹配,编译出来的内核在板子上跑不起来,折腾了两天才发现是gcc版本太新,内核代码不兼容。建议用Linaro 7.x或8.x版本,比较稳定。
2.2.3 测试工具链
写个简单的hello.c测试一下:
#include <stdio.h>
int main(void)
{
printf("Hello, Embedded Linux!\n");
return 0;
}
编译:
arm-linux-gnueabihf-gcc -o hello hello.c
file hello
如果输出显示ELF 32-bit LSB executable, ARM,说明工具链工作正常。
2.3 TFTP/NFS服务搭建
这两个服务是嵌入式开发中的“快递员”和“共享文件夹”。TFTP用来把编译好的内核、设备树传到板子上,NFS让板子直接挂载PC上的文件系统,方便调试。
2.3.1 TFTP服务搭建
TFTP(Trivial File Transfer Protocol)是个轻量级的文件传输协议,常用于网络启动时下载内核。
安装TFTP服务器:
sudo apt install tftpd-hpa
配置TFTP:
编辑配置文件/etc/default/tftpd-hpa:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"
创建TFTP根目录并设置权限:
sudo mkdir /tftpboot
sudo chmod 777 /tftpboot
重启服务:
sudo systemctl restart tftpd-hpa
小提示: 我把所有编译好的内核镜像、设备树文件都放在/tftpboot下,板子通过uboot的tftp命令就能直接下载,非常方便。
2.3.2 NFS服务搭建
NFS(Network File System)让板子通过网络挂载PC上的目录,这样板子就能直接运行PC上的文件系统,不用每次修改都重新烧录。
安装NFS服务器:
sudo apt install nfs-kernel-server
配置NFS导出目录:
编辑/etc/exports文件,添加:
/nfsroot *(rw,sync,no_subtree_check,no_root_squash)
创建NFS根目录:
sudo mkdir /nfsroot
sudo chmod 777 /nfsroot
重启NFS服务:
sudo systemctl restart nfs-kernel-server
注意: no_root_squash这个选项很重要。如果不加,板子上的root用户会被映射成nobody,导致很多操作权限不足。我曾经因为这个,调试驱动时发现设备节点创建不了,查了半天才发现是NFS权限问题。
2.4 环境验证
搭建完所有服务后,最好做个整体验证,确保每个环节都通。
2.4.1 验证TFTP
在/tftpboot下放个测试文件,然后在板子的uboot中执行:
tftp 0x80800000 test.txt
如果能成功下载,说明TFTP正常。
2.4.2 验证NFS
在板子的Linux系统中执行:
mount -t nfs -o nolock 192.168.1.100:/nfsroot /mnt
如果挂载成功,/mnt下能看到PC上/nfsroot目录的内容。
2.5 本章小结
环境搭建看起来步骤多,但做一遍之后后面就一劳永逸了。我个人习惯把虚拟机、工具链、TFTP、NFS的配置写成脚本,换电脑时直接跑一遍就行。
嗯,这里要注意:虚拟机的网络模式一定要和板子在同一个网段。我一般用桥接模式,让虚拟机和板子都连到路由器上,这样通信最稳定。
核心要点:
- Ubuntu虚拟机建议20.04/22.04 LTS,内存8GB+
- 交叉编译工具链用Linaro 7.x/8.x,注意架构匹配
- TFTP用于传输内核和设备树,NFS用于挂载文件系统
- 所有服务搭建完成后务必做整体验证