[转帖]PXE服务器架设指南及PXE启动WinPE(含PE2.0)解决方案总结

时间:2024-03-09 18:15:29
这个求助帖子发布的时间已经很早了(2006年10月份),据我所知,这大概是当时我经常访问的各论坛里第一个讨论通过PXE启动PE的帖子(当然,后来的讨论证明,很多人都在研究这个东西,并且国外早就有人解决了这个问题),而且在大家的努力下成功的找到了解决方案,当时,grub4dos还不支持pxe启动方式。但是,那个帖子中的讨论内容比较乱,没有条理。现在随着grub4dos对pxe启动方式的支持,又有很多人尝试使用grub4dos通过pxe启动pe(而且总是报告失败),所以这个问题又重新提到了桌面上来,而我发现很多人通过pxe启动WinPE之所以失败(无论是用pxelinux还是用grub4dos),并不是因为启动方法或者PXE服务器设置有问题,而是不了解pxe启动PE的过程和原理,所以有必要在这里总结一下。当然,我对通过PXE启动PE的原理也只是通过实践的猜测,可能下面讲述的原理并不严谨,但大体是还是正确的,至少可以解决大部分人遇到的问题。详细的严谨的过程还需要有关高手进一步阐述,也希望高手们对我的总结加以批评指正。


1、PXE启动服务器的架设


简单说来,PXE服务器就是DHCP服务器+TFTP服务器。网络启动过程大概是这样的(可能并不严谨):客户端发送动态获得IP地址的广播包到网络上,DHCP服务器在收到该广播包后,发送给客户端分配IP地址的回应包,客户端收到回应包后设置自己的IP地址,然后从DHCP服务器获得启动服务器的IP地址(DHCP服务器066选项,这就是TFTP服务器的IP地址)及启动文件名(DHCP服务器067选项,这里的启动文件名就是pxelinux.0或者支持pxe的grub4dos的grldr,当然,也可以是startrom.n12或者使用3com Image Edit创建的pxe启动菜单文件,总之,它应该是一种由pxe启动规范规定的固定格式的可执行文件),然后客户端再联系启动服务器(TFTP服务器)获得启动文件并执行,这样基本上就完成了pxe启动过程。


在Unix或者Linux系统下,DHCP服务器和TFTP服务器一般都是分开设置的,两台服务器甚至可以在两台不同的机器上,其实Windows下的设置也是一样的,但在Windows下,我们可以通过使用HaneWin DHCP服务器软件或TFTPD32,这样使用一个软件就搞定了两台服务器(我个人推荐使用HaneWin DHCP服务器软件,但TFTPD32设置起来更简单一些,就是效率有些低),详细的设置方法请自己摸索,你只要知道,在设置PXE服务器时,要设置好DHCP和TFTP两个服务器,其中DHCP服务器要设置启动服务器名(066选项)和启动文件名(067选项)。


下面提供一个我在给下属单位讲课时所写的pxe服务器设置讲义(比较简略,但有截图,你如果理解了上述原理,应该不难搞定):

[url=mhtml:file://E:%20Users%20login.zhang%20Desktop%20BDDWINPE%20PXE服务器架设指南及PXE启动WinPE.mht!x-usc:http://nufans.net/upload/winpe/PXE_Server_Setup.rar]http://nufans.net/upload/winpe/PXE_Server_Setup.rar[/url]


2、PXE启动PE 1.0的原理


首先声明,这里讲的方法不见得适应于所有的PE,基本上基于无忧启动论坛老九(lxl1638)所制作的PE(例如老毛桃定制的版本)都应该是可以的,这些PE都是基于RAMDisk方式启动的,我试验时,深山红叶的PE是不能这样启动的。


通过PXE启动PE需要这么几个文件:


1)startrom.n12:这个文件从Windows 2003 SP1/SP2光盘中来,这个文件实际上也是一个符合pxe启动规范的启动文件,可以直接作为pxe服务器的启动文件来直接运行,当然,它也可以通过pxelinux的kernel命令来运行,我不知道grub4dos是否识别它的文件格式,如果能够识别,原理上它也可以使用grub4dos的kernel命令来执行,否则就使用chainloader --force命令来执行。


