玩式草子─ソフトウェアとたわむれる日々

第12回P-Plamoのカスタマイズその2]

P-Plamoでは、Plamo Linuxの標準的な環境を元にパッケージを選定していますが、contrib以下のパッケージを追加したい場合や不要なパッケージを削除してよりコンパクトにしたい場合もあるでしょう。今回はそのようなパッケージレベルでのカスタマイズ方法について紹介しましょう。

前回までに紹介したように、P-Plamoでは通常のPlamo Linuxの環境を書き込み不可なsquashfsファイルとして用意しておき、その上にaufsのレイヤを被せて読み書き可能なルートファイルシステムを構成しています。

squashfsは、多数のファイルが存在するファイルシステムを高い圧縮率で一つのファイルに畳み込む便利な機能ですが、圧縮率が高い分、圧縮処理には時間がかかるため、あまり頻繁には作り直せません。

そのため現在のP-Plamoでは、小規模な変更はsquashfsではなくinitrd上に用意して、システム起動時のinitスクリプトで必要なファイルの入れ替えを行うようにしていますが、この方法の場合、tmpfs経由でメモリ上に割りあてたaufs上に修正すべきファイルをコピーするので、修正ファイルが増えればそれだけ使用可能なメモリが減ってしまうため、パッケージ更新のような大規模な修正には適しません。

一方、squashfsレベルでの修正は、作成にこそ時間はかかるものの、作成されたsquashfsファイルは必要に応じて読み出されるので、メモリを圧迫することはありません。修正の規模や内容に応じて、この2つの方法を使い分けるのがP-Plamoのカスタマイズのポイントでしょう。

squashfsファイルの展開

squashfsは書き込みや変更ができないファイルシステムなので、修正するためにはいったんHDD上に展開して、必要な変更を加えた上で再生成する必要があります。このための作業にはHDD上に10GB程度の領域と、squashfsを作成するためのツールmksquashfsが必要です。このツールはPlamo-4.72に含まれているので、以下では前回作成したUSBメモリ版のP-PlamoをPlamo-4.72上で改造する手順を紹介しましょう。

以下ではUSBメモリは/dev/sdb1と認識されて/media/disk/にマウントされており、squashfsファイルを展開する作業用の領域は/mnt/P-Plamo/Contents/以下に取ることにします。

まず、squashfsファイルをloopback形式で適当な場所にマウントします。

# mkdir /tmp/loop
# mount -o loop /media/disk/isolinux/rootimg.squash /tmp/loop
# df -h
Filesystem          サイズ  使用  残り 使用% マウント位置
/dev/sda1              19G  8.8G  8.8G  50% /
none                 1013M  184K 1013M   1% /dev
/media               1013M  4.0K 1013M   1% /media
...
/dev/sdb1             3.8G  1.6G  2.2G  42% /media/disk
/dev/loop0            1.6G  1.6G     0 100% /tmp/loop

Plamo-4.72ではsquashfsモジュールもあらかじめ用意され、必要に応じて自動的に組み込まれるので、loopback形式でマウントしたrootimg.squashの中身は透過的に見えます。

# ls -lh /tmp/loop
合計 0
drwxr-xr-x  2 root root  862  3月  4日  15:45 bin/
drwxr-xr-x  2 root root  166  3月 28日  01:24 boot/
drwxr-xr-x  2 root root    3  3月  4日  17:10 cdrom/
...
drwxr-xr-x 21 root root  412 10月  5日 2009年 var/

この/tmp/loop/以下のファイルを/mnt/P-Plamo/Contents/以下にコピーします。

# cd /tmp/loop ; cp -av * /mnt/P-Plamo/Contents/
`bin' -> `/mnt/P-Plamo/Contents/bin'
`bin/Mail' -> `/mnt/P-Plamo/Contents/bin/Mail'
`bin/bash' -> `/mnt/P-Plamo/Contents/bin/bash'
`bin/bash-static' -> `/mnt/P-Plamo/Contents/bin/bash-static'
 ...

なお、ファイルシステムを圧縮してsquashfsファイルを生成するmksquashfsと対になる、unsquashfsというコマンドも存在します。このコマンドは名前が示すようにsquashfsを展開するためのツールで、このコマンドを使えばマウントせずにsquahfsファイルから直接中身を取り出すことも可能です。

