http://dalang.im/post/provision_via_ipxe
- Preknowledge
- Chainloading iPXE
- BIOS (burned-in PXE) => PXELINUX => iPXE Kernel (ipxe.lkrn)
- BIOS (burned-in PXE) => iPXE firmware (unidonly.kpxe / ipxe.pxe)
- boot WinPE via iPXE (for Windows Provision)
- wimboot
- PXELINUX with WinPE ISO
- iPXE => PXELINUX
- PXELINUX => WinPE ISO
- Reference
Preknowledge
PXE
PXE是Preboot eXecution Environment的简称,又称为预执行环境, 通过PXE我们可以通过网络给计算机安装操作系统。 PXE协议大致上结合了DHCP和TFTP。当计算机通过PXE启动时,通过DHCP查找合适的启动服务器,然后通过TFTP下载初始引导程序和附加文件。 现在的网卡一般都烧了PXE的固件,以支持PXE启动
gPXE
gPXE是PXE的一个开源实现(更早的实现是Etherboot)。通过gPXE能让网卡直接支持网络启动,而不依赖于网卡自带的PXE固件。同时相比PXE,gPXE支持更多的协议。 传统的PXE只能通过TFTP进行传输,而gPXE支持HTTP,iSCSI和ATA over Ethernet(AoE),甚至支持wifi链接。
iPXE
iPXE表示 it doesn't PXE。iPXE是gPXE的原班人马写的(他们从Etherboot开始),作为官方的gPXE的替代品。 gPXE扩展的功能在iPXE中都得到支持。 之所以不再使用gPXE是由于存在版权纠纷,iPXE从2010年4月开始,基于同一个代码库开始开发。
PXELINUX
Syslinux是一个优秀的系统启动加载器(bootloader),可引导自硬盘、光盘、和通过PXE的网络启动。 PXELINUX派生自Syslinux,用来使支持PXE的网卡从网络引导启动Linux。PXELINUX程序不是烧在网卡里,而是存储在TFTP服务器上。
Chainloading iPXE
可以把iPXE当作固件刷进计算机网卡的ROM里替换掉自带的PXE,但更为常见的是通过chainloading的方式进入iPXE。
通常我们会接触到两种iPXE:iPXE firmware(undionly.kpxe)和iPXE kernel image(ipxe.lkrn)。两者都可以用来作为bootloader引导OS安装程序,iPXE支持的命令和脚本都能在firmware和kernel中使用。 kernel相当于一个linux系统,功能更加完善,比如支持命令行操作,支持initrd等,而firmware更多是作为bootloader来使用。 在bare metal provision的过程中,一般仅利用iPXE的bootloader功能,所以firmware和kernel都能用来加载操作系统安装程序。
下面介绍一下如何进入iPXE方法:
BIOS (burned-in PXE) => PXELINUX => iPXE Kernel (ipxe.lkrn)
当计算机从网络启动时,先从TFTP下载PXELINUX作为bootloader,然后引导进入iPXE kernel。 首先我们需要配置DHCP服务器以让计算机顺利进入PXELINUX 如果是ISC dhcp作为DHCP服务器,在dhcpd.conf文件中添加:
next-server TFTP_server_address;
filename "pxelinux.0";
如果是dnsmasq作为DHCP服务器,在/etc/dnsmasq.d/
下的配置文件添加:
dhcp-boot=pxelinux.0
注意 修改dhcp配置文件后,要重启dhcp service使其生效 pxelinux.0是存放在TFTP服务器PXELINUX程序,默认路径是/var/lib/tftp/
PXELINUX会根据pxelinux.cfg下的配置文件进行相应的引导工作。默认情况下PXELINUX按以下规则选择匹配的配置文件。
- 根据计算机网卡的MAC地址查找配置文件,文件名的格式为以中划线
-
分割的16进制MAC地址。比如拥有MAC地址为88:99:AA:BB:CC:DD以太网卡(ARP类型为1)的计算机会匹配文件名为01-88-99-aa-bb-cc-dd的配置文件
-
如果步骤1失败,则会尝试以计算机的IP地址(大写的16进制格式)查找配置文件,比如192.0.2.91对应C000025B配置文件。如果查找失败,会移除最后一位值尝试查找C000025文件,直至查找文件名为C的文件失败。最后会选择名为default(小写)的配置文件。下面这个例子说明拥有MAC地址为88:99:AA:BB:CC:DD以太网卡和192.0.2.91IP地址的计算机,查找PXELINUX配置文件的顺序:
pxelinux.cfg/01-88-99-aa-bb-cc-dd
pxelinux.cfg/C000025B
pxelinux.cfg/C000025
pxelinux.cfg/C00002
pxelinux.cfg/C0000
pxelinux.cfg/C000
pxelinux.cfg/C00
pxelinux.cfg/C0
pxelinux.cfg/C
pxelinux.cfg/default
PXELINUX配置文件的一个典型的应用是用来设置pxe引导项菜单。
default menu.c32
prompt 0
menu title PXE Boot Menu
timeout 50
f1 help.txt
f2 version.txt
label ipxe-boot
menu label Using boot.ipxe via iPXE booting
kernel ipxe.lkrn
append initrd=boot.ipxe
label boot-else
menu label Bypass iPXE
localboot 1
通过上面的配置文件会在引导时出现一个持续5秒的menu,以便选择对应的启动项。 默认进入iPXE kernel,进入后执行boot.ipxe脚本,可以在该脚本中执行chain命令以加载对应的操作系统安装程序。
iPXE界面,通过ctrl-b快捷键开启iPXE command line
BIOS (burned-in PXE) => iPXE firmware (unidonly.kpxe / ipxe.pxe)
假如不需要启动菜单,则可以通过iPXE firmware直接进入iPXE。
Universal Network Device Interface (UNDI) 通用网络驱动接口是支持PXE协议的网卡应用程序接口。 当从burned-PXE chainloading iPXE时,iPXE可以直接使用UNDI而不用加载网卡的硬件驱动。这样iPXE就能控制网卡,即便iPXE并没有该网卡的硬件驱动。
undionly.kpxe中的undionly表示该镜像仅加载UNDI而不加载PXE,后缀kpxe中的k表示keep UNDI。undionly.kpxe会通过UNDI复用网卡自身PXE软件栈的驱动。
与undionly.kpxe相对应的是ipxe.pxe,ipxe.pxe不加载UNDI,也不加载PXE,只能通过iPXE自己实现的硬件驱动来操作网卡。如果该网卡不被iPXE支持,就会出错。
比较常用的是以.pxe和.kpxe结尾的镜像文件,.kkpxe文件表示keep PXE + keep UNDI,常用于BIOS有bug的机子上。还有.kkkpxe文件只在制作ipxelinux.0时才用到。
关于不同后缀名称所表示的意思,可以参见 gpxe_imagetypes 和 When do I use .pxe, .kpxe, and .kkpxe?
需要说明的一点是,理想情况下,undionly.kpxe和ipxe.pxe应该都能正常工作,但有时候,有些网卡用undionly.kpxe可能会失败,而此时用ipxe.pxe可能是可以的。 比如HP 2570p (no network with iPXE undionly.kpxe) but ipxe.lkrn is working. 而又有些网卡用ipxe.pxe会失败,而undionly.kpxe又可以。 这些情况都是有可能发生的。
boot WinPE via iPXE (for Windows Provision)
wimboot
若要给计算机安装Windows,需要先进入WinPE。在官方文档的介绍中,使用wimboot来引导WinPE的.wim镜像。 wimboot能够直接从RAM盘加载WinPE,而不用再占用内存资源。
wimboot提供了一下几个优点:
- 高速 wimboot支持通过http下载WinPE镜像,而不受限于TFTP。以一个千兆网卡为例,典型200MBWinPE镜像耗时不超过两秒。
- 高效 wimboot支持Windows复用被RAM盘占用的内存资源,这样就不会造成内存浪费。
- 易用 wimboot能直接加载.wim镜像文件,不用打包成ISO或FAT文件系统的镜像。
iPXE官方文档Network-booting Windows PE详细介绍了加载WinPE的方法。 关键在于正确设置iPXE的chainload脚本。 以加载Windows ADK生成的标准的WinPE为例,可在iPXE中chain下面的脚本:
# iPXE chainload scripts
#!ipxe
kernel wimboot
initrd ${arch}/media/bootmgr bootmgr
initrd ${arch}/media/Boot/BCD BCD
initrd ${arch}/media/Boot/Fonts/segmono_boot.ttf segmono_boot.ttf
initrd ${arch}/media/Boot/Fonts/segoe_slboot.ttf segoe_slboot.ttf
initrd ${arch}/media/Boot/Fonts/segoen_slboot.ttf segoen_slboot.ttf
initrd ${arch}/media/Boot/Fonts/wgl4_boot.ttf wgl4_boot.ttf
initrd ${arch}/media/Boot/boot.sdi boot.sdi
initrd ${arch}/media/sources/boot.wim boot.wim
boot
上面涉及的WinPE文件都来自.wim镜像文件,连同wimboot程序放在web server的根目录,以便通过http能请求到。
PXELINUX with WinPE ISO
在我们的使用中发现,wimboot引导的方式在不少机型上存在兼容问题。比如有华为的服务器wimboot引导后出现黑屏。 出现这种情况时,可以尝试通过iPXE结合传统的PXELINUX来引导WinPE ISO。workflow则变成iPXE => PXELINUX => WinPE ISO
iPXE => PXELINUX
编写一个iPXE脚本boot.ipxe用于加载PXELINUX
# cat boot.ipxe
#!ipxe
set 209:string pxelinux.cfg/boot_winpe_iso
set 210:string http://:/
chain ${210:string}pxelinux.0
set 209
用于设置PXELINUX的配置文件,如果不指定的话,PXELINUX将通过上面提及的规则寻找自己的配置文件。set 210
配置通过http获取PXELINUX镜像文件时的IP地址和端口号。如果PXELINUX.0存放在TFTP服务器上,则无需配置。
在iPXE中,只要chain boot.pxe文件就可以进入PXELINUX了。
PXELINUX => WinPE ISO
通过设置PXELINUX的配置文件,这里为boot_winpe_iso,可以加载WinPE ISO。
# cat pxelinux.cfg/boot_winpe_iso
default winpe
noescape 1
label winpe
kernel /memdisk
initrd winpe.iso
该boot_winpe_iso通过memdisk来加载WinPE ISO。 此时的winpe.iso只能通过TFTP传输了,不再具备http的优势。 用这种方式进WinPE在兼容性上要好很多,能满足大部分机型。
Reference
- http://en.wikipedia.org/wiki/Preboot_Execution_Environment
- http://en.wikipedia.org/wiki/GPXE
- https://wiki.archlinux.org/index.php/Syslinux
- http://www.syslinux.org/wiki/index.php/PXELINUX
- http://ipxe.org/howto/winpe
- http://ipxe.org/wimboot
- http://etherboot.org/wiki/httpboot
- http://chee-yang.blogspot.com/2011/12/ipxe-boot-ipxe-linux-kernel-via.html
- http://chee-yang.blogspot.com/2011/11/ipxe-formerly-known-as-gpxe-is-open.html