上一篇说了PXE BOOT的原理,当计算机这边看到菜单的时候,PXE BOOT的部分已经结束了,接下来就由pxelinu.0处理了。对于linux而言。接下来需要向TFTP SERVER服务器请求kernel和文件系统intrd.gz.然后就能顺利启动操作系统了。上一篇通过PXE BOOT安装linux正是这样一个原理。那么能否也用同样的办法来安装windows呢,是可以的。微软的windows系列也有同样的办法。
    先转载一段某论坛看到的关于windows网络安装的原理:
 
    Windows网络安装表示从局域网内部引导Windows安装,核心技术基于微软的RIS(Remote Installation Services)。
实现Windows网络安装需要四个服务:BOOTP,TFTP,BINL,Windows Share. 其中BOOTP和TFTP是实现PXE启动的基础,关于PXE启动的详细信息,可以参考[url]http://bbs.znpc.net/viewthread.php?tid=3662&extra=page%3D1[/url]
    BINL服务,微软称之为启动信息协商层(Boot Information Negotiation Layer),其作用是网卡查询、身份验证、启动镜像选择等功能。实现Windows网络安装只需要其中一项功能,即网卡查询。Sherpya逆向分析了BINL协议,并写了一个开源的Binl服务程序。要了解详细信息,可以参考本文后的引用1。
    Windows共享服务提供了安装文件的来源,并且在文本模式安装阶段作为启动分区(Boot Partition),因此也是必不可少的。

    Windows网络安装的大致步骤如下:
    1. 目标计算机从网卡PXE Boot ROM启动(当然,你也可以用PXELinux或PXEGrub来实现类似的启动功能)。
    2. 目标计算机从DHCP/BOOTP服务器获得网络地址,并获得TFTP服务器的IP地址和启动文件信息。
    3. 目标计算机向TFTP服务器获得启动文件startrom.com/startrom.n12
    4. startrom.com获取ntldr(由setupldr.exe改名而来),并将控制权传递给它。
    5. setupldr.exe获取ntdetect.com和winnt.sif,winnt.sif应该包含启动相关信息。
    从这个时候起,有两种启动方法,即ramdisk和网络启动,对于Ramdisk,启动分区为\Device\Ramdisk{xxxx...},你可以参考本文后的引用2。对于网络启动,你需要在winnt.sif中设定SetupSourceDevice参数。
    6. setupldr.exe通过ntdetect.com获得网卡的Vendor ID和Device ID, 并将它发送到Binl服务端口(4011)。
    7. Binl服务查找“数据库”,获得需要加载的驱动名称和服务名,返回给setupldr.exe
    8. Setupldr.exe按照正常顺序加载驱动,不过在最后,它会试着去加载前面给出网卡驱动和网络设备相关驱动,你可以从TFTP服务器的log里看到这些。有意思的是,txtsetup.sif并没有网络设备相关驱动的信息,我想可能是直接写在setupldr.exe里了。
    9. 控制权移交给kernel,kernel会试着去mount启动分区,要注意的是,你建好的共享必须提供匿名访问,否则会停住不动。
    10. 开始文本模式安装,setupdd复制文件到硬盘。完成后重新启动。
    11. 开始GUI阶段安装,要注意的是,之前应该在Winnt.sif中指定OriSrc和OriTyp,至于是不是必须的,我不好说,因为并没有试验过。
    12. 安装结束。实际上,你可以在winnt.sif中加入相关信息,以便实现无人值守安装。
 
上面啰唆了这么多,下面开始实际动手来实现这个过程。上面第5步提到了两种启动方式,一种是RAMDISK,一种是网络安装,我们用后一种方式来实现网络安装。
        TFTP和DHCP在上一篇文章已经完成了,接下来需要架设SAMBA服务器.SAMBA服务器的安装和配置很简单.需要注意的是samba的配置文件需要做如下调整:
[global]
null passwords = true
security = share
workgroup = workgroup
[REMINST]
browseable = yes
read only = no
path = /tftpboot
guest ok = yes
把WinXP光盘上的i386目录复制到/tftpboot/winxp目录下,再把一个正在运行的WinXP SP2下的WINDOWS\inf目录复制到/tftpboot/winxp/i386目录下

进入/tftpboot/winxp/i386目录,解开driver.cab文件。
 
