Mar 282007
 

情景:
买了一台微型PC做二奶机,无光驱软驱,又懒得从主PC上拆下来用,于是打算通过网络安装的方式来装操作系统。
需求:
可以支持PXE启动的网卡,经检查版载的Reltek 8110是支持Intel PXE Rom的;
网络环境,没问题,有一个一个宽带路由器;
DHCP Server/TFTP Server,自然是在主PC上搭咯;
PXE Server,根据PXE协议设计的服务,关键问题就在于这里的选取和实现了。
原理:
简单研究了一下,PXE引导主要分为以下几个阶段:

1,硬件自检,BIOS开始运行,选取最优先引导设备进行引导,我们将优先设备设置为LAN,则进入网卡的PXE Rom引导过程。
2,PXE Rom发出DHCP请求,DHCP Server回应,PXE Rom根据回应设立网卡IP地址与协议栈。
3,协议栈建立完成,PXE Rom根据DHCP Server回应中某字端的值得到TFTP Server地址,并向这个地址请求bootstrap。
4,TFTP Server发回bootstrap,PXE Rom将系统控制权移交给bootstrap。
5,bootstrap继续引导过程。

从这个过程可以看出我所需要进行规划的几个key point:
1,bios启用网卡PXE Rom,设置Lan引导优先。
2,建立DHCP Server和TFTP Server,我这里选用Tftpd这个东西,这个是个运行在Windows下面同时支持二者服务角色的一个工具。因为我的主PC是windows系统,所以基本也只能选这个了。DHCP设计的要点在于IP池的规划以及bootfile的指定,前者随便选取一个内部网网段即可,后者牵扯到PXE Server,稍后分析。而TFTP只需要指定一个目录为TFTP root即可,也就是说客户端通过TFTP取文件都是以这个root目录作为参考的,后面的bootstrap和PXE Server相关文件自然也都需要放到此目录。
3,bootstrap这个角色类似硬盘引导的MBR,特点是需要短小精悍,当然也可以像grub一样是个多引导管理器,但因为属于操作系统启动之前的一个程序,一般来说只能跑在实模式下,所以设计的局限比较大。

对于PXE Server的选取,有几个备选者:
1,Windows RIP服务,这是微软官方的Windows部署工具,特点是可以通过网络上的ISO文件来引导系统,就此一点似乎还无其它PXE Server能做到。其bootstrap是安装RIP时得到的一个startrom.12的文件。同时还需要在tftp root放一个ntldr和winnt.sif文件,前者是windows的引导文件,后者是其配置文件,通过在后者中指定一个.ISO文件,可以通过TFTP装载并用这个ISO引导系统,从而完成Windows的安装。但RIP的局限也比较大,其一只能用于Windows系统本身分发,其二RIP本身就是一个集成DHCP和TFTP并加上网络认证的集成解决方案,需要AD的环境来支撑。故放弃之。
2,PXElinux,和syslinux,cdlinux同为一个项目的衍生物,本用于引导linux系统,后来功能越发强大,成为一个通用解决方案,可以用于多种系统的引导了。它的特点是支持类似grub的引导菜单之类的配置,用于客户启动时选择。同时还可以引导在TFTP上的内核,还可以引导软盘镜像,甚至可以创建一个内存虚拟盘来引导更多的Live系统等。事实上我一看到它就觉得肯定要用它了,因为目前没有比它配置更为灵活的工具了。他的bootstrap是一个叫做pxelinux.0的文件,同时用到一个pxelinux.cfg目录下面的default作为多启动的配置文件。因此就决定选它了。
3,还有其它类似grub pxe之类的一些工具,但要么资料少,要么功能不齐,暂时不考虑了,就打算使用pxelinux搞完了。