約5GB強を書き出すためそれなりに時間がかかりますが、こうして取り出したP-Plamoのsquashfsファイルの中身はHDD上で自由に変更することができます。

# du -h
4.2M    /mnt/P-Plamo/Contents/bin
3.5M    /mnt/P-Plamo/Contents/boot
...
23M     /mnt/P-Plamo/Contents/var
5.4G    /mnt/P-Plamo/Contents/

squashfsファイルの修正

上述のように書き出したsquashfsファイルの中身は、ライブラリなども含む完結したLinux環境なので、chrootコマンドでルートファイルシステムを変更すれば、その環境下でremovepkgupdatepkg等のパッケージ管理コマンドを利用できます。今回はパッケージ管理コマンドを使って、Googleが提供しているウェブブラウザGoogle Chromeをインストールしてみましょう。

Google ChromeはPlamo Linuxのパッケージには正式採用されていませんが、FTPサイトのcontrib/以下、あるいはPlamo-test/for-4.7x/からダウンロードできます。本稿執筆時点では、最新版のGoogle Chrome 5.0.375.99 がPlamo-test/for-4.7x/にあります。

% wget ftp://plamo.linet.gr.jp/pub/Plamo-test/for-4.7x/google_chrome-5.0.375.99-i386-P1.tgz
 ....
2010-07-09 23:00:21 (22.2 MB/s) - `google_chrome-5.0.375.99-i386-P1.tgz' へ保存終了 [25479801]

なお、このPlamo-test/以下のディレクトリはテスト段階のパッケージの置き場なので、テストが終わればPlamo-4.7/contrib/以下に移動しているはずなので、上記URLにファイルが無ければPlamo-4.7/contrib/以下で探してください。

Google Chromeはlibbz2.so.1.0というbzip2の共有ライブラリを必要とします。従来のPlamo Linuxのbzip2パッケージには、この共有ライブラリは含まれていませんでしたが、最近は共有ライブラリを含むようにパッケージが修正されたので、bzip2パッケージもダウンロードしておきます。

% wget ftp://plamo.linet.gr.jp/pub/Plamo-4.7/plamo/00_base/bzip2-1.0.5-i586-P4.tgz
...
2010-07-09 23:05:49 (3.30 MB/s) - `bzip2-1.0.5-i586-P4.tgz' へ保存終了 [132090]

これらのパッケージで先に取り出したsquashfs用の環境を更新します。そのためにはsquashfs用の環境にchrootして、その環境内でパッケージ管理ツールを利用するのが簡単です。chrootすると、そのディレクトリ以下のファイルしか見えなくなるので、更新用のパッケージはあらかじめchroot先の適切な場所に移動しておきます。

# mv google_chrome-5.0.375.99-i386-P1.tgz bzip2-1.0.5-i586-P4.tgz /mnt/P-Plamo/Contents/tmp/
# chroot /mnt/P-Plamo/Contents/
bash-3.2# cd tmp ; updatepkg bzip2-1.0.5-i586-P4.tgz
old:3, new:4
removing bzip2-1.0.5 (P3)

Removing package bzip2...
...
bzip2-1.0.5-i586-P4 のインストール中 
PACKAGE DESCRIPTION:
bzip2-1.0.5-i586-P4 のインストールスクリプトを実行中

bash-3.2# installpkg google_chrome-5.0.375.99-i386-P1.tgz
google_chrome-5.0.375.99-i386-P1 のインストール中 
PACKAGE DESCRIPTION:
google_chrome-5.0.375.99-i386-P1 のインストールスクリプトを実行中

bash-3.2# rm *.tgz
bash-3.2# exit
exit
# 

必要なパッケージの更新、追加作業が終われば、この環境を再度squashfs化します。この作業にはかなりの時間とCPUパワーを必要とし、手元の Athlon64X2 2.2GHz のマシンでは約40分ほどかかりました。

# cd /mnt/P-Plamo/Contents
# /usr/bin/mksquashfs * ../rootimg.squash -b 1024KB -comp lzma -noappend
Parallel mksquashfs: Using 2 processors
Creating 4.0 filesystem on ../rootimg.squash, block size 1048576.

Exportable Squashfs 4.0 filesystem, lzma compressed, data block size 1048576
	compressed data, compressed metadata, compressed fragments
	duplicates are removed
Filesystem size 1617769.31 Kbytes (1579.85 Mbytes)
	32.15% of uncompressed filesystem size (5031353.65 Kbytes)