#cabextract driver.cab
一般的机器没有cabextract,需要先安装这个软件,或者你在windows下解压缩好了复制过来也行.由于我们刚才已经架好了samba,并且给了写权限,可以直接通过samba来把这些文件复制到linux上去.
由于在Linux下,TFTPD对大小写很敏感,刚才的rules也把所有对文件和目录的请求都改成了小写,所以这里也要把所有文件名都改成小写的。用如下命令来修改:
#find ./ -depth | perl -ne 'chomp;m</[^/]*$>;$d=$`;$_=$f=$&;''s/([\x80-\xFF].)|(\w)/$1\l$2/g;system "mv",$d.$f,$d.$_ if $f ne $_'
 
现在进入/tftpboot/i386目录下,ls一下,都是小写了,i386记得也改成小写.
下面我们把windows启动的几个文件都复制到tftpboot目录下
#cd /tftpboot/winxp/i386
#cabextract startrom.n1_ startrom.n12

#sed -i -e 's/NTLDR/XPLDR/gi' startrom.n12

#cabextract setupldr.ex_ setupldr.exe

#sed -i -e 's/winnt\.sif/winxp\.sif/gi' setupldr.exe

#sed -i -e 's/ntdetect\.com/ntdetect\.wxp/gi' setupldr.exe

#cp ntdetect.com /tftpboot/ntdetect.wxp
 
这几个sed命令的意思对启动文件中关于文件名的地方进行修改,为啥要修改呢,因为如果要安装不同的windows的版本,就需要修改文件名,避免冲突.
 
接下来创建winxp.sif应答文件
[data]
floppyless = "1"
msdosinitiated = "1"
; Needed for second stage
OriSrc = "\\192.168.1.253\REMINST\winxp\i386"
OriTyp = "4"
LocalSourceOnCD = 1
DisableAdminAccountOnDomainJoin = 1

[SetupData]
OsLoadOptions = "/fastdetect"
; Needed for first stage
SetupSourceDevice = "\Device\LanmanRedirector\192.168.1.253\REMINST\winxp"

[UserData]
ComputerName = *
; if needed
;ProductID=
OriSrc ,SetupSourceDevice这两行不要写错了.192.168.1.253是架设samba的机器的IP地址,REMINST是共享名.如果这两行写错了,后面安装的时候会一些错误.
 
接下来就是搞定Binl Server了,
#wget [url]http://oss.netfarm.it/guides/ris-linux-0.3.tar.gz[/url]
#tar zxf ris-linux-0.3.tar.gz
#cd ris-linux-0.3

缓存驱动
#./infparser.py /tftpboot/winxp/i386/inf

#./binlsrv.py
注意不要关闭binlsrv.py这个进程。

配置到这里几乎全部工作都完成了,应该可以通过PXE安装WinXP了。在开一个vmware,开机按F12.出现菜单后,找到winxp远程安装的那一项,可以安装了.如果有什么问题,可以查看tftp的log来排错.日志在/var/log/messages.一般都是文件名大小写的问题等等.需要注意的是.要安装系统的机器的网卡的驱动一定要事先放在/tftpboot/winxp/i386/inf 下,默认winxo的drivers.cab里面集成了大量驱动,如果你的网卡驱动不在winxp自带的包里,需要手动复制网卡驱动盘中的文件到这里.
 
如果我们想全程自动安装winxp,而不需要交互操作的话,可以把安装xp的应答文件写到winxp.sif里面.下面给一个例子.
[data]
floppyless = "1"
msdosinitiated = "1"
; Needed for second stage
OriSrc = "\\192.168.1.253\reminst\winxp\i386"
OriTyp = "4"
LocalSourceOnCD = 1
DisableAdminAccountOnDomainJoin = 1

[SetupData]
OsLoadOptions = "/fastdetect"
; Needed for first stage
SetupSourceDevice = "\Device\LanmanRedirector\192.168.1.253\reminst\winxp"

[Unattended]
UnattendMode=FullUnattended
UnattendSwitch="Yes"
OemPreinstall="Yes"
OemSkipEula="Yes"
FileSystem=*
WaitForReboot="No"
NoWaitAfterTextMode=1
NoWaitAfterGUIMode=1
DriverSigningPolicy=Ignore
NonDriverSigningPolicy=Ignore
Hibernation="No"
TargetPath = \WINDOWS
InstallFilesPath = "\\192.168.1.253\reminst\winxp\i386"
LegacyNIC = 1
[SystemRestore]
[GuiUnattended]
EncryptedAdminPassword="No"
AutoLogon="Yes"
AdminPassword=*
OEMSkipRegional=1
TimeZone=004
OemSkipWelcome=1
[Components]
msmsgs=off
msnexplr=off
 
PXE BOOT安装windows到这里就成功了,接下来还会告诉大家,如何进一步利用PXE BOOT来实现其他功能.敬请期待下集.