前回までにxorrisoのさまざまな機能を紹介してきました。紹介したのはxorrisoの機能のごく一部にすぎないものの、xorrisoの実力とISO9660ファイルシステムの持つ可能性を感じていただけたと思います。
xorrisoはこのように強力なソフトウェアなものの、機能が豊富すぎて(その結果ドキュメントも長大で)、初心者が手を出すにはやや敷居が高くなっています。
また、オプションの指定方法や意味等がLinuxでCD/DVDを作成する際のデファクト・スタンダートと言えるmkisofsやcdrecordと大きく異なってることも、xorrisoが敬遠される一因でしょう。
作者もそのあたりは気になったようで、xorrisoにはmkisofs/cdrecordとほぼ同じオプションが使えるエミュレーション機能が用意されています。今回はこのエミューレション機能と筆者がxorrisoを使うきっかけとなったBIOS/UEFIデュアルブートの話題を紹介しましょう。
xorrisoのエミュレーション機能
xorrisoには-as <personality>という指定で、<personality>に指定したコマンドをエミュレートする機能があります。<personality>にはmkisofsとcdrecordが指定でき、"mkisofs"を指定するとmkisofsのオプション体系が、"cdrecord"を指定するとcdrecordのオプション体系が、それぞれ利用可能になります。
xorrisoのmanページからこの機能を紹介した部分を引いてみましょう。参考のために私訳も付しておきます。
互換コマンド用エミュレーション
CDにISO9660を書き込むには、従来、ISO9660イメージ作成用のmkisofsと書き込み用のcdrecordが使われてきた。xorrisoは、それらコマンドを包括的にエミュレーションするわけではないが、主要な機能に関しては、それらコマンドが使用するオプションと共に利用可能になっている。
-as personality option [options] --
personalityとして指定したプログラムに、可変長のリストとして指定されたオプションを与えた際の処理をおおまかに模倣する。
すなわち、"xorriso -as mkisofs"とすると、mkisofsと同じオプションが使える、というわけです。指定可能なオプションは"-help"で一覧することができます。
この結果を"mkisofs -help"で表示されるmkisofsのオプション一覧と比較してみると、manページでsparse emulationと称しているとおり、両者はおおまかにしか重なりません。しかし、RockRidge形式を使うための"-R"、Joliet形式を使うための"-J"、出力先を指定する"-o"、ボリュームIDを指定する"-V"、起動処理回りの"-no-mul-boot","-eltorito-alt-boot"等、よく使う重要なオプションはカバーされており、普通に使う範囲では問題なさそうです。
事実、以前mkisofsを取り上げた回で紹介した実行例は"xorriso -as mkisofs ..."で対応できました。
この"-as <personality>"には、<personality>のコマンド名でxorrisoを起動すると自動的に有効になる、というショートカットも用意されています。すなわち、mkisofsという名前でxorrisoへのシンボリックリンクを張り、xorrisoをmkisofsという名前で起動すると、自動的に"-as mkisofs"オプションが指定されたことになるわけです。
エミュレーション機能でもうひとつ重要なpersonalityがcdrecordです。
こちらの方もcdrecordの主要な機能のみをカバーしている程度ですが、「mkisofsで作成したISOイメージをcdrecordで書き込む」という使い方の範囲は十分対応できます。また、このオプションもシンボリックリンクを利用してcdrecordという名前でxorrisoを起動すれば、自動的に有効になります。
エミュレーション機能を使えば、xorriso独自の機能を学ばなくても、従来通りのmkisofs/cdrecordのつもりでxorrisoを使うことができます。しかしながら、前回までに紹介してきたように、xorrisoにはISO9660ファイルシステムを自在に操作する便利な機能があるので、ぜひそれらも使いこなせるようになってください。
xorrisofsとBIOS/UEFIデュアルブート
さて、最後に筆者がxorrisoを調べるきっかけになった、DVD/USBメモリそれぞれのBIOS/UEFIのデュアルブートの話題を取りあげましょう。
xorrisoを取り上げた最初の回にも触れたように、筆者がこのソフトウェアを使うようになったきっかけは、mkisofs/cdrecordでは実現できなかった「DVDイメージをそのままUSBメモリにベタ書きしてもUEFIから起動できる」という機能を、Arch Linuxのインストーラが実現していたからでした。
たとえば、Arch Linuxのインストール用ISOの再構成方法を紹介したページ"Remastering the Install ISO"を見ると、このようなコマンドラインを使ってISOイメージを生成しています。
一方、以前紹介したように、Plamo Linuxのインストール用ISOイメージは、mkisofsを使って以下のようなコマンドラインにしていました。
xorrirsoのコマンドラインは最初に"-as mkisofs"を指定しているので、オプション等はmkisofsと同等になるはずですが、両者を見比べてみると、xorrisoには"-isohybrid-mbr"、"-isohybrid-gpt-basdat"といったmkisofsには存在しないオプションが追加されています。そこで、これらのオプションの意味を調べてみました。
まず、これらオプションの名前になっているisohybridという機能について紹介しておきましょう。"isohybrid"はCD/DVDからLinuxを起動する際に使われるisolinuxの一機能で、"isolinux"はその名の通りISO9660ファイルシステムからLinuxを起動するためのブートローダです。
上記使用例にあるように、mkisofsで"-b isolinux/isolinux.bin"を指定すると、あらかじめisolinuxディレクトリに用意されているisolinux.binが、ブートローダとしてISOファイルのシステム領域に書き込まれます。
起動メディアがCD/DVDだった場合、PCのBIOSは起動処理をISOファイルのシステム領域にゆだねるので、そこに用意されたisolinux.binが実行され、カーネルなど必要なファイルを読み込みます。
一方、このISOファイルをUSBメモリ等にベタ書きした場合、書きこまれた内容はISOファイルであっても、ハードウェアとしてのUSBメモリはBIOSからはHDDとして見えます。その結果、BIOSはisolinuxのあるISO9660のシステム領域ではなく、HDD(USBメモリ)の先頭にあるMBRに起動処理をゆだねようとするので、そのままではisolinuxが起動できません。
isohybridはこの間を繋ぐための開発されたツールで、isolinuxで起動するように作成したISOファイルの先頭部分に、isolinuxを呼び出すための擬似的なMBRを書き込みます。
この処理を施したISOファイルをベタ書きしたUSBメモリから起動すると、BIOSはUSBメモリをHDDと見なして擬似的なMBRを呼び出し、擬似的なMBRがisolinuxを起動して実際のカーネル等を読み込む、という2段ロケットのような方法でシステムが起動されることになります。
mkisofsを使っていたPlamo Linuxの場合、isohybrid処理はsyslinuxパッケージから提供されているisohybridというコマンドを使って、mkisofsで作成したISOファイルへの後処理として行っていました。
一方、xorriroの場合、syslinuxとの親和性が高まっていて、ISOイメージを作成する際に直接擬似的なMBRを書き込んでしまうことが可能です。そのためのオプションが-isohybrid-mbrで、上記Arch Linuxのコマンドラインでは"~/customiso/isolinux/isohdpfx.bin"を擬似的なMBRとしてISOファイルに埋めこんでいます。
擬似的なMBRは単純に書き込むだけではだめで、MBRから呼び出すisolinux.binの位置を、作成したISOファイルに合わせて登録する必要があります。そのためisohybridコマンドは作成済みのISOファイルへの後処理用のツールとして開発されたのに対し、xorrisoでは一歩進んでisohybridの機能を自らのうちに取り込んでいるわけです。
もう一つ-isohybrid-gpt-basdatもmkisofsにはないxorrisoの独自機能で、EFI用に用意されたブートイメージを"Basic Data"タイプの仮想的なGPTパーティションとしてパーティションテーブルに登録する、という処理を行います。
言葉で説明するだけではわかりにくいと思うので、このオプションがどう働くのか、具体的な例で紹介しましょう。
まず、Plamo Linux用に用意しているBIOSとUEFI用のブートローダをTestディレクトリにコピーしておきます。具体的には、UEFI用のブートローダを収めたEFIディレクトリとそのディレクトリをFAT16なファイルシステムに収めたefiboot.img、BIOS用のisolinux用のディレクトリを用意します。これらのファイルの意味や作り方については、本連載の過去記事を参照してください。
このディレクトリからxorrisoを使って起動可能なISOファイルを作ります。
もう1つ、オプションに"-isohybrid-gpt-basdat"を追加したISOファイルを作ってみます。
作成された2つのISOファイルのサイズは同じです。
一方、これらをfileコマンドで比べると、パーティションの表示が異なっていることに気づきます。
ISOファイルは一種のファイルシステムなので、fdiskを使って内部構造を調べることもできます。
この結果を見ると、-isohybrid-gpt-basdatオプションを指定した場合、ISOファイルの中に用意したefiboot.imgの領域(セクタで言えば136から65671)が、ESP(EFIシステムパーティション)としてパーティションテーブルに登録されていることがわかります。
この領域は実際にはISOファイルの一部なわけですが、仮想的なパーティションとしてパーティションテーブルに登録することで、UEFIにESPと思いこませ、そこにあるブートローダを起動させているわけです。
本来、ISOファイルにはパーティションテーブルは不要なので、このISOファイルをDVD等に書き込んで起動した場合、パーティションテーブルの部分は無視されます。
一方、ISOファイルをUSBメモリにベタ書きしUEFI環境でブートすると、USBメモリはHDDとして認識されるためHDDブートの処理が行なわれ、UEFIはパーティションテーブルを利用してブートローダを探すことになります。
これらの流れを整理してみましょう。
従来のPC BIOSから起動する場合、起動メディアがDVDならば、ISO9660の流儀に則ってisolinuxが実行されます。一方、起動メディアがISOイメージをベタ書きしたUSBメモリの場合、"-isohybrid-mbr"オプションでISOイメージの先頭に書き込まれた疑似MBR(isohdpfx.bin)が起動され、ここからisolinuxが呼び出されます。
一方、UEFI環境では、起動メディアがDVDの場合、UEFIはDVDを読み込んでそのディレクトリを調べ、EFIディレクトリにある/BOOT/BOOTx64.efiを起動します。起動メディアがUSBメモリの場合、UEFIはUSBメモリをHDDと認識してパーティションテーブルを探し、"-isohybrid-gtp-basdat"で作成した仮想ESPを読み込んで、そこにある/BOOT/BOOTx64.efiを起動します。
ISOファイルの先頭部分には未使用領域があることを利用して、そこに疑似MBRと仮想パーティションテーブルを用意すれば、1つのISOファイルでDVDとUSBメモリ、さらにはPC BIOSとUEFIを使いわけてブートできる、このテクニックに気付いた時は、優れたミステリーを読み終えた時のような興奮を覚えました。
以前触れたように、mkisofsを使っていたころは、「ISOイメージをベタ書きしたUSBメモリからUEFI起動できない」という問題が気になっていました。
今回、xorrisoをイジってみて、このトラブルの原因は、ISOイメージにESPを登録したパーティションテーブルが存在していなかったからだ、とわかり、長年ひっかかっていたトゲがやっと抜けたような気分になりました(苦笑)。
ソフトウェアの世界では、この種の「コロンブスの卵」的なアイデアやテクニックはあちこちに隠れています。ドキュメントやソースコードを手掛りにそれらを読み解いていくのも、フリーソフトウェアの魅力のひとつと言えるでしょう。