注意:PCメーカーやMicrosoftの推奨する方法ではありません。壊れにくいような手順は取っていますが、重要なシステムに適用することはおすすめしません。普通に回復ディスクを使うのが楽だと思います。どちらかというと、仕組みを読み取ってもらえれば幸いです。
手順の概要
最近のWindowsの起動時の設定はBoot Configuration Data (BCD) というところに格納されており、ここにセーフモードで起動するかどうかの設定も入っている。そこで、このBCDをUSBメモリからブートしたUbuntuを使って書き換えることで、Windowsをセーフモードで起動させる。なおBCD書き換えの際、標準外のツールを使うため、ファイルが壊される可能性を考慮して、セカンダリBCDストアを構成し、そちらの設定を変更することにする。
図にすると以下の通り。
環境/必要なもの
対象の環境は、UEFIで稼動するWindows。Windows 10で検証したが、Vista以降ならいけると思う。また、必要なものはUbuntu 14.04 (or later) のブータブルUSBメモリ や DVD。すでにデュアルブート環境なら、それでも問題ない。
一応、検証した環境(VirtualBox)でのbcdeditコマンドの出力結果はこんな感じ。
Windows ブート マネージャー -------------------------------- identifier {bootmgr} device partition=\Device\HarddiskVolume2 path \EFI\Microsoft\Boot\bootmgfw.efi description Windows Boot Manager locale ja-JP inherit {globalsettings} default {current} resumeobject {43ea4f06-91dc-11e5-8faa-ac88953b08c0} displayorder {current} toolsdisplayorder {memdiag} timeout 30 Windows ブート ローダー -------------------------------- identifier {current} device partition=C: path \Windows\system32\winload.efi description Windows 10 locale ja-JP inherit {bootloadersettings} recoverysequence {43ea4f08-91dc-11e5-8faa-ac88953b08c0} recoveryenabled Yes isolatedcontext Yes allowedinmemorysettings 0x15000075 osdevice partition=C: systemroot \Windows resumeobject {43ea4f06-91dc-11e5-8faa-ac88953b08c0} nx OptIn bootmenupolicy Standard
手順
1) セカンダリブートパス・セカンダリBCDストアの構成
1-1) Ubuntuの起動
ブータブルUSBメモリなどでUbuntuを起動する。1-2) EFI システムパーティション (ESP) のマウント
Ubuntuが起動したら、EFI システムパーティションをどこか適当な場所にマウントする。マウントしたら、EFI/Microsoft/Boot/BCDが存在することを確認しておく。$ sudo parted /dev/sda print モデル: ATA VBOX HARDDISK (scsi) ディスク /dev/sda: 34.4GB セクタサイズ (論理/物理): 512B/512B パーティションテーブル: gpt 番号 開始 終了 サイズ ファイルシステム 名前 フラグ 1 1049kB 473MB 472MB ntfs Basic data partition hidden, diag 2 473MB 578MB 105MB fat32 EFI system partition boot 3 578MB 595MB 16.8MB Microsoft reserved partition msftres 4 595MB 34.4GB 33.8GB ntfs Basic data partition msftdata $ sudo mkdir /mnt/efi $ sudo mount /dev/sda2 /mnt/efi $ find /mnt/efi -name BCD /mnt/efi/EFI/Microsoft/Boot/BCD ←Microsoft/Boot/BCDが存在することを確認 /mnt/efi/EFI/Microsoft/Recovery/BCD
1-3) Microsoftディレクトリのコピー
EFIアプリケーションであるWindows Boot Manager (bootmgfw.efi)及びその設定であるBoot Configuration Data (BCD)が含まれるMicrosoftディレクトリをコピーする。$ cd /mnt/efi/EFI $ sudo cp -pr Microsoft MicrosoftSafeMode
手順参考:Windows RE を起動するためのハードウェア回復ボタンの追加
2) セカンダリBCDストアのBCDの書き換え
2-1) hivexregeditツールのインストール
設定が格納されているBCDは、レジストリハイブの形式をとっている。そこで、レジストリハイブを編集できる「hivexregedit」ツールを使えるようにする。「hivexregedit」ツールは、libwin-hivex-perlパッケージに入っているので、これをインストールすればOK。
$ sudo apt-get install libwin-hivex-perlなお、他にもレジストリハイブを扱うツールがlibhivex-binパッケージにいくつか入っているので、必要があれば入れる。
2-2) BCDファイルをレジストリエディタ形式にエクスポート
hivexregeditの--exportオプションを使って、BCDの内容を*.regファイルでおなじみの形式にエクスポートする。$ hivexregedit --unsafe-printable-strings --export /mnt/efi/EFI/MicrosoftSafeMode/Boot/BCD '\' > /tmp/bcd.regこれにより、テキストエディタやビューワで表示が可能になった。--unsafe-printable-stringsをつけないと、文字列が軒並みhex表記になって見れたもんじゃない。
2-3) Windows Boot Managerのobjectを探す
@junichia氏のブログエントリ「ブート構成データ(BCD)ストアを理解すれば VHDブート は簡単」に図があるので見て欲しいのだけど、BCDにはひとつのWindows Boot Managerのobjectと、複数のWindows Boot Loaderのobjectがある。Boot Loader側にsafe modeの設定もあるのだけど、まずはどれがdefaultで利用されているBoot Loaderか確認するため、Boot Manager側のobjectを探し出す。boot managerのオブジェクトを探し出すには「bootmgfw.efi」を文字列検索するのが簡単。
$ less /tmp/bcd.reg (/で検索) [\Objects\{9dea862c-5cdd-4e70-acc1-f32b344d4795}\Elements\12000002] "Element"=str(1):"\EFI\Microsoft\Boot\bootmgfw.efi^@" [\Objects\{9dea862c-5cdd-4e70-acc1-f32b344d4795}\Elements\12000004] "Element"=str(1):"Windows Boot Manager"
これで、boot managerのオブジェクトのGUIDが「{9dea862c-5cdd-4e70-acc1-f32b344d4795}」であることがわかった。
なお、各項目はElements\以下の数値で何か判断することが可能である。上記における「12000002」は「BcdLibraryString_ApplicationPath」でbcdeditコマンドでは「path」として表示される。同様に「12000004」は「BcdLibraryString_Description」でbceditコマンドでは「description」である。それぞれの数値が何を意味するかは、MSDNにも記述があるのだが、Geoff Chappell氏の「BCD Elements」が見やすくておすすめである。
2-4) Widnows Boot Managerのobjectから「default」を探し出す
Boot Managerがわかったので、そのGUIDを利用して、デフォルトのBoot Loaderの指定を探し出す。デフォルトのBoot Loaderが記述されているのはBcdBootMgrObject_DefaultObject (default)で「23000003」である。$ less /tmp/bcd.reg (/で検索) [\Objects\{9dea862c-5cdd-4e70-acc1-f32b344d4795}\Elements\23000003] "Element"=str(1):"{43ea4f07-91dc-11e5-8faa-ac88953b08c0}"
ここでデフォルトのBoot Loaderが{43ea4f07-91dc-11e5-8faa-ac88953b08c0}であることがわかった。一応、{43ea4f07-91dc-11e5-8faa-ac88953b08c0} のBcdLibraryString_ApplicationPath (path) 「12000002」及び BcdLibraryString_Description (description) 「12000004」を確認しておく。
$ less /tmp/bcd.reg (/で検索) [\Objects\{43ea4f07-91dc-11e5-8faa-ac88953b08c0}\Elements\12000002] "Element"=str(1):"\Windows\system32\winload.efi" [\Objects\{43ea4f07-91dc-11e5-8faa-ac88953b08c0}\Elements\12000004] "Element"=str(1):"Windows 10"これでいいようだ。
2-5) Boot Loader objectにセーフモード設定を組み込む
Boot Loaderのobjectにセーフモード関連のElementを追加する*.regファイルを作り、それをhivexregeditの--mergeオプションを使って組み込む。項目がいくつかあるので後の表を見て欲しいが、例えばmsconfigで言うところのセーフモード: 代替シェルで起動する記述は以下の通りである。生成したbcd.regをコピーして作るのが楽。
$ cp /tmp/bcd.reg /tmp/bcd-safe.reg $ vi /tmp/bcd-safe.reg ~~~ Windows Registry Editor Version 5.00 [\Objects\{43ea4f07-91dc-11e5-8faa-ac88953b08c0}\Elements\25000080] "Element"=hex(3):00,00,00,00,00,00,00,00 [\Objects\{43ea4f07-91dc-11e5-8faa-ac88953b08c0}\Elements\26000081] "Element"=hex(3):01 ~~~上記の例ではBcdOSLoaderInteger_SafeBoot (safeboot) 「25000080」を「Minimal」にし、BcdOSLoaderBoolean_SafeBootAlternateShell (やsafebootalternateshell) 「26000081」をtrueにしている。
以下は検証したわけではないが、msconfig.exeの「ブート」タブの表示(以下参考)とbcdeditの出力を見ながら、「BCD Elements」とつきあわせて表にまとめたものが以下となる。
msconfigの項目 | bcdeditの項目 | 名称 | Element | 備考 |
---|---|---|---|---|
- | path | BcdLibraryString_ApplicationPath | 12000002 | string |
- | description | BcdLibraryString_Description | 12000004 | string |
- | default | BcdBootMgrObject_DefaultObject | 23000003 | GUID |
セーフブート | safeboot | BcdOSLoaderInteger_SafeBoot | 25000080 | 0: 最小(Minimal) / 1: ネットワーク(Network) / 2: Active Directory修復(DsRepair) |
(代替シェルのときのみ) | safebootalternateshell | BcdOSLoaderBoolean_SafeBootAlternateShell | 26000081 | boolean |
GUI ブートなし | quietboot | BcdOSLoaderBoolean_DisableBootDisplay | 26000041 | boolean |
ブートログ | bootlog | BcdOSLoaderBoolean_BootLogInitialization | 26000090 | boolean |
基本ビデオ | vga | BcdOSLoaderBoolean_UseVgaDriver | 26000040 | boolean |
OS ブート情報 | sos | BcdOSLoaderBoolean_VerboseObjectLoadMode | 26000091 | boolean |
regファイルを作ったら、--mergeでmergeする。
$ sudo hivexregedit --merge /mnt/efi/EFI/MicrosoftSafeMode/Boot/BCD /tmp/bcd-safe.reg
再度hivexregedit --exportしてみて、組み込まれていればOK。
2-6) umount
言うまでもないかもしれないが、umountしておく。$ sudo umount /mnt/efi
3) grubから新しいBCDを使って起動
UbuntuをEFIで起動しているということは、EFIで動作するgrubが使えるということである。そこで、そのgrubを利用して上記で作ったセカンダリブートパス・BCDストアを選択して起動する。再びUbuntu ブータブルUSBメモリで再起動し、grubメニューが現れたら、「c」キーを押しコンソールモードに切り替える。切り替わったら、以下のように入力して、新しいbootmgfw.efiを使って起動する。
grub> set root=(hd0,gpt2) grub> chainloader /efi/MicrosoftSafeMode/Boot/bootmgfw.efi grub> boot
hdのパスはPCによって異なるはずなので、以下の図のようにTAB補完を活用しながら入力するとよい。
これでセーフモードで立ち上がってくれば成功。とくにEFI firmware側の設定は変更していないので、ブータブルUSBメモリを外して普通に起動すれば元通り。気になるようであれば、EFIシステムパーティションから今回作ったディレクトリを削除しておけばOKである。