....
	sys (3)
	daemon (2)
	uucp (14)
# ls -lh ../rootimg.squash
-rwx------ 1 root root 1.6G  7月 10日  09:51 ../rootimg.squash

新しく作ったsquashfsファイルをUSBメモリにコピーします。

# cp ../rootimg.squash /media/disk/isolinux/rootimg.squash
# cd / ; sync ; sync ; umount /media/disk

以上の作業でP-Plamoからgoogle-chromeが使えるようになりました。

図1 P-PlamoにGoogle Chromeを追加
図1 P-PlamoにGoogle Chromeを追加

P-Plamoでのカーネル更新

P-Plamoのカスタマイズのもう1つの例として、カーネルを更新する手順を紹介しましょう。P-Plamoの場合、カーネルの起動はsquashfsの環境外で行なっていることに注意してください。具体的には、カーネル本体はブートローダからロードできる位置に置くとともに、initrd内で初期化時に組み込むモジュールドライバ類もカーネルに合わせて更新する必要があります。

前節同様、/mnt/P-Plamo/Contents/以下のP-Plamo用環境内に新しいカーネルパッケージをコピーし、パッケージを更新しておきます。以下の例ではカーネル本体と共に、カーネルが提供するヘッダファイルパッケージも更新しています。

# cp kernel-2.6.32.16_plamoSMP-i586-P1.tgz /mnt/P-Plamo/Contents/tmp/
# cp kernel_headers-2.6.32.16_plamoSMP-i386-P1.tgz /mnt/P-Plamo/Contents/tmp/
# chroot /mnt/P-Plamo/Contents
bash-3.2# updatepkg -f kernel-2.6.32.16_plamoSMP-i586-P1.tgz

Removing package kernel...
Removing files:
  --> Deleting symlink boot/System.map
  --> Deleting symlink boot/config
....
PACKAGE DESCRIPTION:
kernel-2.6.32.16_plamoSMP-i586-P1 のインストールスクリプトを実行中

bash-3.2# updatepkg -f kernel_headers-2.6.32.16_plamoSMP-i386-P1.tgz

Removing package kernel_headers...
Removing files:
  --> usr/include/drm/drm.h was found in another package. Skipping.
...
kernel_headers-2.6.32.16_plamoSMP-i386-P1 のインストール中 
PACKAGE DESCRIPTION:

bash-3.2# exit
#

前節同様、mksquashfsコマンドでsquashfsファイルを再生成し、USBメモリにコピーしておきます。

# cd /mnt/P-Plamo/Contents ; /usr/bin/mksquashfs * ../rootimg.squash -b 1024KB -comp lzma -noappend
Parallel mksquashfs: Using 2 processors
Creating 4.0 filesystem on ../rootimg.squash, block size 1048576.
....
	uucp (14)
#  -lh ../rootimg.squash
-rwx------ 1 root root 1.6G  7月 10日  11:23 ../rootimg.squash
# cp ../rootimg.squash /media/disk/isolinux/rootimg.squash

以上の作業でsquashfsファイルの更新は完了ですが、上述のようにP-Plamoのカーネルはsquashfsの外部でロードされるので、そのための作業も必要になります。

まず、起動用のカーネル本体をUSBメモリにコピーします。Plamoの場合、カーネル本体のファイル名にはバージョン番号なども含んでいますが、ブートローダの設定ファイルであるsyslinux.cfgではvmlinuzという名前のファイルをロードするように設定しているので、それに合わせるためにコピー先でvmlinuz-2.6.32.16_plamoSMPをvmlinuzにコピーしています。

# cp /mnt/P-Plamo/Contents/boot/vmlinuz-2.6.32.16_plamoSMP /media/disk/isolinux/
# cp /media/disk/isolinux/{vmlinuz-2.6.32.16_plamoSMP,vmlinuz}

次にinitrd.gzを展開して、initrd内に用意している初期化時に組み込むモジュールドライバも新しいカーネル由来のものに更新します。

# cd /media/disk/isolinux ; gunzip initrd.gz
# mount initrd /tmp/loop -o loop
# cd /tmp/loop/lib/modules
# ls -l
合計 689,152
-rw-r--r-- 1 root root  27,513  3月 29日  10:20 atkbd.ko
-rw-r--r-- 1 root root 170,572  3月 29日  10:20 aufs.ko
-rw-r--r-- 1 root root  35,960  3月 29日  10:20 cdrom.ko
....
# for i in *.ko ; do
 > find /mnt/P-Plamo/Contents/lib/modules/2.6.32.16-plamoSMP -name $i -exec cp {} . \;
 > done
