LinuxのPXEを使ってWindows PEをネットワークブート

Windows PEをPXEサーバを使ってネットワークブートしてみた。他のWindows系OSと異なり、ネットワークブートすることも念頭に置かれて作られているためか、それほど手間はかからなかった。BartPEやLinux系でネットワークブートをやったことがあれば、簡単に設定できるだろう。

まずはちょっとおさらい。Windows PEはWindows系OSを大量のPCに配布したり、Windows系OSがシステムトラブルを起こした時にメモリだけで起動し修復作業をするために開発された特殊なOSである。*1 そのためWinPEのユーザはOEMメーカは千台ものPCを管理しなければならない大手の情報システム部門がほとんどだと思うが、Windows製品の正規ユーザであれば個人でも利用できる。(「Windows PE」を参照)

WinPEの基本的な利用方法はWinPEの起動CDを作成して、そのCDからブートして使う。しかし、企業などでWindowsの保守で使う場合は、PCにCD/DVDドライブがなければならず、コストもかかり、また外部ドライブを使うにしても手間がかかる。今時のPCであればネットワークインタフェースはほぼ標準であり、今時のBIOSであればPXEによるネットブートもサポートしているので、大量のPCを保守するのであればCDブートではなく、ネットワークブートの方が便利だ。

そこで、WinPEをネットワークブートできるか確認してみた。(なお、ここではPXEサーバとしてLinuxマシンを使っているが、PXEの動作はWindowsでもLinuxでも同じなので基本的にはどちらでも構わない。PXEとTFTPについては設定済みという前提で話を進めるので、LinuxによるPXEの一般的な設定については「PXEによるディスクレス・クライアント(総集編)」を参照のこと。)

PXEサーバに必要なファイルをコピーする

まず必要なファイルをPXEサーバに置いておく必要がある。必要なファイルはWinPEのブートCDを作成する開発環境から持ってくる(もしくは、作成したWinPEのCDからと、WinPEを起動してその中のファイルをネットワーク経由でコピーしても可能)。「Windows PE」にあるようにAIKをインストールすると、Windows PEの環境は

C:\Program Files\Windows AIK\Tools\PETools

に置かれる。まずは、そこから次のファイル・フォルダをコピーする。(ここでは、WinPEでブートするPCのアーキテクチャx86である前提で話を進める。もし64ビット系のPCなどでは適宜、適当なフォルダを使う。)

C:\Program Files\Windows AIK\Tools\PETools\x86\winpe.wim
C:\Program Files\Windows AIK\Tools\PETools\x86\boot\

