1. PXE网络启动基础:协议栈架构与交互流程
PXE这东西,说白了就是让一台裸机通过网络把操作系统拉起来。我最早接触它是在做无盘工作站项目的时候,那时候机房几十台机器都没硬盘,全靠PXE启动。嗯,今天咱们就把它的底裤扒干净。
1.1 PXE协议栈长什么样?
PXE不是单一协议,它是几个协议的组合拳。我习惯把它分成三层来看:
- 底层:UDP/IP — 无连接传输,快但不靠谱
- 中间层:DHCP — 拿IP地址和启动参数
- 应用层:TFTP — 下载启动文件
你想想看,一台刚通电的机器,没有操作系统,没有IP地址,怎么跟网络通信?PXE固件(写在网卡的Option ROM里)硬编码了一套最小化的UDP协议栈。它不需要完整的TCP/IP,因为TFTP和DHCP都跑在UDP上。
关键点:PXE客户端只支持UDP,不支持TCP。这意味着所有传输都得靠UDP的简单机制,丢包重传由TFTP自己搞定。
我在项目中遇到过一个问题:某些UEFI网卡默认关闭了PXE Option ROM,导致机器死活起不来。后来进BIOS把"Network Stack"打开才解决。嗯,这坑我踩过。
1.2 DHCP交互流程 — 不只是拿IP
PXE的DHCP跟普通DHCP不太一样。普通DHCP只给你IP地址、网关、DNS。PXE的DHCP还要告诉你:TFTP服务器在哪、启动文件名是什么。
具体流程分四个阶段:
- DHCP Discover(广播) — 客户端喊:"谁给我个IP?顺便告诉我启动服务器在哪!"
- DHCP Offer(单播/广播) — 服务器回应,里面带Option 54(Server Identifier)和Option 60(Class Identifier,标记这是PXE客户端)
- DHCP Request(广播) — 客户端说:"就你了,给我配置吧。"
- DHCP Ack(单播) — 服务器确认,同时塞入Option 66(TFTP服务器地址)和Option 67(启动文件名)
个人习惯:我一般会在DHCP服务器上把Option 66和67写死,而不是依赖Proxy DHCP。因为Proxy DHCP多一次交互,容易出兼容性问题。
这里有个容易翻车的地方:如果DHCP服务器返回的Option 67是相对路径(比如"boot/pxelinux.0"),PXE客户端会把它拼接到TFTP根目录后面。我曾经因为路径写错,折腾了一下午。
1.3 TFTP传输 — 慢但可靠
TFTP是PXE的传输主力。它没有认证,没有加密,纯靠UDP加ACK确认。每次传输固定512字节的数据块,收到ACK才发下一块。
TFTP的传输模式:
| 模式 | 说明 | 典型用途 |
|---|---|---|
| octet | 二进制模式,逐字节传输 | 内核、initrd、引导加载器 |
| netascii | 文本模式,自动转换换行符 | 配置文件(极少用) |
我建议你只用octet模式。netascii模式在跨平台时会把换行符搞乱,我吃过这个亏。
警告:TFTP默认端口是69,但数据端口是动态协商的。防火墙如果只开放69端口,数据包会被拦截。我建议开放UDP 1024-65535,或者用tftp-hpa的--port-range参数限制端口范围。
1.4 启动文件加载顺序
PXE客户端拿到TFTP服务器地址和启动文件名后,就开始下载文件了。但具体下载哪个文件,取决于固件类型和配置。
典型的加载顺序(以BIOS/Legacy模式为例):
- pxelinux.0 — 第一阶段引导加载器,由syslinux提供
- ldlinux.c32 — pxelinux.0的库文件,必须跟pxelinux.0在同一目录
- pxelinux.cfg/default — 配置文件,决定启动哪个内核
- vmlinuz — Linux内核
- initrd.img — 初始根文件系统
如果是UEFI模式,文件名会变成:
- bootx64.efi(x86_64架构)
- bootia32.efi(IA32架构)
- 或者自定义的grubx64.efi
为什么会这样?因为UEFI固件只认EFI可执行文件,不认pxelinux.0这种DOS时代的引导器。
下面这张图把整个流程串起来了:
1.5 实际项目中的避坑指南
讲几个我踩过的坑,你遇到了能少走弯路:
坑1:TFTP传输超时
我曾经在跨网段部署PXE时,TFTP传输到一半就断了。原因是TFTP的UDP包被三层交换机拦截了。解决方案:在DHCP的Option 66里填TFTP服务器的实际IP,不要填网关IP。另外,tftp-hpa的--timeout参数可以调大重试间隔。
坑2:启动文件名大小写
TFTP服务器(特别是tftpd-hpa)默认区分大小写。我遇到过把"pxelinux.0"写成"Pxelinux.0"导致404的情况。建议统一用小写,并在DHCP配置里写绝对路径。
调试技巧:在DHCP服务器上开启日志(journalctl -u isc-dhcp-server -f),可以看到客户端请求的Option 60和67。如果客户端没发Option 60,说明PXE固件没启用。这时候去BIOS里找"Network Boot"或"UEFI Network Stack"。
1.6 小结
PXE启动的核心就三件事:拿IP、拿文件名、拿文件。DHCP负责前两件,TFTP负责最后一件。启动文件的加载顺序是链式的:先下载引导器,引导器再下载配置文件,配置文件告诉它下载哪个内核和initrd。