在Windows 2003 sp1/sp2的光盘中,还有一个startrom.com文件,它的作用跟startrom.n12是相同的,只是启动时需要按一个F12键才能继续,而startrom.n12则去掉了F12这个提示。


2)ntldr:这个文件是从Windows 2003 SP1/SP2光盘中的setupldr.exe改名而来,它的作用应该相当于从本地硬盘启动PE的setupldr.bin,但两者并不相同,但它决不是我们平常所使用的ntldr。这个文件必须放到TFTP服务器的根目录。


3)ntdetect.com:这个就是XP或2003所使用的c:\下的ntdetect.com。这个文件也必须放到TFTP服务器的根目录。


4)winnt.sif:这个是PE的启动配置文件(用来指定PE的系统目录及PE映像文件所在路径及启动选项)。这个文件也必须放到TFTP服务器的根目录。通过pxe启动的PE支持3种映像文件格式,例如,ISO、IMG或者SDI。其实,SDI格式相当于IMG格式,只是SDI格式在IMG文件前加了一个文件头。一般我们都使用ISO或IMG格式,但这两种格式的启动选项是有所不同的,ISO格式要在启动选项中增加一个/rdexportascd,而SDI格式还要增加一个/rdoffset选项。下面是Winnt.sif的示例: 复制内容到剪贴板 代码:[SetupData]
BootDevice = "ramdisk(0)"
BootPath = "\I386\SYSTEM32\"
OsLoadOptions = "/minint /fastdetect /rdpath=\netpe.c\winpe.img"
;OsLoadOptions = "/minint /fastdetect /rdexportascd /rdpath=WINPE.ISO"

另外,winnt.sif文件中还要注意的就是BootPath选项,默认它指向"\I386\SYSTEM32"目录,但老毛桃的PE将I386目录修改成了WXPE,那么这里要作对应的修改,同时还要修改2)中的ntldr文件,将其中所有的I386替换为WXPE。只是修改winnt.sif是没有用的。后面我们讲通过PXE启动多个PE时还要讲更多的hack PE启动文件的方法。


5)PE映像文件(IMG或者ISO或者SDI格式,例如WinPE.IMG):这里特别要注意的就是PE的映像文件一定不能使用cab压缩格式,如果你用老毛桃的PE,一定要将它光盘根目录下的WinPE.IS_解压缩成winpe.iso然后放到这里使用。这样,IMG格式的PE就比较有优势了,因为IMG格式是硬盘分区映像格式,你可以对这个分区使用NTFS文件系统并加上NTFS压缩,基本上压缩率也接近cab压缩格式,这样img文件就没有必要使用cab压缩但仍然具有cab的压缩率,而且img格式可以直接使用Virtual Disk Manager(VDM)挂载并进行编辑,修改起来比较方便。另外,这个PE映像文件没有必要放在TFTP服务器的根目录下,例如上面的winnt.sif中就将winpe.img放在了TFTP服务器的/netpe.c/目录下。


PXE启动PE的过程大致是(可能也不是很严谨):startrom.n12获得执行后,在TFTP服务器根目录下寻找ntldr(setupldr.exe),找到后加载ntldr并执行,而ntldr则在TFTP服务器的根目录下查找winnt.sif,根据winnt.sif的内容从TFTP服务器上下载PE的映像文件并根据选项进行PE的加载,在PE的加载过程中可能会用到ntdetect.com。


3、让PXE服务器支持同时启动多个PE(1.0)的设置方法

通过上面的讲述,我们已经明白了通过PXE启动PE的一个概况,由于PE通过PXE启动时,要求NTLDR(setupldr.exe)、winnt.sif和ntdetect.com必须放在TFTP服务器的根目录,那么要想让PXE服务器支持同时启动多个PE,必须对文件名进行hack,其中ntdetect.com是PE启动时共用的,没有必要进行修改,但ntldr和winnt.sif由于只跟一个PE有关,所以文件名必须进行更改。假设我们要启动的第二个PE的映像文件名为netpe.iso,该映像文件放在TFTP根目录下的netpe目录下,ISO中的I386目录被改成了WXPE,由于该PE通过pxe启动时不能再使用ntldr和winnt.sif,那么这两个文件我们对应改成:netpe和netpe.sif,详细的hack过程如下:

