4. 主机环境准备:三大服务器的搭建与配置
好,咱们开始动手搭建主机环境。这部分我称之为「基础设施三件套」——TFTP、NFS、DHCP。少了任何一个,网络启动都跑不起来。我个人习惯先把这三个服务装好、配通,再回头调试U-Boot,这样能少走很多弯路。
核心思路:TFTP传内核和设备树,NFS挂载根文件系统,DHCP给开发板自动分配IP。三者配合,才能实现一键网络启动。
4.1 TFTP服务器搭建(tftp-hpa)
TFTP这玩意儿,说白了就是个简化版的FTP。它没有认证,没有目录列表,但胜在轻量、快速。U-Boot用它来下载内核镜像和设备树文件。
安装与配置
# 安装tftp-hpa服务器和客户端(用于测试)
sudo apt-get update
sudo apt-get install tftp-hpa tftpd-hpa -y
安装完成后,配置文件在 /etc/default/tftpd-hpa。我个人习惯把TFTP根目录设在 /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"
嗯,这里要注意 --secure 参数。它限制了TFTP只能访问根目录下的文件,不能往上翻。安全第一嘛。
# 创建根目录并设置权限
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
# 重启服务
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa
验证小技巧:在TFTP根目录下放一个测试文件,然后用本地回环地址测试:
echo "Hello TFTP" | sudo tee /srv/tftp/test.txt
tftp localhost -c get test.txt
cat test.txt
如果能读到内容,说明服务正常。
我曾经踩过的坑:防火墙没关!Ubuntu默认的ufw会拦截UDP 69端口。如果你发现开发板一直timeout,先检查:sudo ufw status。我建议直接关掉防火墙做测试:sudo ufw disable。
4.2 NFS服务器搭建(nfs-kernel-server)
NFS的作用是让开发板通过网络挂载根文件系统。这样你修改了文件系统内容,开发板重启就能生效,不用反复烧写Flash。我在项目中经常这么干,调试效率翻倍。
安装与配置
# 安装NFS服务器
sudo apt-get install nfs-kernel-server -y
配置文件是 /etc/exports。这里要指定共享目录和访问权限。
# 编辑exports文件
sudo vim /etc/exports
# 添加以下内容(假设根文件系统在/srv/nfs/rootfs)
/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
解释一下这几个参数:
rw:读写权限sync:同步写入,数据更安全no_subtree_check:禁用子树检查,提升性能no_root_squash:允许客户端以root身份操作,这个很关键
为什么必须用no_root_squash?因为U-Boot启动后,内核会以root身份挂载NFS。如果不加这个参数,开发板上的root用户会被映射成nobody,导致各种权限问题。我刚开始学的时候就被这个坑过,折腾了一下午。
# 创建根文件系统目录(先随便放个文件测试)
sudo mkdir -p /srv/nfs/rootfs
echo "NFS Test" | sudo tee /srv/nfs/rootfs/test.txt
# 导出并重启服务
sudo exportfs -a
sudo systemctl restart nfs-kernel-server
sudo systemctl enable nfs-kernel-server
验证方法:在本地挂载测试。
sudo mount -t nfs localhost:/srv/nfs/rootfs /mnt
cat /mnt/test.txt
sudo umount /mnt
4.3 DHCP服务器搭建(isc-dhcp-server)
DHCP负责给开发板自动分配IP地址。你想想看,如果每次都要手动设置IP,那多麻烦。DHCP还能顺便告诉开发板TFTP服务器的地址和要下载的文件名,一举两得。
安装与配置
# 安装DHCP服务器
sudo apt-get install isc-dhcp-server -y
主配置文件是 /etc/dhcp/dhcpd.conf。这里要配置子网、地址池,以及TFTP相关的选项。
# 编辑配置文件
sudo vim /etc/dhcp/dhcpd.conf
# 内容如下:
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.100 192.168.1.200;
option routers 192.168.1.1;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
# TFTP服务器地址(就是你的主机IP)
next-server 192.168.1.10;
# 要下载的文件名(U-Boot会用到)
filename "u-boot.bin";
# 默认租约时间
default-lease-time 600;
max-lease-time 7200;
}
关于网卡接口:你需要告诉DHCP服务器监听哪个网卡。编辑 /etc/default/isc-dhcp-server:
# 找到这一行,改成你的网卡名(比如eth0)
INTERFACESv4="eth0"
# 重启服务
sudo systemctl restart isc-dhcp-server
sudo systemctl enable isc-dhcp-server
我曾经遇到的典型问题:DHCP服务启动失败,提示 subnet mismatch。原因是我主机的IP地址不在配置的子网范围内。解决办法:先把主机IP改成静态的,比如 192.168.1.10/24,再重启DHCP服务。
4.4 整体验证流程
三个服务都搭好后,我建议做个快速联调。把开发板用网线连到主机,上电看串口输出。如果看到类似这样的信息,说明环境OK:
BOOTP broadcast 1
DHCP client bound to address 192.168.1.100
Using ethernet device
TFTP from server 192.168.1.10; our IP address is 192.168.1.100
Filename 'u-boot.bin'.
Load address: 0x82000000
Loading: #################################################################
done
Bytes transferred = 512000 (7d000 hex)
嗯,看到这个输出,说明TFTP和DHCP已经通了。NFS的验证要等到内核启动后,挂载根文件系统时才能看到效果。
我的个人建议:别急着一次配完三个服务。先配TFTP,用U-Boot的 tftp 命令测试下载。通了再配DHCP,最后配NFS。分步验证,出问题好定位。
这张图把整个流程串起来了。开发板上电后,先通过DHCP拿到IP地址和TFTP服务器信息,然后从TFTP下载U-Boot或内核,最后通过NFS挂载根文件系统。三个服务各司其职,缺一不可。
快速检查清单:
- ✅ TFTP服务运行中?
systemctl status tftpd-hpa - ✅ NFS导出正确?
showmount -e localhost - ✅ DHCP监听正确网卡?
journalctl -u isc-dhcp-server | tail - ✅ 主机IP和DHCP配置在同一子网?
- ✅ 防火墙已关闭或放行了相关端口?
好了,主机环境准备就绪。这三个服务配好之后,你就可以开始玩U-Boot的网络启动了。记住,遇到问题别慌,先检查服务状态,再看网络连通性,最后看配置文件。大部分问题都出在这三个环节上。