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メモリの場合、修正したいファイルを置き替えるだけで改造は終了しますが、DVDメディアの場合はsquashfsファイル等を置き替えてからISO9660形式のイメージファイルを再生成する必要があります。そのための手順については最後に述べます。
以下では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 コマンドでルートファイルシステムを変更すれば、その環境下でremovepkg やupdatepkg 等のパッケージ管理コマンドを利用できます。今回はパッケージ管理コマンドを使って、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を追加
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}
ここではカーネルバージョンの情報を残すためにcpで別ファイルを作っていますが、mvで直接ファイル名を変えてしまっても構いません。このような処理にはハードリンクが便利ですが、残念ながらたいていのUSBメモリがあらかじめフォーマットされているVFATファイルシステムではハードリンクの機能は利用できません。
次に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 のカーネル更新を確認
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
こうして作成したファイルをcdrecord やgrowisofs でDVDメディアに書き出せば、カスタム化したDVD起動版P-Plamoが完成します。