1)startrom.n12:这个文件没有必要放到TFTP服务器的根目录下,可以将它跟PE映像文件放到同一个目录下,文件名可以起成netperom.0,由于它启动时要查找TFTP服务器根目录下的ntldr,所以必须使用十六进制编辑器(UltraEdit)打开它进行修改,将该文件中的所有ntldr字符串查找替换成netpe。

2)将原来的ntldr(setupldr.exe)改名为netpe并放到TFTP服务器的根目录下,用UE打开并将所有的winnt.sif字符串替换为netpe.sif,同时将所有的I386字符串替换为WXPE。

3)新建一个文件,名为netpe.sif,放到TFTP服务器根目录下,内容如下: 复制内容到剪贴板 代码:[SetupData]
BootDevice = "ramdisk(0)"
BootPath = "\WXPE\SYSTEM32\"
OsLoadOptions = "/minint /fastdetect /rdexportascd /rdpath=\NETPE\NETPE.ISO"

4)修改pxelinux的启动菜单文件(pxelinux.cfg/default),加入一个条目,内容如下:

LABEL netpe
MENU LABEL WinPE with Network Support for PXE boot
kernel /netpe/netperom.0

如果使用pxegrub,那么启动菜单是类似这样的:
title WinPE with Network Support for PXE boot
pxe keep
chainloader --force /netpe/netperom.0

基本上,上面所讲的就包括了有关PXE启动PE的所有内容,下面提供一个我的TFTP服务器目录结构(包括pxelinux.cfg/default)下载包,供大家参考:
[url=mhtml:file://E:%20Users%20login.zhang%20Desktop%20BDDWINPE%20PXE服务器架设指南及PXE启动WinPE.mht!x-usc:http://nufans.net/upload/winpe/PXE_WinPE_Climbing.rar]http://nufans.net/upload/winpe/PXE_WinPE_Climbing.rar[/url]


4、PXE启动PE 2.0的原理

首先声明,我个人从来没有制作甚至使用过PE 2.0,因为从心理上我一直比较排斥它,感觉它是微软为了打压BartPE才出来的东西,而且体积也很大,没有PE 1.0的短小精悍,从功能上也没有发现它比PE 1.0有什么优胜的地方(最新的不一定是最好的)。所以,这篇总结纯粹是为了方便对相关的技术感兴趣的人参考而做的,这里总结的东西都是参考别人的帖子再加上我的理解而做出来的,纯粹是纸上谈兵,没有任何实践基础,因此错漏难免,敬请各位高手批评指正。

参考帖子:

1) [url=mhtml:file://E:%20Users%20login.zhang%20Desktop%20BDDWINPE%20PXE服务器架设指南及PXE启动WinPE.mht!x-usc:http://bbs.wuyou.com/viewthread.php?tid=106600]http://bbs.wuyou.com/viewthread.php?tid=106600[/url],由titanbai站友提供的PXE启动PE 2.0的详细技术细节,感谢titanbai站友的无私奉献!
2) [url=mhtml:file://E:%20Users%20login.zhang%20Desktop%20BDDWINPE%20PXE服务器架设指南及PXE启动WinPE.mht!x-usc:http://bbs.wuyou.com/viewthread.php?tid=100886]http://bbs.wuyou.com/viewthread.php?tid=100886[/url],由“原名丢了”站友提供的PXE启动多个PE 2.0的设置文档(英文),来源于911CD论坛。


其实PXE启动PE 2.0的原理大体与启动PE 1.0的原理相似,只是换了几个启动文件而已。首先,PE 2.0的引导方式不再使用NT的NTLDR方式,而是使用了VISTA的BCD方式,PE 1.0和PE 2.0在引导上的主要区别也就在于此。

PE 2.0的启动文件变成了下面几个:

1) pxeboot.0: 由pxeboot.com或者pxeboot.n12改名而来,这两个文件可以从WAIK中获得,详细方法请参考titanbai站友的帖子。这个文件对应PE 1.0中的startrom.0文件。它的放置位置一般是TFTP服务器的/boot目录下,个人感觉它的位置可以随意放置。它的主要作用是加载TFTP根目录下的bootmgr.exe文件。

