2010年02月01日

QEMUで動作したDebianのカーネルをリビルドする

前回の方法で、qemu上にきちんと動作するDebianのシステムを構築することができました。これをひとつのベースとして、いろいろいじって試してみることにします。

まずはカーネルのリビルドです。



基本方針

Debianのソースパッケージをapt-getで取得して、それをそのままビルドすればよいわけですが、qemu上でのコンパイルはとてもとても時間がかかります。一晩かけても終わりません。

なので、qemu上のarmのDebianではソースパッケージの取得とそのソースの展開とパッチの適用まで行い、そのソースをPCのLinuxに持ってきて、そこでクロスコンパイルするようにします。

最初は /boot/config-2.6.26-2-versatile のとおりにビルドして動作を確認し、次にconfigを変更してカスタマイズしていきます。

以下、armel$のプロンプトはqemu上のarmのDebian, 単なる$はPCのLinux での操作であることを示します。

カーネルのソースパッケージの取得

armel$ su
# apt-get build-dep linux-image-2.6.26-2-versatile
# exit
armel$ mkdir work
armel$ cd work
armel$ apt-get source linux-image-2.6.26-2-versatile

ソースの展開とパッチの適用

armel$ cd linux-2.6-2.6.26/
armel$ debian/rules source 2>&1 |tee source.log

debian/rules build

と実行すれば一気にビルドまでやってくれますが、ソースを展開してパッチを適用したところで止めるためには debian/rules source とします。何をやったか後で調べられるように tee コマンドでログをファイルに落としておきます。

これが完了すると、debian/build/source_armel_none のディレクトリにパッチを適用されたカーネルのソースが展開されるので、これをまるごとPCのLinuxに転送します。

(最初からworkのディレクトリをPC LinuxにNFSでマウントしておくと楽です。それに関してはこのページ

カーネルのビルド

ビルドはPCのLinuxで行います。

configファイルは arm Debianの /boot ディレクトリからあらかじめコピーしておいてください。

クロスコンパイラはandroidのソースツリーにあったものを流用しました。$ANDROID はandroidのソースツリーの先頭です。

$ cd source_armel_none/
$ cp $HOME/config-2.6.26-2-versatile .
$ export ARCH=arm
$ export CROSS_COMPILE=$ANDROID/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-

カーネルのロードモジュールを配置するディレクトリ名はカーネルのバージョンと関連付けられているので、MakefileのEXTRAVERSIONの値を以下のように修正します。

$ diff -u Makefile.org Makefile
--- Makefile.org	2010-01-29 16:53:46.000000000 +0900
+++ Makefile	2010-01-29 16:54:13.000000000 +0900
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 26
-EXTRAVERSION =
+EXTRAVERSION = -2-versatile
 NAME = Rotary Wombat
 

これでビルドします。最初はconfigを変更せずに試してください。

$ cp config-2.6.26-2-versatile .config
$ make menuconfig
$ make zImage 2>&1 |tee make.log

arch/arm/boot/zImage に起動に使う圧縮されたカーネルイメージができあがります。vmlinuz-2.6.26-2-versatile の代わりにこれを使ってqemuを起動し、問題なく立ち上がることを確認します。

$ qemu-system-arm -M versatilepb \
 -kernel zImage \
 -initrd initrd.img-2.6.26-2-versatile \
 -hda hda.img.qcow2 \
 -append "root=/dev/sda1"

ブート時に使用するカーネルモジュールをカーネルに最初から組み込むことにしてinitrdを不要にする

組み込みシステムでは起動するときに使用するデバイスは変わることがありません。なので必要なカーネルモジュールはカーネルに組み込んでしまったほうがシンプルになります。それによってinitrdが不要になり起動シーケンスも簡略化できます。

arm Debianが起動した後に、使用されているカーネルモジュールを知るには以下のコマンドを使います。

armel$ lsmod
Module                  Size  Used by
ipv6                  287700  10 
loop                   14124  0 
smc91x                 15140  0 
psmouse                38192  0 
sg                     31568  0 
sr_mod                 15908  0 
cdrom                  35928  1 sr_mod
ext3                  122728  1 
jbd                    45332  1 ext3
mbcache                 7936  1 ext3
sd_mod                 25232  3 
sym53c8xx              67188  2 
scsi_transport_spi     24224  1 sym53c8xx
scsi_mod              150212  5 sg,sr_mod,sd_mod,sym53c8xx,scsi_transport_spi

これらのモジュールがカーネルに組み込まれるように make menuconfig でconfigを修正してみてください。

configを修正したらビルドして起動を確認します。

lsmodで何も表示されなくなるまで、これを繰り返します。

lsmodで何も表示されなくなったら、qemuの -initrd オプションをはずして起動してみてください。うまく立ち上がれば成功です。

$ qemu-system-arm -M versatilepb \
 -kernel zImage \
 -hda hda.img.qcow2 \
 -append "root=/dev/sda1"

カーネルとinitrdをDebianのパッケージ管理からはずす。

もはや、カーネルは自分で自由に変更するので、Debianのパッケージの管理下にある必要がありません。

apt-get upgrade したときに自分の変更と衝突してエラーになったりするので、該当するDebianのパッケージを削除してしまいます。

armel$ su
# apt-get remove initramfs-tools
# apt-get autoremove

/boot も /lib/modules もディレクトリごと無くなりました。これらは必要に応じて自分で作るようにします。

これでカーネルとユーザーランドの依存関係が疎になりました。

積極的にカーネルをいじって試してみましょう。



トラックバックURL

トラックバック一覧

1. クロス開発でのQEMU まとめ(基礎編)  [ KMC Staff Blog ]   2010年09月16日 11:08
ここまでのQEMUの記事のリンク集です。 なお、CELFテクニカルジャンボリーにて、時間をいただきましたので、このあたりについて話をさせていただきます。 (3月5日 中野サンプラザ 入場無料) よろしければご参加ください。

コメントする

名前
URL
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード