4、PXE协议:PXE固件与BIOS/UEFI的关系、PXE启动流程

聊到网络启动,PXE协议是绕不开的核心。说白了,它就是一套让裸机通过网络加载操作系统的标准。我最早接触PXE是在一次机房批量部署的场景里,那时候一台台插U盘装系统,装到怀疑人生。后来用上PXE,效率直接翻了几倍。

今天咱们就把它拆开揉碎了讲清楚。重点看三个东西:PXE固件和BIOS/UEFI怎么配合、启动流程到底怎么走、以及UNDI和NBP这两个关键角色。

4.1 PXE固件与BIOS/UEFI的关系

先搞清楚一个概念。PXE本身不是一个独立的系统,它是嵌入在固件里的一层协议栈。你想想看,BIOS或者UEFI在初始化硬件之后,会去扫描可启动设备。如果启用了网络启动,固件就会加载PXE ROM里的代码。

这里有个细节。传统BIOS下,PXE ROM通常是一个Option ROM,大小有限,功能也比较简单。它通过INT 18h中断来触发网络启动。我遇到过一台老服务器,BIOS里的PXE ROM版本太旧,死活认不出新网卡。后来刷了固件才解决。

到了UEFI时代,情况就不一样了。UEFI本身就是一个微型操作系统,它内置了完整的网络协议栈。PXE在UEFI下是以UEFI驱动程序的形式存在的。它不再依赖实模式的中断调用,而是通过UEFI的协议接口来工作。

关键区别:
  • BIOS下的PXE:实模式,通过INT 18h调用,ROM空间有限
  • UEFI下的PXE:保护模式,通过UEFI协议接口,功能更完整

嗯,这里要注意。UEFI的PXE启动支持IPv6,而传统BIOS基本只支持IPv4。我在一个双栈网络环境里调试过,BIOS那端死活拿不到IPv6地址,换成UEFI就正常了。

4.2 PXE启动流程详解

整个流程其实就三步:拿IP、下文件、跑程序。但每一步里面都有不少门道。

4.2.1 DHCP获取IP地址

客户端开机后,网卡初始化完毕,PXE固件就开始干活了。它会广播一个DHCP Discover报文。这个报文和普通DHCP不一样,里面带了一个特殊的选项——Option 60(Vendor Class Identifier),值通常是"PXEClient"。服务器一看这个选项,就知道这是个PXE请求。

DHCP服务器回应的时候,除了分配IP地址,还必须带上几个关键信息:

  • Option 54:服务器标识
  • Option 66:TFTP服务器地址
  • Option 67:启动文件名(比如pxelinux.0)

我个人习惯把DHCP和TFTP分开部署。DHCP用Windows Server,TFTP用Linux。这样出问题好排查。有一次客户反映启动慢,我查了半天,发现是DHCP的Option 66配成了域名,DNS解析超时。改成IP地址后,速度立马上来了。

小技巧:如果DHCP服务器不支持Option 66/67,可以用dnsmasq或者isc-dhcp-server,它们对PXE支持很完善。

4.2.2 TFTP下载文件

拿到IP和启动文件名之后,PXE固件会通过TFTP去下载这个文件。TFTP协议很简单,基于UDP,端口69。它没有认证,没有加密,就是纯粹的传输。所以安全性嘛,你懂的。

这里有个坑。TFTP的传输效率不高,尤其是大文件。默认的块大小是512字节,虽然可以通过Option协商调大,但很多老设备不支持。我建议启动文件尽量控制在几MB以内。如果非要传大文件,可以考虑用HTTP Boot替代TFTP,UEFI是支持的。

# 一个典型的TFTP传输过程
客户端 -> 服务器: RRQ pxelinux.0
服务器 -> 客户端: DATA (块1, 512字节)
客户端 -> 服务器: ACK (块1)
服务器 -> 客户端: DATA (块2, 512字节)
客户端 -> 服务器: ACK (块2)
...
服务器 -> 客户端: DATA (最后一块, 小于512字节)
客户端 -> 服务器: ACK (最后一块)

