イメージファイルから起動する -- 2008-09-23  

概要  

通常、Linuxを起動するときはext3パーティションなどから起動しますが、例えばFAT32のファイルシステム上に置いたイメージファイルからLinuxが起動できれば、Windowsのデータディスク兼、Linuxシステムというものが作れます。つまり・・・

通常の使い方
 + HDDなど-------------------------------------------+
 |+-- パーティション1(ext3) --+-- パーティション2 --+|
 || Linuxシステム             | その他のものなど    ||
 |+---------------------------+---------------------+|
 +---------------------------------------------------+
このようにパーティションまるまるを使う

イメージファイルを使うなら・・・

 + SDカードやUSBメモリ --------------+
 |+-- パーティション(FAT32) --------+|
 || イメージファイル(Linuxシステム) ||
 || データファイルなど              ||
 |+---------------------------------+|
 +-----------------------------------+

こんな感じになります。イメージファイル内にLinuxシステムが構築されているので内容はイメージファイル(とその他のファイル)と通常のデータファイルになります。通常はWindowsで使うデータ用SDカード、しかし、そのSDカードからブートするとLinuxが起動する、ということが可能になります。もちろんLinuxからも通常のデータファイルは参照できます。Windowsからイメージファイル内のデータは見えませんが(何かソフトを使えばいいのかも)。
そんな設定をFAT32でフォーマットしたSDカード上で試してみました。

 

mkinitrdおよびgrubの操作、ext3イメージファイル作成の知識は必須です。

設定の指針  

Linuxのブートで使われるinitrd.img中のinitスクリプトを修正します。

この作業はinitrd.imgを展開して必要なファイルを追加したり編集した後、再度initrd.imgを構成することにより行います。なお、ここで用いるinitrd.imgはUSBからの起動に必要なファイルのセットアップをしてあるものとします(参考:Linux on USB)。ディストリビューションはVine Linux 4.2です。

実際の作業  

作業はrootで行います。適当なディレクトリ作成してその下で行うといいと思います。

initrd.imgの展開  

# cp /boot/initrd.img .
# mkdir work
# cd work
# gzip -dc ../initrd.img | cpio -idmv

まずinitrd.imgファイルを展開します。上記のコマンドでworkディレクトリ以下にinitrd.imgの内容が展開されます。いくつかのディレクトリとinitという名前のスクリプトができていると思います。このinitがブート時に実行される起動スクリプトで、これを修正することによりinitrdの挙動を制御することができます。

ディレクトリ構成  

私の場合のディレクトリ構成は以下のようになってました。

bin/
  insmod
  modprobe
  nash
dev/
  console, null, ram, systty, tty1, tty2, tty3, tty4
etc/
init               <-- 修正するinitスクリプト
lib/
  ehci-hcd.ko      <-- EHCIモジュール
  fat.ko           <-- FATモジュール
  ohci-hcd.ko      <-- OHCIモジュール
  scsi_mod.ko      <-- SCSIモジュール
  sd_mod.ko        <-- SDカードモジュール
  usb-storage.ko   <-- USBストレージモジュール
  vfat.ko          <-- VFAT(FAT32)モジュール
loopfs/            <-- 実パーティションのマウントポイントとして使います
proc/
sbin/
sys/
sysroot/           <-- 最終的にルートパーティションをマウントします

起動スクリプトファイルの編集  

必要なファイルがそろったら起動時に実行されるスクリプトファイルであるinitを編集します。

 1: #!/bin/nash
 2: 
 3: mount -t proc /proc /proc
 4: setquiet
 5: echo Mounted /proc filesystem
 6: echo Mounting sysfs
 7: mount -t sysfs none /sys
 8: echo "Loading ehci-hcd.ko module"     --- USBドライブの認識
 9: insmod /lib/ehci-hcd.ko
10: echo "Loading ohci-hcd.ko module"
11: insmod /lib/ohci-hcd.ko
12: echo "Loading scsi_mod.ko module"
13: insmod /lib/scsi_mod.ko
14: echo "Loading sd_mod.ko module"
15: insmod /lib/sd_mod.ko
16: echo "Loading usb-storage.ko module"
17: insmod /lib/usb-storage.ko
18: sleep 10                              --- ここまで
19: echo Creating block devices
20: mkdevices /dev
21: echo Creating root device
22: mkrootdev /dev/root
23: echo 1 > /sys/power/suspend2/do_resume
24: umount /sys
25: echo "Loading fat.ko module"                            
26: insmod /lib/fat.ko                                <-- FATモジュール
27: echo "Loading vfat.ko module"
28: insmod /lib/vfat.ko                               <-- VFAT(FAT32)モジュール
29: echo Mounting root device
30: /bin/mount -t vfat /dev/root /loopfs              <-- パーティションをマウント
31: echo Mounting root image file
32: mknod /dev/loop b 7 0                             <-- ループバックデバイスの作成
33: losetup /dev/loop /loopfs/rootfs.img              <-- イメージファイルを割り当て
34: mount -o defaults --ro -t ext3 /dev/loop /sysroot <-- イメージファイルをマウント
35: echo Switching to new root
36: switchroot /sysroot

環境によってはモジュールが異なるかもしれませんが、重要なのは25〜34行目の部分です。

  1. VFATモジュールをロードしてFAT32のファイルシステムを/loopfsにマウントします(25-30)。ここでマウントされる/dev/rootはgrub.conf(menu.lst)のカーネルオプションのroot=のデバイスが割り当てられます
  2. マウントしたファイルシステムにあるrootfs.imgというファイルを/sysrootにマウントします(31-34)
  3. 最後にマウントしたイメージにswitchrootして完了です

initrdファイルの作成と配置  

作業が完了したらinitrd.imgを作成します。

# find | cpio -H newc -o | gzip -9 > ../initrd.img

後はFAT32のSDカードにコピーしてGRUBをインストールすればOK。

SDカードのディレクトリ構成
/
  boot/
     grub/
        menu.lstなどのGRUBに必要なファイル
     vmlinuz    -- カーネル
     initrd.img -- 今回作成したinitrd
  rootfs.img    -- ルートファイルシステムイメージ
こんな感じで。とりあえず今回作成したinitではシステムイメージはrootfs.imgに固定されています。変数を駆使すればファイルを選択できるようになると思うのですが、nashでの変数の扱いがイマイチなのでとりあえずファイル名の選択はパスします(^^;。

感想 + 注意点  

このようにして16GBのSDカード上にセットアップして、Eee PC 901-Xで起動してみましたが問題なく起動しました(^^)。
まあ、わざわざここまでしてイメージファイルから起動する必要があるかは謎です [huh]。Windows用のデータSDと共存できるのでLinuxを起動するときにSDカードを入れ替えるという手間が省けるぐらいです。
ループバックデバイスをマウントするのに通常のmountが必要と以前書いていましたが、nashの組み込みコマンドであるlosetupを使用すれば必要ないようです。また、ループバックデバイスをセットアップ後は通常のパーティションと同じように扱えるので通常通り-o defaults --roでルートにマウントすればfsckで怒られることもないようです。
なお、パーティションがFAT32なのでイメージファイルの最大サイズは4GBなので注意しましょう。応用すればNTFSでもできると思います。

コメント