最理想的打算,是通过pxe的bootstrap直接从tftp上拖ISO并启动ISO内的安装程序,但事实往往没有这么美好….在pxelinux的Documents里面和maillists里面找了半天,发现一个很严肃的问题,pxelinux无法通过TFTP引导ISO,原因是一般ISO都比较大(至少也是1张CD600M左右吧),无法直接从TFTP内拿到本地(因为此时本地机器可能硬盘尚未分区甚至尚无硬盘,只有一个空空如也的网络协议栈),因此这也就“无法实现”。而为什么RIP就可以这么做呢?简单研究了一下资料,发现RIP可能是将TFTP的ISO影射为一个本地驱动器,然后通过ntldr引导这个驱动器内的exe文件实现ISO启动的,而奥妙应该就在startrom和ntldr中了,同时这些文件也hardcode了引导ISO的可执行文件地址,限定在\i386的某些文件下,也就是说对ISO也有硬性要求,因此在实现如此cool的功能的情况下牺牲了普适性。而pxelinx的设计思路中所包含的memdisk虽有异曲同工之妙,但是通过bios调用硬性在内存中扣出了一部分,将tftp中的memdisk文件载入到这部分内存,并将此块内存模拟成一个磁盘,再引导的,因此这个memdisk肯定要载入完成才能引导,同时还必须小于物理内存量。所以,直接通过pxelinux引导ISO的计划失败了。
但这并不代表束手无策了,聪明如在下的,自然很快就能从海量的资料中加以归纳总结,得出另外可行的方案,我这里很快就拟出了2个方案:
1,使用pxelinux的memdisk装载一个软盘镜像,为dos7的软盘镜像,dos下还有网络协议栈在维护,例如微软的协议栈和客户端,以及IBM的协议栈等。这样引导成功后就可以在dos下对磁盘分区,分好后启动协议栈,再通过ftp,http或netshare等任何dos下可用的手段把windows安装文件(i386)拖回本地硬盘,然后运行winnt.exe进入windows安装。此方案可行,只是需要在细节方面注意下就可以了,例如网卡驱动,协议栈选取,建立共享等,再细化一些甚至有dos下的虚拟光驱等工具可以直接用。但对于我个人来说,此方案过于繁琐,我个人的实验仅仅到了成功引导入dos,部署起dos下的网络环境就停止了,因为dos下配网络确实有够繁琐的。以前曾经看到一些万能dos工具盘等的个人作品来的,想来用这些东西应该能减轻一些工作量。不过我在干到这个地步时又想到了另外的偷懒办法,因此又有了下面的方案。对于第一种方案的pxelinux的config是这么写的,记录一下:

LABEL DOSDISK
MENU LABEL —-MSDOS710
kernel memdisk floppy
append initrd=msdos710.img

2,pxelinux有个chianloader,可以再引导入别的bootstrap,这里就可以想一下是否可以继续调用RIP的bootstrap了,然而由于我懒得过头,不想把自己的主PC上AD装RIP拿bootstrap和ntldr等,寄希望于能放狗找到,一不小心发现已经有某些人提取了这些支撑文件用于引导WinPE,刚好手头有一张WinPE的ISO,随手一试竟然成功了。于是乎就惬意的在由PXE引导成功的WinPE中用分区魔术师分硬盘,加载网络协议,映射主PC中的ISO共享,然后将此ISO用虚拟光驱挂载,然后直接setup开始安装。唯一需要注意的是安装前必须将硬盘分好区,并需要选择“将安装文件copy到本地磁盘”,因为一旦安装过程第一次重启后我的PXE引导的WinPE就不复存在了,同时虚拟光驱也没了。其实不用引导WinPE应该也能支持chianload出RIP的bootstrap来引导windows安装ISO的,但是不幸的问题是我下载到的几个RIP支撑文件都是被hack过的,为了引导WinPE的ISO作了修改,所以不能引导安装ISO,XD
配置文件更简单:

LABEL winpe
MENU LABEL —-Windows PE
kernel startrom.0

同时tftp root下别忘了放ntldr,nedetect,winnt.sif,其中winnt.sif如下:

[SetupData]
BootDevice = “ramdisk(0)”
BootPath = “\WXPE\System32\”
OsLoadOptions = “/noguiboot /fastdetect /minint /rdexportascd /rdpath=winpe.iso”

其实PXE远远不止是部署系统这么简单的作用,目前做得最好的恐怕是中国科技大内部的PXE服务器了,他们用pxelinx实现了太多的操作系统的live版或是安装版了,具体可以参见http://pxe.ustc.edu.cn/

  3 Responses to “无光驱、软驱,通过PXE安装Windows 2003”

  1. 楼主很有创新精神,
    你的方案相当有意思,
    该天一定要试试.

  2. 我個人對你文中最後的第二點很感興趣, 可以說明的更詳細些嗎? 謝謝

  3. 该注意的地方都写了,唯一一个需要自己动手的就是那个startrom.0,这玩艺其实来自Windows RIP服务,为了让其能引导WinPE,用二进制修改工具将其固化在里面的系统路径修改掉就可以了.
    这篇文章时间过于久远,我自己做过的那些东西都不知道扔哪里去了,建议你可以去无忧启动论坛翻翻帖子,不少人自己diy的多重启动系统光盘大致都是用这个方法,尤其注意那些支持PXE启动的版本,里面的那些东西都可以拿来用.

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>