2) bootmgr.exe: 这就是VISTA的bootmgr了,它也是由WAIK中获得的,而且它必须放到TFTP服务器的根目录下(与PE 1.0中的setupldr.exe对应)。它的作用主要是读取启动配置文件也就是/boot/BCD,根据BCD的配置进一步加载/boot/boot.sdi文件。

3) /boot/BCD:这是bootmgr的启动菜单配置文件,跟VISTA的启动菜单配置文件没有什么区别,它主要对应NT的boot.ini文件,由VISTA的命令行程序bcdedit.exe来进行配置和修改。一个创建BCD文件启动PE 2.0的例子如下: 复制内容到剪贴板 代码:Bcdedit -createstore c:\BCD
Bcdedit -store c:\BCD -create {ramdiskoptions} /d "Ramdisk options"
Bcdedit -store c:\BCD -set {ramdiskoptions} ramdisksdidevice  boot
Bcdedit -store c:\BCD -set {ramdiskoptions} ramdisksdipath  \boot\boot.sdi
:: NEW GUID CREATED HERE
for /f "tokens=1-3" %%a in (\'Bcdedit -store c:\BCD -create /d "WinPE 2.0" /application osloader\') do SET GUID1=%%c
Bcdedit -store c:\BCD -create {bootmgr} /d "VISTA Boot Manager"
Bcdedit -store c:\BCD -set {bootmgr} timeout 15
Bcdedit -store c:\BCD -set {bootmgr} displayorder %GUID1%
Bcdedit -store c:\BCD -set %GUID1% systemroot \Windows
Bcdedit -store c:\BCD -set %GUID1% detecthal Yes
Bcdedit -store c:\BCD -set %GUID1% winpe Yes
Bcdedit -store c:\BCD -set %GUID1% osdevice ramdisk=[boot]\Boot\WinPE.wim,{ramdiskoptions}
Bcdedit -store c:\BCD -set %GUID1% device ramdisk=[boot]\Boot\WinPE.wim,{ramdiskoptions}

4) boot.sdi: 这个文件好像是通用的,将VISTA光盘上的boot.sdi文件复制过来即可,必须放到TFTP服务器/boot目录下。

5) WinPE.WIM: 这就是PE 2.0的主映像文件了,也要放到/boot目录下。

PE 2.0的PXE启动过程大概是这个样子的:

首先,pxeboot.0获得执行权限(可以由pxelinux菜单直接调用,或者将pxeboot.0直接作为PXE服务器的启动文件),然后,该文件下载TFTP服务器根目录下的bootmgr.exe并执行,bootmgr.exe再读取/boot/BCD文件获得PE 2.0的启动配置,并进一步下载/boot/boot.sdi及/boot/winpe.wim,然后执行winpe.wim中的winload.exe开始PE 2.0的启动过程。

5、让PXE服务器支持同时启动多个PE 2.0的方法

这个主要参考上面“原名丢了”站友所贴的那个英文帖子的内容,我简单翻译一下,其实,主要还是hack相应的启动文件,麻烦就在于bootmgr.exe加了checksum校验及数字签名校验,相应设置一下就行了。翻译的不太好,有什么问题,大家再继续探讨。

英文原文及对照翻译如下:

you want to be able to boot different images. You could put extra entries in the BCD file using BCDEDIT but perhaps like me you don\'t want to display bootmgr\'s menu and want to use your existing PXELINUX initial PXE stage to choose the image. So want bootmgr to use different BCD files.

你想启动多个PE 2.0的映像文件,一个方法是你可以使用BCDEDIT修改BCD启动配置文件,加入多个PE的启动项。但如果你跟我一样,不想看到bootmgr的启动菜单,而想通过pxelinux选择要启动的PE,这时候就需要bootmgr使用不同的BCD启动配置文件。

So you currently have an entry in pxelinux.cfg\default (or a specific config for your test PC) that says:

目前,你的pxelinux.cfg\default中应该有这么一项: 复制内容到剪贴板 代码:label winpe2
kernel boot/pxeboot.0