#ls -l
合計 690,176
-rw-r--r-- 1 root root  27,513  7月 10日  11:46 atkbd.ko
-rw-r--r-- 1 root root 171,506  7月 10日  11:46 aufs.ko
-rw-r--r-- 1 root root  35,960  7月 10日  11:46 cdrom.ko
....

新しいモジュールドライバに更新できれば、ブートローダが読めるようにinitrdを圧縮しておきます。

# cd /media/disk/isolinux ; umount /tmp/loop
# gzip initrd
# ls -lh
合計 1.6G
-rwxr-xr-x 1 kojima root 2.0K  3月 29日  10:20 boot.cat
-rwxr-xr-x 1 kojima root 2.4M  3月 29日  10:20 initrd.gz
...
-r-xr-xr-x 1 kojima root 1.6G  7月 10日  11:33 rootimg.squash
-rwxr-xr-x 1 kojima root  464  3月 28日  11:16 sample.msg
-rwxr-xr-x 1 kojima root 2.2M  7月 10日  09:00 vmlinuz

これで必要な作業は終了したのでUSBメモリをアンマウントします。

# cd / ; sync ; sync
# umount /media/disk

以上の操作でP-Plamoのカーネルが更新できました。

図2 P-Plamo のカーネル更新を確認
図2 P-Plamo のカーネル更新を確認

DVDイメージファイルの再生成

書き替え可能なUSBメモリの場合、修正したファイルを置き替えれば改造は終了しますが、書き替えができないDVDメディアの場合はsquashfsと同様、いったんHDD上に中身を展開して必要なファイルを変更した上で、DVDのイメージファイル(ISO9660形式ファイル)を再生成してDVDに書き出す、という作業が必要になります。以下ではそのための手順を簡単に紹介しておきましょう。

まず、既存のP-PlamoのDVDの中身をHDDに取り出します。今回は/cdrom/にマウントされたDVDから、/mnt/P-Plamo/DVD/以下にコピーすることにします。

# cp -a /cdrom/* /mnt/P-Plamo/DVD/
# ls -R /mnt/P-Plamo/DVD
/mnt/P-Plamo/DVD/:
ChangeLog  initrd  isolinux/

/mnt/P-Plamo/DVD/isolinux:
boot.cat      isolinux.cfg  rootimg.squash   vmlinuz
initrd.gz     plamo41.lss   sample.msg       vmlinuz-2.6.32.10-plamoSMP
isolinux.bin  pplamo.lss    syslinux.cfg

このisolinux/以下のファイルを適宜修正版と差し替えます。

# cp /mnt/P-Plamo/rootimg.squash /mnt/P-Plamo/DVD/isolinux/rootimg.squash
...

ISO9660形式のファイルの作成にはmkisofsコマンドを使います。下記で利用しているオプションのうち-J-rは長いファイル名を許可するJoliet/RockRidge形式の指定、-b-cはEl Torito形式の起動に用いるファイルの指定、-no-emul-boot-boot-load-size-boot-info-tableは起動方式の指定、-VはDVDのボリューム名、-oは出力先のISO9660形式ファイル名の指定になります。

# cd /mnt/P-Plamo
# mkisofs -v -J -r -b isolinux/isolinux.bin -c isolinux/boot.cat \
       -no-emul-boot -boot-load-size 4 -boot-info-table \
       -V P-Plamo-custom -o P-Plamo-custom_dvd.iso DVD

Setting input-charset to 'EUC-JP' from locale.
2.01.01a75 (i686-pc-linux-gnu)
Scanning DVD
Scanning DVD/isolinux
Excluded by match: DVD/isolinux/boot.cat
Writing:   Initial Padblock                        Start Block 0
....
Done with: Ending Padblock                         Block(s)    150
Max brk space used 21000
817569 extents written (1596 MB)
# ls -lh *.iso
-rw-r--r-- 1 root root 1.6G  7月 10日  23:45 P-Plamo-custom_dvd.iso

こうして作成したファイルをcdrecordgrowisofsでDVDメディアに書き出せば、カスタム化したDVD起動版P-Plamoが完成します。

おすすめ記事

記事・ニュース一覧