* イメージファイルから起動する -- 2008-09-23 [#ff6b93eb]
 ** 概要 [#ydd85690]
 通常、Linuxを起動するときはext3パーティションなどから起動しますが、例えばFAT32のファイルシステム上に置いたイメージファイルからLinuxが起動できれば、Windowsのデータディスク兼、Linuxシステムというものが作れます。つまり・・・
  通常の使い方
   + HDDなど-------------------------------------------+
   |+-- パーティション1(ext3) --+-- パーティション2 --+|
   || Linuxシステム             | その他のものなど    ||
   |+---------------------------+---------------------+|
   +---------------------------------------------------+
  このようにパーティションまるまるを使う
 イメージファイルを使うなら・・・
   + SDカードやUSBメモリ --------------+
   |+-- パーティション(FAT32) --------+|
   || イメージファイル(Linuxシステム) ||
   || データファイルなど              ||
   |+---------------------------------+|
   +-----------------------------------+
 こんな感じになります。イメージファイル内にLinuxシステムが構築されているので内容はイメージファイル(とその他のファイル)と通常のデータファイルになります。通常はWindowsで使うデータ用SDカード、しかし、そのSDカードからブートするとLinuxが起動する、ということが可能になります。もちろんLinuxからも通常のデータファイルは参照できます。Windowsからイメージファイル内のデータは見えませんが(何かソフトを使えばいいのかも)。~
 そんな設定をFAT32でフォーマットしたSDカード上で試してみました。
 #br
 mkinitrdおよびgrubの操作、ext3イメージファイル作成の知識は必須です。
 
 ** 設定の指針 [#g89af983]
 Linuxのブートで使われるinitrd.img中のinitスクリプトを修正します。
 - FAT32用ドライバモジュールの追加
 - initの修正
 
 この作業はinitrd.imgを展開して必要なファイルを追加したり編集した後、再度initrd.imgを構成することにより行います。なお、ここで用いるinitrd.imgはUSBからの起動に必要なファイルのセットアップをしてあるものとします(参考:[[Linux on USB>../Linux on USB]]。ディストリビューションはVine Linux 4.2です。
 この作業はinitrd.imgを展開して必要なファイルを追加したり編集した後、再度initrd.imgを構成することにより行います。なお、ここで用いるinitrd.imgはUSBからの起動に必要なファイルのセットアップをしてあるものとします(参考:[[Linux on USB>../Linux on USB]])。ディストリビューションはVine Linux 4.2です。
 
 ** 実際の作業 [#gbd07949]
 作業はrootで行います。適当なディレクトリ作成してその下で行うといいと思います。
 
 *** initrd.imgの展開 [#w9c787d5]
  # cp /boot/initrd.img .
  # mkdir work
  # cd work
  # gzip -dc ../initrd.img | cpio -idmv
 まずinitrd.imgファイルを展開します。上記のコマンドでworkディレクトリ以下にinitrd.imgの内容が展開されます。いくつかのディレクトリと''init''という名前のスクリプトができていると思います。このinitがブート時に実行される起動スクリプトで、これを修正することによりinitrdの挙動を制御することができます。
 
 *** ディレクトリ構成 [#tc9b8175]
 私の場合のディレクトリ構成は以下のようになってました。
  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/           <-- 最終的にルートパーティションをマウントします
 
 *** 起動スクリプトファイルの編集 [#g8cf772c]
 必要なファイルがそろったら起動時に実行されるスクリプトファイルである''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行目の部分です。
 + VFATモジュールをロードしてFAT32のファイルシステムを/loopfsにマウントします(25-30)。ここでマウントされる/dev/rootはgrub.conf(menu.lst)のカーネルオプションのroot=のデバイスが割り当てられます
 + マウントしたファイルシステムにあるrootfs.imgというファイルを/sysrootにマウントします(31-34)
 + 最後にマウントしたイメージにswitchrootして完了です
 
 *** initrdファイルの作成と配置 [#jdb36960]
 作業が完了したら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での変数の扱いがイマイチなのでとりあえずファイル名の選択はパスします(^^;。
 
 ** 感想 + 注意点 [#d69ef861]
 このようにして16GBのSDカード上にセットアップして、Eee PC 901-Xで起動してみましたが問題なく起動しました(^^)。~
 まあ、わざわざここまでしてイメージファイルから起動する必要があるかは謎です&huh;。Windows用のデータSDと共存できるのでLinuxを起動するときにSDカードを入れ替えるという手間が省けるぐらいです。~
 ループバックデバイスをマウントするのに通常のmountが必要と以前書いていましたが、nashの組み込みコマンドであるlosetupを使用すれば必要ないようです。また、ループバックデバイスをセットアップ後は通常のパーティションと同じように扱えるので通常通り-o defaults --roでルートにマウントすればfsckで怒られることもないようです。~
 なお、パーティションがFAT32なのでイメージファイルの最大サイズは4GBなので注意しましょう。応用すればNTFSでもできると思います。
 
 ** コメント [#i2091207]
 #comment