2011年5月5日(木) 忙しいったらありゃしない [同日]
○ [memo][Linux] MeeGoのLive CDイメージを分解して書き込み可能で起動できるようにする
Momongaとか MeeGoとか、ライブCDのイメージが リリースされていてうれしいです。 手元のPCのハードディスクにインストールしないでも使ってみられる。 でも、残念ながらファイルシステムに書き込み不可能 (再起動すると変更が無かったことになる)なっちゃいます。 最近のUSBフラッシュメモリの容量は充分に大きいようなので、ライブCDから 普通に書き込み可能なファイルシステムをとりだして、 ブートできるようにしてみました。 なんかおもちゃもできてきたしね。
ここでは、 http://meego.com/downloads http://repo.meego.com/MeeGo/builds/1.1.99/latest/images/meego-netbook-ia32/ より、 ベータ版のMeeGo v1.2 for Netbooks (meego-netbook-ia32-1.1.99.5.20110503.6.img) を使ってみます。 ISOLinuxを使っているライブCDなら同様の手順で作業できると思います。
手順のまとめ。作業用のLinux上で、 img/ディレクトリ以下にダウンロードしたLiveCDのイメージを置き、 USBフラッシュメモリが/dev/sdeにある場合は下記のようにします。 USBフラッシュメモリのデバイスファイル名は、 USBフラッシュメモリを挿入してからdmesgなどを実行して確認してください。 (書く先を間違えると作業用のLinuxのファイルを消しちゃうことになりますよね。 なお、ここではbtrfsを使っています。 btrfsに貴重な情報を預けるのは、まだ、避けて置いた方が良いかもしれません。 作業に使ったMomonga 7のmkfs.btrfsは「Btrfs v0.19 IS EXPERIMENTAL」と警告を表示しますし、 スリープ(ハイバネーション?)から復帰できなくなったMeeGoの電源を強制的に切った後、 btrfsがマウントできなくなることも一度ありました。
まずfdisk /dev/sdeで必要なパーティションを切ります。 手元では、4GBのフラッシュメモリの最初の512MB (sde1) をFAT32 (ID 0x0C)に、 残り (sde2) をLinux (ID 0x83)してみました。
起動するOSのルートファイルシステムを作ってマウントしておきます。 起動してくるOSがルートファイルシステムを見つけられるように ラベルを付けておくのを忘れない。 mkfs.btrfsはbtrfs-progsパッケージにあります。
# mkfs.btrfs -L meego-root /dev/sde2 # mount -o ssd,compress /dev/sde2 /mnt/tmp
起動するOSのルートファイルシステムをループバックマウントして フラッシュメモリにコピー。
$ mkdir lo $ mkdir lo2 $ mkdir lo3 # mount -o loop img/meego-netbook-ia32-1.1.99.5.20110503.6.img lo # mount -o loop lo/LiveOS/squashfs.img lo2/ # mount -o loop lo2/LiveOS/ext3fs.img lo3 # cp -a lo3/* /mnt/tmp
cpをしている途中に 「cp: writing `/mnt/tmp/usr/share/icons/gnome/icon-theme.cache': デバイスに空き領域がありません」 などというエラーが出ることがあります。 全体としてはうまくいっているようなので、念のためcpが終了してから エラーのあったファイルだけもう一度上書きコピーしておいてみました。
起動後の状態に合わせて/mnt/tmpの/etc/fstabの ルートファイルシステムの行を編集しておきます。
/dev/root / btrfs ssd,compress 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 tmpfs /dev/shm tmpfs defaults 0 0 proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0
ルートファイルシステム側で必要な作業はここまで。
# umount /mnt/tmp
次にカーネルとinitrdを入れておく方のパーティションを作ります。 grubのファイルもここに入れます。
# mkfs.vfat /dev/sde1 # mount /dev/sde1 /mnt/tmp # grub-install --root-directory=/mnt/tmp /dev/sde # cp -a lo/isolinux/vmlinuz0 /mnt/tmp/boot/meego-vmlinuz # cp -a lo/isolinux/initrd0.img /mnt/tmp/boot/meego-initrd.img
grubのためのメニュー。 カーネルオプションにquietを加えると起動しなかったのは、 USBメモリを読むカーネルモジュールが安定する前に ルートファイルシステムをマウントしようとしたりしてるのでしょうか?
default=0 timeout=3 title MeeGo kernel /boot/meego-vmlinuz root=LABEL=meego-root initrd /boot/meego-initrd.img title Normal Harddisk map (hd0) (hd1) map (hd1) (hd0) rootnoverify (hd0) chainloader +1
これで作業終了です。
# umount /mnt/tmp # umount lo3 # umount lo2 # umount lo
これで作業はおしまい。ちゃんと起動しますように。
さて、もう少し詳細についても記録しておきます。
fdiskでのパーティションの作成。 sde1は普通のフラッシュメモリとしても使えるようにするためにFAT32にしましたが、 必要が無ければLinuxでも良いですよね。 今回は起動するOSのルートファイルシステムをbtrfsにしたいのですが、 GRUBがbtrfsを読んでくれるかどうか定かではなかったので、 パーティションを2つに分けて、 カーネルとinitrdはGRUBが確実に読める場所にしました。 これまた、ルートファイルシステムをext2などにする場合にはパーティションは 1つで良いかもしれません。
ルートファイルシステムの内容。 下記はmeego-netbook-ia32-1.1.99.5.20110503.6.imgではなく meego-netbook-ia32-1.1.imgを使った作業からの記録です。 meego-netbook-ia32-1.1.99.5.20110503.6.imgでも大きな違いはないはず。
LiveCDのイメージをどんどんループバックマウントして内容を見てみました。
# mount -o loop img/meego-netbook-ia32-1.1.img lo
mount: warning: lo seems to be mounted read-only.
$ tree lo
lo
├── LiveOS
│ ├── osmin.img
│ └── squashfs.img
└── isolinux
├── boot.cat
├── initrd0.img
├── isolinux.bin
├── isolinux.cfg
├── splash.jpg
├── vesamenu.c32
└── vmlinuz0
2 directories, 9 files
isolinux.cfgの中には起動オプションがいくつか見えました。 下記は抜粋です。
label linux0 menu label Boot MeeGo kernel vmlinuz0 append initrd=initrd0.img root=CDLABEL=netbook-ia32-x86_64-201010261558 rootfstype=iso9660 ro liveimg quiet label liveinst0 menu label Installation Only kernel vmlinuz0 append initrd=initrd0.img root=CDLABEL=netbook-ia32-x86_64-201010261558 rootfstype=iso9660 ro liveimg quiet liveinst nosplash 4 label local menu label Boot from local drive localboot 0xffff
たぶん、isolinux/vmlinuz0とisolinux/initrd0.imgがそれぞれ カーネルとinitrdのイメージでしょう。
LiveOS/osmin.imgの中にはファイルは無いようでした。
# mount -o loop lo/LiveOS/osmin.img lo2/ $ tree lo2 lo2 └── osmin 0 directories, 1 file # umount lo2
LiveOS/squashfs.imgの中にはext3のイメージが入っているみたい。 この辺が、 起動中は書きこめるファイルシステムへの変更点が再起動すると無くなっちゃう (というか、CDという書き込み不可のメディアに記録されたファイルシステムに、 起動中だけでも書き込んだように見せられる)、カラクリなのかも。 とにかく、このext3fs.imgの内容をルートファイルシステムとして見せてあげれば 良さそうです。
# mount -o loop lo/LiveOS/squashfs.img lo2/
# tree lo2
lo2
└── LiveOS
└── ext3fs.img
1 directory, 1 file
# mount -o loop lo2/LiveOS/ext3fs.img lo3
$ ls lo3/
bin/ dev/ home/ lost+found/ mnt/ proc/ sbin/ sys/ usr/
boot/ etc/ lib/ media/ opt/ root/ srv/ tmp/ var/
$ cat lo3/etc/fstab
/dev/root / ext3 defaults,noatime 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
tmpfs /dev/shm tmpfs defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
これだけでは、ライブCDとして走っているカーネルが、 自分のルートファイルシステムをどうやって SquashFSそしてext3としてループバックマウントしているのか理解することは できませんでした。 というわけで、 ISOLinuxの動作についてはもう少し調べてみたいような気もするのでした。 initrdの中の/initを覗いてみたりもしたのだけれどよくわからなかった。 (追記) オライリーのProgrammer's High、番外編: LiveCDのファイルシステム(1)、番外編: LiveCDのファイルシステム(2)が参考になるかもしれない。
そうそう、Momonga 7 LiveCDはMeeGoと同じく ライブCDのイメージにブートローダが含まれていて、 そのままUSBフラッシュメモリに書けば (dd if=<イメージ> of=/dev/sde) 起動するようになりましたが、 Android x86ではブートローダが含まれていなくて、 ライブCDとして起動するためにも自前でブートローダを書きこむ必要がありました。 Android x86は起動しても手元のDell E4200ではタッチパッドが効かなかったのが残念。
ルートファイルシステムの容量。 上記の作業 (meego-netbook-ia32-1.1.99.5.20110503.6.img) でLiveOS/ext3fs.imgの内容を USBフラッシュメモリのbtrfsにコピーした結果、
# df /mnt/tmp/ Filesystem 1K-ブロック 使用 使用可 使用% マウント位置 /dev/sde2 3392512 1220552 2171960 36% /mnt/tmp
となりました。 つまり、btrfsにcompressオプションを付けてコピーした結果、必要な容量は1192 MB。 これに対して、 ライブCD自体のイメージは882MB、LiveOS/squashfs.imgは875MBでした。 LiveOS/ext3fs.img (このファイル自体の容量は、 たぶんext3ファイルシステムとしての空きの部分も含めて3.0GB) をループバックマウントした先をdu -smすると2030MBとのこと。 ということは、含まれるファイルの容量に対してファイルシステムのイメージの容量を、 SquashFSは875/2030=43%に、 btrfs (compress,ssd) は1192/2030=59%に縮めてることになります。 たいしたもんだねえ。 SquashFSの中のext3からbtrfsにファイルをコピーするのに時間がかかるのも、 これだけの伸張と圧縮をしてると思うと、うなずけました。
最近のツッコまれどころ