これらのフォルダをPXEサーバのTFTPのディレクトリへコピーする。TFTPサーバをWinPEのブートのためだけに使うのであればTFTPのルートの下に、直接、"boot"や"winpe.wim"を置けば設定の手間が軽減できる(ちょっとだけファイル名の変更やファイルの移動は必要だが。)しかし、TFTPをWinPEのブートだけに使うのはもったいないので私は次のようにした。まず、TFTPのルートディレクトリに"winpe"というディレクトリを作り、その下に"x86"のフォルダをコピーした。TFTP上でのディレクトリの構成は以下の通り。(なお、"boot\fonts\"の下の中国語フォント(ch*.ttf)、韓国語フォント(ko*.ttf)、またそれ以外にも通常のPXEブートには必要ないファイルやディレクトリは削除してある。以下が(日本語表示オプションを除けば)ほぼ必要最小限である。

[root@pxeserver ~]# ls -R /tftpboot/winpe/
/tftpboot/winpe/:
x86

/tftpboot/winpe/x86:
boot  winpe.wim

/tftpboot/winpe/x86/boot:
bcd  boot.sdi  fonts

/tftpboot/winpe/x86/boot/fonts:
jpn_boot.ttf  wgl4_boot.ttf

以上で半分以上のファイルはPXEサーバにコピーできたが、実は肝心のNBP(Network Bootstrap Program、PXEブートで一番最初にダウンロードされるブートローダ)と次に呼び出される2次ローダなどが無い。これはRAMイメージ上のWinPEのディレクトリの中に入っているので、これを取り出す必要ある。まず、Linux上で/tftpboot/winpe/x86/pxeというディレクトリを作り、次にWinPEを立ち上げてネットワーク経由などで次のファイルやフォルダをそこへ持ってくる。

X:\Windows\Boot\PXE\pxeboot.n12
X:\Windows\Boot\PXE\bootmgr.exe
X:\Windows\Boot\PXE\en-US\
X:\Windows\Boot\PXE\ja-JP\

("en-US"、"ja-JP"は日本でメッセージを出すなどで使うのでなくても構わない。)
もしくは、WinPEの起動ディスク開発環境(AIK)をつかって次の方法で持ってくることも可能だ。

C:\winpe_x86>dir
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は A190-DEB9 です

 C:\winpe_x86ディレクトリ

2008/06/17  09:27              .
2008/06/17  09:27              ..
2008/01/05  03:23             2,048 etfsboot.com
2008/06/17  09:27              ISO
2008/06/17  09:27              mount
2008/01/23  17:45       183,819,403 winpe.wim
               2 個のファイル         183,821,451 バイト
               4 個のディレクトリ     649,486,336 バイトの空き領域

C:\winpe_x86>imagex /mount winpe.wim 1 mount

ImageX Tool for Windows
Copyright (C) Microsoft Corp. All rights reserved.


Mounting: [C:\winpe_x86\winpe.wim, 1] ->
          [C:\winpe_x86\mount]

Successfully mounted image.



C:\winpe_x86>xcopy /s mount\Windows\Boot\PXE N:\tftpboot\winpe\x86\pxe
mount\Windows\Boot\PXE\abortpxe.com
mount\Windows\Boot\PXE\bootmgr.exe
	:
mount\Windows\Boot\PXE\zh-HK\bootmgr.exe.mui
mount\Windows\Boot\PXE\zh-TW\bootmgr.exe.mui
33 個のファイルをコピーしました

C:\winpe_x86>imagex /unmount mount

ImageX Tool for Windows
Copyright (C) Microsoft Corp. All rights reserved.


Unmounting: [C:\winpe_x86\mount]...

Successfully unmounted image.



C:\winpe_x86>

(この例ではNドライブはネットワークドライブであり、Linuxマシンのディレクトリを共有している。そこへファイルをコピーしている。PXEの下をすべてコピーしているので、後で不必要なファイルは削除しておく。)

全てのファイルをコピーしたPXEサーバ上のTFTPのディレクトリは次のようになる。

[root@pxeserver ~]# ls -RF /tftpboot/winpe/
/tftpboot/winpe/:
x86/

/tftpboot/winpe/x86:
boot/  pxe/  winpe.wim

/tftpboot/winpe/x86/boot:
bcd  boot.sdi  fonts/

/tftpboot/winpe/x86/boot/fonts:
jpn_boot.ttf  wgl4_boot.ttf

/tftpboot/winpe/x86/pxe:
bootmgr.exe  en-US/  ja-JP/  pxeboot.n12

/tftpboot/winpe/x86/pxe/en-US:
bootmgr.exe.mui

/tftpboot/winpe/x86/pxe/ja-JP:
bootmgr.exe.mui

なお、ファイルのパーミッションは、これらのファイルはLinux上では単に置いてあるだけで実行できないし、TFTPサーバが読みだすだけなのでrootの所有で644のパーミッションにしておいた(ディレクトリは755)。

TFTPで配布できるようにシンボリックリンクを張る

すべてのファイルはPXEサーバ上へ展開できたが、このままでは、PXEクライアント(=WinPEを起動するPC)からTFTPでリクエストされるパス名やファイル名と異なるので、ファイル名・ディレクトリ名の変更やディレクトリの移動が必要になる。しかし、Linuxではシンボリックリンクという大変便利な方法があるので、それを利用してクライアントからのリクエストに対応できるようにする。なお、クライアントからは「\」記号を使ってフォルダを指定してくるが、Linuxでは「\」はディレクトリの区切り記号でないので、これもシンボリックリンクを使って解決できる。一石二鳥の方法だ。例えば、クライアントからは"\boot\boot.sdi"というファイルを要求してくるが、WindowsPXEサーバであればTFTPのルートフォルダの下に"BOOT"というフォルダを作り、その下に"BOOT.SDI"というファイルを置いておけばいい。(フォルダ名やファイル名は"BOOT"でも"Boot"でも"boot"でも構わない。その辺、Windows系はいい加減というか。実はローダーが要求する名前も大小文字が実体のファイル名と異なったり、"\boot"だったり"\Boot"だったり、一貫性がない....。) 一方、LinuxPXEサーバを使う場合は"\boot\boot.sdi"という「名前」のファイルにしなければならない。そう、「\」は区切記号ではなく、ファイル名の中の単なる文字として扱えばいい。あとは、大文字、小文字の区別も含めて正確にクライアントから要求された通りの「ファイル名」として、実体ファイルへシンボリックリンクをかける。

/tftpbootディレクトリから、必要なファイルへ、クライアントから呼び出されるパス名・ファイル名で、シンボリックリンクをかける。全てのファイルにシンボリックリンクをかけると以下のような内容になる。

[root@pxeserver ~]# ls -l /tftpboot/
total 100
lrwxrwxrwx 1 root root   18 2008-06-17 11:17 \Boot\BCD -> winpe/x86/boot/bcd
lrwxrwxrwx 1 root root   23 2008-06-17 11:17 \boot\boot.sdi -> winpe/x86/boot/boot.sdi
lrwxrwxrwx 1 root root   35 2008-06-17 11:21 \Boot\en-US\bootmgr.EXE.MUI -> winpe/x86/pxe/en-US/bootmgr.exe.mui
lrwxrwxrwx 1 root root   33 2008-06-17 11:18 \Boot\Fonts\jpn_boot.ttf -> winpe/x86/boot/fonts/jpn_boot.ttf
lrwxrwxrwx 1 root root   34 2008-06-17 11:18 \Boot\Fonts\wgl4_boot.ttf -> winpe/x86/boot/fonts/wgl4_boot.ttf
lrwxrwxrwx 1 root root   35 2008-06-17 11:20 \Boot\ja-JP\bootmgr.EXE.MUI -> winpe/x86/pxe/ja-JP/bootmgr.exe.mui
lrwxrwxrwx 1 root root   25 2008-06-17 11:21 bootmgr.exe -> winpe/x86/pxe/bootmgr.exe
lrwxrwxrwx 1 root root   19 2008-06-17 11:22 \sources\boot.wim -> winpe/x86/winpe.wim
drwxr-xr-x 3 root root 4096 2008-06-17 11:15 winpe

ここで大文字、小文字の区別は意味があるので、この通りにリンクを張る必要がある。WinPEのバージョン等によって、ローダがtftpサーバへ要求するファイル名(の特に大文字小文字)が異なる可能性もあり、その場合tftpサーバは要求に応えられない。上手くtftpサーバからファイルをダウンロードできない場合は、ログを見ながら適宜修正する。

/etc/dhcpd.confの設定

PXEクライアントが最初にダウンロードするNBPが"pxeboot.n12"であることを知らせるために /etc/dhcpd.conf に次のようなクライアントの設定を追加する。(ここでは、PXEクライアントのホスト名を"disklesswin"という名前として/etc/hostsに登録してあるものとする。)

host disklesswin {
        hardware ethernet       01:23:45:67:89:AB; # PCのMACアドレス
        fixed-address           disklesswin; # /etc/hostsで定義されているホスト名
        next-server             192.168.100.97; # PXEサーバのIPアドレス
        filename                "/winpe/x86/pxe/pxeboot.n12";
        default-lease-time 1296000; # 2 weeks
        max-lease-time 2592000; # 4 weeks
}

/etc/dhcpd.conf を変更したらdhcpdサービスを再起動していおく。

[root@pxeserver ~]# service dhcpd restart

以上で設定は終了。Windows PEを動かしたいPCの電源を入れれば、ネットワークブートするはずである。(PCのBIOS設定で優先的にPXEでブートすることを忘れないように。)

ネットワークブートしてみる


で、無事にブート完了。

これでノートPCなどCDドライブのないPCでもWinPEが使えるので、システムのトラブルなどの修復作業が楽になる。

bootmgerのメッセージを日本語にしてみる

ブートのメッセージは英語のままである。これは、ブートの方法を指定するBCD(Boot Configuration Data)ファイルに言語として英語を使うように設定されているからだ。日本語でメッセージを出したければBCDを変更して、日本語をデフォルト言語にする。
BCDを変更するにはWinPEを一旦CDから立ち上げ、CDに入っているオリジナルのBCDを次の手順で変更する:

X:\windows\system32>copy D:\BOOT\BCD X:\Windows\Temp\bcd.ja-JP
        1 個のファイルをコピーしました。

X:\windows\system32>cd X:\Windows\Temp

X:\Windows\Temp>dir
 ドライブ X のボリューム ラベルは Boot です
 ボリューム シリアル番号は 0AD6-C20D です

 X:\Windows\Temp のディレクトリ

2008/01/19  17:45              .
2008/01/19  17:45              ..
2008/01/05  03:22           262,144 bcd.ja-JP
               1 個のファイル             262,144 バイト
               2 個のディレクトリ      31,764,480 バイトの空き領域

X:\Windows\Temp>bcdedit /store bcd.ja-JP /set {bootmgr} locale ja-JP
この操作を正しく終了しました。

X:\Windows\Temp>bcdedit /store bcd.ja-JP /set {default} locale ja-JP
この操作を正しく終了しました。

X:\Windows\Temp>bcdedit /store bcd.ja-JP /set {memdiag} locale ja-JP
この操作を正しく終了しました。

X:\Windows\Temp>dir
 ドライブ X のボリューム ラベルは Boot です
 ボリューム シリアル番号は 0AD6-C20D2 です

 X:\Windows\Temp のディレクトリ

2008/01/19  17:45              .
2008/01/19  17:45              ..
2008/06/17  12:27           262,144 bcd.ja-JP
               1 個のファイル             262,144 バイト
               2 個のディレクトリ      31,752,192 バイトの空き領域

X:\Windows\Temp>

新しく作った"bcd.ja-JP"を使ってPXEブートするように設定すれば日本語のメッセージになる。

無事にブートが終われば、わざわざ日本語で表示する必要性もない。が、

エラーが起きた時は少しは役に立つか。もっとも元のメッセージが意味不明なので、余り役に立たないかも。

参考にしたページと感想

今回はほとんど参考にするページはなかった。LinuxやBartPEのネットワークブートをやっていたので、大体は勘で出来てしまった。XPの時よりも素直に動いたし、WinPEの中にネットワークブート用のコマンドやツールが集められているので、やりやすかった。

*1:特殊といってもWindows PE 2.0はWindows Server 2003 SP1のカーネルntosknl.exeと全く同じファイルだった。