我曾经在一个跨三层网络的场景里调试PXE,TFTP老是超时。后来发现是中间防火墙没开UDP 69端口的高端口回包。TFTP的数据端口是动态分配的,防火墙得允许UDP 1024以上端口才行。

4.2.3 执行引导程序

文件下载到内存后,PXE固件会跳转到这个文件的入口点执行。这个文件就是NBP(Network Bootstrap Program)。它可以是pxelinux.0、grub2的core.img、或者Windows的bootmgfw.efi。

NBP一旦跑起来,PXE固件的任务就基本结束了。后续的启动逻辑由NBP接管。比如pxelinux.0会去读取配置文件,然后根据配置去下载内核和initrd。整个过程就像接力赛,PXE是第一棒,NBP是第二棒。

注意:NBP必须和固件架构匹配。BIOS下用pxelinux.0,UEFI 32位用bootia32.efi,UEFI 64位用bootx64.efi。混用会导致启动失败。

4.3 UNDI与NBP的概念

这两个术语经常出现在PXE的文档里,但很多人搞不清楚它们的具体作用。

4.3.1 UNDI(Universal Network Device Interface)

UNDI是PXE协议栈的最底层。它直接和网卡硬件打交道,提供统一的接口给上层调用。说白了,它就是网卡的抽象层。不管你的网卡是Intel、Realtek还是Broadcom,只要实现了UNDI接口,PXE固件就能用统一的方式操作它。

UNDI分为两种:

  • 硬件UNDI:网卡厂商提供的固件实现,烧录在网卡的Option ROM里
  • 软件UNDI:由PXE固件模拟实现,用于兼容没有UNDI的网卡

我记得有一次给一台老笔记本做网络启动,网卡是Broadcom的,PXE固件里没有对应的UNDI驱动。后来我刷了一个第三方固件,把软件UNDI加进去,才搞定。

4.3.2 NBP(Network Bootstrap Program)

NBP就是前面提到的引导程序。它是PXE启动流程的终点,也是操作系统加载的起点。NBP通过PXE API来获取网络资源,比如下载配置文件、内核镜像等。

常见的NBP有:

NBP名称 适用场景 特点
pxelinux.0 BIOS + Linux 经典,配置灵活
bootx64.efi UEFI 64位 + Windows/Linux 标准UEFI应用
grub2的core.img UEFI + Linux 功能强大,支持加密
ipxe.efi UEFI + 高级需求 支持HTTP、iSCSI

我个人比较喜欢用iPXE。它比原版PXE功能强太多,支持HTTP下载、iSCSI启动、甚至脚本控制。有一次需要在没有DHCP的环境里做网络启动,iPXE的脚本功能帮了大忙,直接硬编码了IP和启动路径。

总结一下:
  • UNDI是网卡的抽象层,让PXE固件能操作任何网卡
  • NBP是引导程序,负责加载操作系统
  • PXE固件在中间,把UNDI和NBP串联起来

4.4 PXE启动流程图

下面这张图把整个流程串起来了。从客户端开机到操作系统启动,每一步都标清楚了。

PXE启动流程图 客户端开机 PXE固件初始化(UNDI加载) DHCP Discover/Offer/Request/Ack 获取IP + Option 66/67 TFTP下载NBP文件 如 pxelinux.0 / bootx64.efi 执行NBP引导程序 加载操作系统内核 UNDI:网卡抽象接口 由固件或网卡ROM提供 NBP:网络引导程序 通过PXE API获取资源

这张图把UNDI和NBP的位置标得很清楚。UNDI在底层,负责和网卡通信。NBP在上层,负责加载系统。PXE固件在中间做调度。三者缺一不可。

避坑指南:我曾经遇到一个案例,客户端能拿到IP,但TFTP下载总是失败。排查后发现是网卡驱动问题——UNDI接口没有正确初始化。解决办法是更新网卡固件,或者在PXE设置里关闭UEFI网络栈再重新开启。

好了,关于PXE协议的核心内容就这些。从固件关系、启动流程到UNDI和NBP,每个环节都有它的设计逻辑。理解这些,你就能自己搭建一套稳定的网络启动环境了。

可可精品资料库