which startes the process:

这一项启动PE 2.0的过程是这样的: 复制内容到剪贴板 代码:pxelinux.0
|
v
boot/pxeboot.0
|
v
bootmgr.exe <-- /Boot/BCD
|
v
boot/boot.sdi <-- /Boot/WinPE.wim
|
v
winload.exe

But...the file "\Boot\BCD" is hardcoded into bootmgr.exe!

但是,文件“\Boot\BCD”是固化在bootmgr.exe里面的!

Ok, no problem...

好,没问题...

Copy bootmgr.exe to testmgr.exe and hex edit it:
复制bootmgr.exe为testmgr.exe并用十六进制编辑器编辑它:
Change the "\Boot\BCD" unicode text at 0x4F98C to "\Test\BCD".
将0x4F98C位置处的Unicode字符串"\Boot\BCD"修改为"\Test\BCD"。

Also, copy boot\pxeboot.0 to test\pxetest.0 and hex edit this too:
同样的,复制\boot\pxeboot.0为\boot\pxetest.0,并同样编辑:
Change the "bootmgr.exe" at 0x5961 to "testmgr.exe"
将0x5961位置处的“bootmgr.exe”字符串修改为“testmgr.exe”。

Copy boot\BCD to test\BCD and use BCDEDIT to change the osdevice and device entries to use "[boot]\Test\TestPE.wim,{ramdiskoptions}". No need to change the boot/boot.sdi entry.
复制 \boot\BCD 为 \test\BCD,然后用BCDEDIT修改“osdevice”和“device”项为“[boot]\Test\TestPE.wim,{ramdiskoptions}”,没必要修改\boot\boot.sdi那一项。

Add an entry in pxelinux.cfg\default:

在pxelinux.cfg\default中增加一项: 复制内容到剪贴板 代码:label testpe2
kernel test/pxetest.0

Ok, we hope this will now follow this process:
好,我们希望这一项的启动过程是这样的: 复制内容到剪贴板 代码:pxelinux.0
  |
  v
test/pxetest.0
  |
  v
testmgr.exe <-- /Test/BCD
  |
  v
boot/boot.sdi <-- /Test/WinPE.wim
  |
  v
winload.exe

We, try it and get a checksum error with testmgr.exe.
而测试启动时会出现“checksum error with testmgr.exe”(testmgr.exe文件校验错误)。

Ok, it has a PE checksum at 0x130 so we use a tool (such as PE Explorer) to calculate our testmgr.exe\'s checksum and update the file.

原来,bootmgr.exe在0x130位置处有一个PE checksum(PE文件校验码),我们可以使用工具(例如PE Explorer,注:用google可以找到很多下载)重新计算testmgr.exe的校验码并将新校验码添入对应位置。

Try again...bootmgr reports:

再试...bootmgr 报告: 引用:
Windows cannot verify the digital signature for this file.

Windows不能验证这个文件的数字签名。

Looks like testmgr.exe has a digital signature that is getting checked and fails!

看来象是testmgr.exe有一个数字签名机制,由于没有通过验证所以失败了!

Now we\'re stuck...but there\'s this stuff about -set nointegritychecks Yes on various google pages...

现在,我们遇到了不可克服的困难...但在很多google页面上(关于PE 2.0)有这样的设置:-set nointegritychecks Yes。

Using "bcdedit -store x:\BCD -set nointegritychecks Yes"
or "bcdedit -store x:\BCD {guid} -set nointegritychecks Yes"
puts the setting in for the WinPE image (disabling driver signing - I believe) but doesn\'t stop the problem with our testmgr.exe (which stops before TestPE.wim is even retrieved).

使用上面的命令(甚至在WinPE的映像中禁用了驱动数字签名检测),但testmgr.exe仍然出现上述错误(甚至还没有等到下载TestPE.WIM文件)。

But, what about "bcdedit -store x:\BCD {bootmgr} -set nointegritychecks Yes" ?

但,"bcdedit -store x:\BCD {bootmgr} -set nointegritychecks Yes"这个命令又如何呢?

Yeah, it works!

好,解决了