Linux网络引导服务器搭建:DHCP、TFTP、NFS服务配置与嵌入式开发实践
1. 项目概述与核心价值
如果你正在折腾嵌入式开发板,比如Freescale(现NXP)的Sandpoint或MVP评估板,或者管理着一批无盘工作站,那么“网络引导”这个技术你一定绕不开。简单来说,就是让设备一开机,就能通过网络从一台服务器上把整个操作系统“拉”下来运行,本地连硬盘都不需要。这听起来很酷,但真动手配置起来,尤其是要协调好DHCP、TFTP、NFS这几个服务,让它们像精密齿轮一样咬合,新手很容易就卡在某个环节,对着启动失败的板子干瞪眼。
我最近就为了给几块老旧的Sandpoint和MVP板子搭建一个统一的开发和测试环境,重新梳理了一遍在Linux上构建NFS DHCP/BOOTP服务器的全过程。这不仅仅是把几个服务装好那么简单,关键在于理解它们之间如何协同工作,以及在不同发行版(如Red Hat 7.2、Mandrake 7.0)和特定开发环境(MontaVista CDK)下的细微差别。网上很多教程要么过于简略,要么版本太老不适用,踩坑几乎是必然的。本文将基于我的实操经验,为你拆解从零开始构建这样一个服务器的每一个步骤,重点解释“为什么”要这么做,并分享那些官方文档里不会写的避坑技巧。无论你是嵌入式开发者、系统管理员,还是对网络引导技术感兴趣的极客,这篇指南都能帮你少走弯路。
2. 网络引导的核心原理与流程拆解
在动手配置之前,我们必须先搞清楚客户端设备从按下电源键到最终进入系统,到底和服务器之间发生了哪些“对话”。这个过程环环相扣,任何一个环节出错都会导致引导失败。
2.1 引导过程的四步握手协议
整个网络引导过程可以看作客户端与服务器之间的一次精密握手,主要分为四个阶段:
发现与寻址(DHCP/BOOTP):客户端上电后,其引导程序(通常是U-Boot或类似固件)会初始化网络接口,然后向整个子网广播一个BOOTP/DHCP Discover报文。这个报文中最重要的信息就是客户端网卡的MAC地址。服务器上的
dhcpd守护进程一直在监听网络,一旦收到这个广播,就会检查自己的配置(/etc/dhcpd.conf),看这个MAC地址是否在已知的合法客户端列表中。提供与确认(DHCP Offer/ACK):如果MAC地址合法,服务器会通过DHCP Offer报文回应,其中包含了为客户端分配的IP地址、子网掩码、网关等信息。客户端接受后,服务器发送DHCP ACK进行最终确认。至此,客户端获得了在网络中通信的“身份证”(IP地址)。
引导文件传输(TFTP):获得IP地址后,客户端会向服务器请求引导文件(如
vmlinuz-freescale-sandpoint,即内核镜像)。这个文件的路径是在上一步的DHCP响应中通过filename参数指定的。传输使用TFTP协议,这是一种基于UDP的简单文件传输协议,没有认证和复杂交互,专为引导这种轻量级任务设计。服务器上的tftpd服务负责响应这个请求,将指定的内核文件发送给客户端。根文件系统挂载(NFS):客户端将收到的内核加载到内存并启动。内核启动后,需要挂载根文件系统(
/)。它同样根据DHCP响应中的root-path参数(例如/opt/hardhat/devkit/ppc/82xx/target),知道根文件系统位于服务器的哪个目录下。随后,内核通过NFS协议,将这个远程目录挂载为自己的根文件系统。从此,客户端的所有文件操作(读取库文件、写入日志等)实际上都通过网络发生在服务器的这个目录中。
关键理解:DHCP负责“定位”(分配IP和告知文件路径),TFTP负责“送钥匙”(传输内核),NFS负责“提供房间”(提供完整的运行环境)。三者缺一不可,且配置必须严格对应。
2.2 为何选择此方案:优势与适用场景
为什么我们要不厌其烦地配置这套略显复杂的系统?因为它解决了几个核心痛点:
- 集中化管理与快速部署:所有系统的内核和根文件系统都存放在服务器上。要更新系统、调试程序或修复漏洞,你只需要在服务器端操作一次,所有网络引导的客户端在下次重启时都会自动生效。这对于需要管理数十上百台嵌入式设备或实验室无盘机的场景,效率提升是颠覆性的。
- 节省客户端存储成本与复杂度:客户端无需配置硬盘、Flash等本地存储介质,降低了硬件成本和功耗,也避免了存储设备损坏带来的风险。对于Sandpoint这类评估板,尤其方便。
- 便于开发与调试:在嵌入式开发中,开发者可以在服务器上直接编译和修改文件,客户端能立即使用新版本,极大加快了编译-测试的迭代循环。配合NFS的读写属性,调试日志也能直接写入服务器,方便查看。
- 环境一致性:确保所有客户端运行完全一致的系统环境,避免了因本地存储差异导致的问题。
3. 服务器环境准备与工具链部署
工欲善其事,必先利其器。服务器的稳定性和工具链的完整性是后续所有工作的基础。这里我以当时主流的Red Hat Linux 7.2环境为例,但会穿插说明其他发行版的关键差异。
3.1 操作系统与基础服务确认
首先,确保你的服务器已经安装了一个干净的Linux系统。我强烈建议使用Red Hat 7.2或Mandrake 7.0,因为它们在后续与MontaVista CDK的兼容性上表现最好。根据原始文档的提示,Yellow Dog Linux作为主机时,搭配MontaVista的Journeyman版本可能会导致根文件系统以只读方式挂载,影响使用,需特别注意。
安装系统后,你需要检查或安装以下核心RPM包:
- DHCP服务器:
dhcp-2.0pl5-8.i386.rpm(或更高兼容版本)。这是提供动态IP分配的核心。 - 超级守护进程:这取决于你的发行版。
- Red Hat 7.2 / Yellow Dog 2.1:使用
xinetd。需要安装xinetd-2.3.3-1.i386.rpm。xinetd是inetd的增强版,提供更细粒度的服务管理。 - Mandrake 7.0 / Red Hat 7.0:使用传统的
inetd。通常对应的包是netkit-base或类似。
- Red Hat 7.2 / Yellow Dog 2.1:使用
- TFTP客户端与服务器:
tftp和tftp-server包。TFTP服务将由xinetd或inetd管理。
你可以使用rpm -qa | grep -E “dhcp|xinetd|tftp”来检查这些包是否已安装。
3.2 MontaVista CDK 2.0的安装与“变通”
MontaVista CDK(Cross Development Kit)是用于为PowerPC架构(如Sandpoint、MVP板子使用的处理器)交叉编译Linux内核和工具链的环境。它是我们构建目标系统内核和根文件系统的基石。
获取与挂载:从MontaVista官网获取CDK 2.0的ISO,将其刻录成光盘或挂载为ISO文件。
执行安装脚本:关键的一步是运行安装脚本。文档中提到的脚本路径是
/mnt/cdrom/bin/hhl-host-install。这里有一个经典大坑:这个脚本内部会检查/etc/redhat-release文件,如果发现不是Red Hat 7.0,它可能会拒绝安装或报错。临时“伪装”系统版本:为了解决这个问题,我们需要一个临时变通方案。在安装前,备份并编辑
/etc/redhat-release文件:cp /etc/redhat-release /etc/redhat-release.backup echo “Red Hat Linux release 7.0 (Enigma)” > /etc/redhat-release执行这个操作后,再运行安装命令:
/mnt/cdrom/bin/hhl-host-install --install --lsp freescale-sandpoint-82xx重要提示:安装完成后,务必将
/etc/redhat-release文件恢复原状,以免影响系统其他功能的判断。cp /etc/redhat-release.backup /etc/redhat-release实操心得:这个“伪装”方法在Red Hat 7.2和Mandrake 7.0上亲测有效。在Yellow Dog上安装时可能会遇到一些非致命错误,可以忽略,但需接受根文件系统可能只读的风险。最稳妥的方案还是使用官方明确支持的Red Hat 7.2。
目录结构解析:安装成功后,关键目录如下:
/opt/hardhat/devkit/ppc/82xx/target/:这是目标板的根文件系统。后续NFS服务就是将这个目录共享出去。里面的boot/子目录存放着内核镜像。/opt/hardhat/devkit/ppc/82xx/bin/:交叉编译工具链(如ppc_82xx-gcc),用于在x86主机上编译生成PowerPC的可执行文件。/opt/hardhat/devkit/lsp/freescale-sandpoint/linux-2.4.2_hhl20/:内核源代码目录,你需要在这里根据目标板配置和编译内核。/opt/hardhat/host/bin/zsrec:一个将ELF格式文件转换为S-record格式的工具,方便通过串口等下载到板载Flash。
4. DHCP服务器配置详解
DHCP配置是网络引导的“总调度中心”,任何错误都会导致客户端无法获取IP或得到错误的引导信息。
4.1 配置文件 dhcpd.conf 的编写
首先,确保DHCP的租约文件存在。对于Red Hat 7.x,执行:
touch /var/lib/dhcp/dhcpd.leases对于更老的6.x系统,路径可能是/var/state/dhcp/dhcpd.leases。
接下来是重头戏:编辑/etc/dhcpd.conf。请务必使用你自己网络的真实参数替换下面的示例IP和MAC地址!
# 允许响应BOOTP请求(老式网络引导协议,DHCP兼容) allow bootp; # 定义服务器所在的子网和掩码 subnet 192.168.1.0 netmask 255.255.255.0 { # 指定该子网的网关(路由器)地址 option routers 192.168.1.1; # 指定DNS服务器地址(非必须,但建议设置) option domain-name-servers 192.168.1.1; # 定义一个客户端组 group { # 第一个客户端:Sandpoint板(使用Realtek PCI网卡) host sandpoint-board { # 客户端的以太网MAC地址,必须准确填写 hardware ethernet 00:0c:29:xx:xx:xx; # 请替换为你的Sandpoint板网卡MAC # 为该客户端静态分配的IP地址 fixed-address 192.168.1.100; # 客户端通过TFTP下载的引导文件名 filename “vmlinuz-freescale-sandpoint”; # 客户端NFS挂载的根文件系统路径 option root-path “/opt/hardhat/devkit/ppc/82xx/target”; } # 第二个客户端:MVP板(集成Galileo网卡) host mvp-board { hardware ethernet 00:90:27:xx:xx:xx; # 请替换为你的MVP板网卡MAC fixed-address 192.168.1.101; filename “vmlinuz-freescale-sandpoint”; # 假设使用相同内核 option root-path “/opt/hardhat/devkit/ppc/82xx/target”; } } }4.2 关键参数解析与避坑指南
allow bootp;:这是必须的。因为很多嵌入式引导ROM(包括Sandpoint/MVP常用的)最初发送的是BOOTP请求。没有这一行,DHCP服务器会忽略这些请求。subnet和netmask:必须与服务器自身网络接口(如eth0)的配置在同一网段。你可以用ifconfig命令查看服务器的IP和掩码。hardware ethernet:这是唯一标识客户端的钥匙。获取方法:在目标板的U-Boot命令行下,通常有printenv或类似命令可以查看ethaddr变量。务必核对无误,一个字符错误都会导致分配失败。fixed-address:建议为开发板分配静态IP,便于后续调试和访问。确保IP地址不在你网络DHCP服务器的动态分配池中,避免冲突。filename:这个文件名是相对于TFTP根目录的。在我们的配置中,TFTP根目录是/tftpboot,所以服务器会在/tftpboot/vmlinuz-freescale-sandpoint寻找这个文件。我们后面会创建符号链接。option root-path:这是NFS服务器的本地路径,不是URL。客户端会尝试挂载server_ip:/opt/hardhat/devkit/ppc/82xx/target。确保这个路径存在且包含完整的根文件系统。
严重警告:一个子网内绝对不能有多个活跃的DHCP服务器,否则会造成IP地址分配混乱,导致网络瘫痪。在配置前,请确认你的路由器或网络中没有其他DHCP服务在运行。
4.3 启动与测试DHCP服务
配置完成后,重启DHCP服务以加载新配置:
service dhcpd restart # 或 /etc/rc.d/init.d/dhcpd restart成功的输出应该是:
Shutting down dhcpd: [ OK ] Starting dhcpd: [ OK ]你可以通过netstat -anu | grep :67检查DHCP服务器(监听67端口)是否已运行。更直接的测试是,启动你的客户端开发板,在服务器的/var/log/messages日志文件中,你应该能看到类似dhcpd: DHCPDISCOVER from xx:xx:xx:xx:xx:xx via eth0和dhcpd: DHCPOFFER on 192.168.1.100 to xx:xx:xx:xx:xx:xx via eth0的记录,这表明服务器收到了请求并进行了响应。
5. TFTP服务配置与内核链接
TFTP服务负责传输那个小小的内核文件。它的配置相对简单,但权限和路径问题常常是隐形的杀手。
5.1 配置TFTP服务器
TFTP服务通常由xinetd或inetd这个“超级守护进程”管理。你需要根据发行版编辑不同的配置文件。
对于 Red Hat 7.2 / Yellow Dog 2.1 (使用 xinetd):
- 编辑或创建文件
/etc/xinetd.d/tftp。 - 输入以下内容:
service tftp { socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /tftpboot disable = no }server_args = -s /tftpboot:-s参数指定了TFTP的安全根目录。客户端只能访问/tftpboot目录及其下的文件,无法向上回溯,这是一个重要的安全限制。/tftpboot就是TFTP服务的根目录。
对于 Mandrake 7.0 / Red Hat 7.0 (使用 inetd):
- 编辑
/etc/inetd.conf。 - 找到以
tftp开头的行,去掉行首的注释符#。它看起来应该像这样:
注意,这里直接跟了目录tftp dgram udp wait root /usr/sbin/tcpd in.tftpd /tftpboot/tftpboot,没有-s参数,但效果类似。
5.2 创建TFTP根目录与内核符号链接
创建TFTP根目录并设置权限:
mkdir -p /tftpboot chmod 755 /tftpboot chown nobody:nobody /tftpboot # 许多TFTP服务以nobody身份运行,确保其有读权限注意事项:权限设置不当是TFTP传输失败的常见原因。确保
/tftpboot目录对TFTP进程的运行用户(通常是nobody或root)是可读的。创建内核文件的符号链接:DHCP配置中指定的
filename是vmlinuz-freescale-sandpoint。但MontaVista编译出的内核镜像实际路径可能在/opt/hardhat/devkit/ppc/82xx/target/boot/下,并且名字可能略有不同(如带版本号)。我们不需要复制文件,创建一个符号链接即可。cd /tftpboot ln -sf /opt/hardhat/devkit/ppc/82xx/target/boot/vmlinuz-freescale-sandpoint-2.4.2 vmlinuz-freescale-sandpointln -sf中的s代表软链接,f代表强制创建。这样,无论实际内核文件叫什么,在TFTP世界里,它都被统一为vmlinuz-freescale-sandpoint。验证链接:执行
ls -l /tftpboot/,你应该能看到类似输出:lrwxrwxrwx 1 root root 67 Mar 10 10:00 vmlinuz-freescale-sandpoint -> /opt/hardhat/devkit/ppc/82xx/target/boot/vmlinuz-freescale-sandpoint-2.4.2
5.3 重启TFTP服务
- 对于 xinetd 系统:
service xinetd restart或killall -HUP xinetd - 对于 inetd 系统:
killall -HUP inetd或/etc/rc.d/init.d/inet restart
重启后,你可以用本地TFTP客户端测试一下服务是否正常:
cd /tmp tftp localhost tftp> get vmlinuz-freescale-sandpoint tftp> quit ls -lh vmlinuz-freescale-sandpoint如果能看到下载下来的文件(虽然是个链接,但获取的是实际内容),说明TFTP服务配置成功。
6. NFS服务器配置与导出设置
NFS让客户端能把服务器上的一个目录当成自己的硬盘来用。配置的核心是/etc/exports文件,它定义了哪些目录可以共享给哪些客户端,以及以什么权限共享。
6.1 配置 /etc/exports 文件
编辑/etc/exports文件,添加如下行:
/opt/hardhat/devkit/ppc/82xx/target 192.168.1.100(rw,sync,no_root_squash,no_subtree_check) 192.168.1.101(rw,sync,no_root_squash,no_subtree_check)让我们分解一下这个配置:
/opt/hardhat/devkit/ppc/82xx/target:这是要共享的服务器本地路径,即我们的目标根文件系统。192.168.1.100和192.168.1.101:这是允许访问的客户端IP地址。我们使用了DHCP中分配的静态IP。你也可以使用通配符如192.168.1.*,但基于IP的限制更安全。rw:以读写权限共享。这是至关重要的,如果这里是ro(只读),客户端启动后无法创建临时文件、写入日志,很多服务会失败。sync:同步写入。确保数据在回复客户端之前已写入磁盘,更安全。no_root_squash:这是嵌入式网络引导的关键选项。它禁止将客户端的root用户映射为服务器上的匿名用户(通常是nobody)。如果启用root_squash,客户端root用户对NFS共享目录的操作权限会被严重限制,导致系统无法正常启动或运行。no_subtree_check:禁用子树检查,可以提高性能,在导出整个目录时推荐使用。
6.2 启动NFS服务并验证
- 使导出生效:运行
exportfs -ra。这个命令会重新读取/etc/exports文件,使更改立即生效,无需重启服务。 - 启动NFS服务(如果尚未运行):
service nfs start # 并设置开机自启 chkconfig nfs on - 验证导出:运行
showmount -e localhost。你应该能看到:
这表明NFS共享已经正确配置。Export list for localhost: /opt/hardhat/devkit/ppc/82xx/target 192.168.1.100,192.168.1.101
6.3 NFS配置的深度解析与安全考量
- 为什么需要
no_root_squash?在常规NFS共享中,出于安全考虑,默认会将客户端的root用户请求“压扁”(squash)成服务器上的一个普通用户(如nfsnobody)。但对于网络引导的根文件系统,客户端内核需要以root身份在根文件系统上创建设备节点(如/dev/console)、写入/var/run下的PID文件、修改某些配置文件等。如果root权限被压扁,这些操作都会因权限不足而失败,导致系统启动异常。 - 安全警告:
no_root_squash是一个潜在的安全风险,因为它允许网络上的指定IP地址以root身份访问服务器上的共享目录。务必确保只将共享目录导出给可信的、特定的IP地址(如你的开发板),并且该目录不包含服务器本身的敏感数据。在我们的配置中,我们精确指定了Sandpoint和MVP板的IP地址,这比使用网段通配符要安全得多。 - 防火墙:确保服务器的防火墙(如果启用)放行了NFS相关端口(如2049)以及RPC端口(如111)。在简单的开发环境中,可以暂时关闭防火墙进行测试:
service iptables stop(生产环境请谨慎操作)。
7. 客户端引导配置与问题排查实录
服务器端配置完毕,现在焦点转向客户端——我们的Sandpoint或MVP评估板。
7.1 目标板引导环境设置
大多数PowerPC评估板使用U-Boot作为引导加载程序。你需要通过串口连接到板子的U-Boot命令行,设置以下环境变量:
# 设置板子自身的IP地址(应与DHCP分配的固定地址一致,但也可由DHCP分配) setenv ipaddr 192.168.1.100 # 设置服务器IP地址 setenv serverip 192.168.1.50 # 假设你的服务器IP是192.168.1.50 # 设置引导文件名,必须与DHCP配置中的filename及TFTP下的文件名完全一致 setenv bootfile vmlinuz-freescale-sandpoint # 设置NFS根路径,格式为 ‘服务器IP:导出路径’ setenv nfsroot /opt/hardhat/devkit/ppc/82xx/target # 定义网络引导命令 # 1. dhcp: 通过DHCP获取IP、serverip、bootfile等参数(覆盖手动设置) # 2. tftp: 从tftp服务器加载内核镜像到内存地址0x1000000 # 3. bootm: 从内存地址0x1000000启动内核,并传递内核命令行参数 # 参数说明:root=/dev/nfs 表示根设备为NFS # nfsroot=${serverip}:${nfsroot} 指定NFS服务器和路径 # ip=${ipaddr}:${serverip}::255.255.255.0::eth0:off 配置网络 setenv netboot ‘dhcp; tftp 0x1000000 ${bootfile}; bootm 0x1000000’ # 将netboot设置为默认引导命令 setenv bootcmd run netboot # 保存环境变量到持久化存储(如Flash) saveenv设置完成后,重启板子或执行run netboot,引导过程就开始了。
7.2 常见问题与排查技巧实录
即使按照步骤操作,第一次成功引导也常常伴随着各种错误。下面是我在实战中遇到的一些典型问题及解决方法:
问题1:客户端卡在“TFTP from server...”或“Loading: T T T T T”
- 现象:U-Boot开始TFTP传输,但进度点(.)变成了一系列T,然后超时。
- 排查:
- 服务器防火墙:这是最常见的原因。在服务器上执行
service iptables stop临时关闭防火墙测试。 - TFTP目录权限:确认
/tftpboot目录及其下的内核文件(或链接)对TFTP进程用户(如nobody)有读权限。可以尝试chmod -R 755 /tftpboot。 - SELinux(仅限Red Hat/CentOS新版本):SELinux可能会阻止TFTP访问。可以临时设置为宽容模式测试:
setenforce 0。 - 路径与文件名:在服务器上执行
tftp localhost,然后get vmlinuz-freescale-sandpoint,看能否成功。确保U-Boot中的bootfile变量、DHCP中的filename、TFTP根目录下的文件名三者完全一致,包括大小写。
- 服务器防火墙:这是最常见的原因。在服务器上执行
问题2:内核启动后卡在“VFS: Unable to mount root fs”或“Kernel panic”
- 现象:内核开始解压并启动,但最后报错无法挂载根文件系统。
- 排查:
- NFS导出路径:检查
/etc/exports文件,确保路径正确,且客户端IP已被授权。运行showmount -e确认。 - NFS服务状态:确保
nfs和portmap(或rpcbind)服务都在运行。 - 内核NFS支持:你为开发板编译的内核必须包含NFS客户端支持(
CONFIG_ROOT_NFS=y)以及对应的网络驱动和文件系统驱动。这需要在编译内核时通过make menuconfig确认。 - 内核命令行参数:仔细检查U-Boot传递给内核的
root=和nfsroot=参数。可以在U-Boot中使用printenv查看bootargs,或在Linux内核启动早期按任意键查看启动参数。确保IP地址、路径没有拼写错误。 - 服务器防火墙(再次):NFS使用多个端口,防火墙可能阻止。测试时关闭防火墙。
- NFS导出路径:检查
问题3:系统启动后根文件系统为只读(Read-only file system)
- 现象:系统能启动,但无法创建或删除文件,
mount命令显示根文件系统挂载为ro。 - 排查:
- /etc/exports 选项:这是最可能的原因。确认共享选项包含
rw(读写),而不是ro(只读)。 - 文件系统权限:虽然设置了
no_root_squash,但请确认服务器上/opt/hardhat/devkit/ppc/82xx/target目录本身的权限允许写入。可以尝试chmod -R 755(对目录)和chmod -R 644(对文件)进行标准化,但注意不要破坏某些特殊文件(如设备节点/dev/console)的权限。 - 内核配置:确保内核编译时包含了对应文件系统(如ext2/ext3)的读写支持。
- /etc/exports 选项:这是最可能的原因。确认共享选项包含
问题4:DHCP请求无响应,客户端使用默认IP或169.254.x.x
- 现象:客户端没有获得我们配置的固定IP。
- 排查:
- MAC地址错误:反复核对
/etc/dhcpd.conf中的hardware ethernet与开发板实际的MAC地址。一个字母或数字的错误都会导致匹配失败。 - 多DHCP服务器冲突:用
ps aux | grep dhcpd检查服务器上是否只有一个dhcpd进程。同时检查网络中路由器是否也开启了DHCP功能,将其关闭或配置为排除你为开发板预留的IP段。 - DHCP服务未监听正确网卡:如果服务器有多个网卡(如
eth0,eth1),dhcpd可能绑定在了错误的接口上。可以在/etc/sysconfig/dhcpd(或类似位置)中添加DHCPDARGS=eth0来指定网卡,然后重启服务。
- MAC地址错误:反复核对
问题5:系统启动后网络不通
- 现象:能挂载NFS根文件系统,但无法
ping通网关或其他机器。 - 排查:
- 内核命令行网络参数:检查U-Boot传递给内核的
ip=参数。格式非常关键:ip=<客户端IP>:<服务器IP>:<网关IP>:<子网掩码>:<主机名>:<网卡>:<自动配置>。例如ip=192.168.1.100:192.168.1.50:192.168.1.1:255.255.255.0::eth0:off。确保网关和掩码正确。 - 服务器路由:在服务器上,确保到客户端子网的路由是通的。
- 内核命令行网络参数:检查U-Boot传递给内核的
7.3 诊断工具与日志查看
- 服务器端日志:
/var/log/messages(或/var/log/syslog)是首要查看点。在这里你可以看到dhcpd的分配记录、xinetd/inetd的TFTP连接记录、以及rpc.mountd的NFS挂载请求记录。使用tail -f /var/log/messages实时监控,然后在客户端启动,观察日志输出。 - 网络抓包:终极调试利器。在服务器上运行
tcpdump -i eth0 -n port 67 or port 68 or port 69 or port 2049,可以同时捕获DHCP(67/68)、TFTP(69)和NFS(2049)的流量,清晰看到每一步的请求和响应包,精准定位协议层面的问题。
构建一个稳定的NFS DHCP/BOOTP服务器确实需要耐心,需要你像侦探一样,根据现象在DHCP、TFTP、NFS、内核、U-Boot这几个环节中排查线索。但一旦配置成功,那种通过网络瞬间让一块“裸板”跑起完整系统的便捷性和高效性,会让你觉得所有的折腾都是值得的。这套环境不仅适用于文中的老款评估板,其原理和步骤对于任何支持网络引导的ARM、MIPS开发板,乃至x86的无盘工作站,都具有很高的参考价值。关键在于理解每个协议的作用和交互过程,然后根据具体的硬件和发行版进行适配。