2010年02月05日
vmlinuxとzImageの関係
Linuxカーネルを起動する時に使うzImageってvmlinuxをzipで圧縮したものなの?
zImageを伸長するのはブートローダーの仕事?
改めて調べてみたので、ここでそれを紹介します。
(以下の話はアーキテクチャによって詳細が異なるかもしれません。今回はarmのlinuxを題材にします。)
これってどんなファイル?と思ったときはまず file コマンドで調べます。
$ file vmlinux vmlinux: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, not stripped $ file arch/arm/boot/zImage arch/arm/boot/zImage: data
vmlinuxがELFのオブジェクトファイルなのはいいとして、zImageの方は単に「data」。dataって言われても。。
次にどうやってつくられたものかmake zImage したときのログを見ます。
... LD vmlinux SYSMAP System.map SYSMAP .tmp_System.map OBJCOPY arch/arm/boot/Image Kernel: arch/arm/boot/Image is ready GZIP arch/arm/boot/compressed/piggy.gz AS arch/arm/boot/compressed/piggy.o LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready
つまりは、
vmlinuxはオブジェクトファイルをstatic linkしたELFの実行ファイル
vmlinuxをobjcopyで実際に実行に必要な部分だけとりだしたのがarch/arm/boot/Image これでシンボル情報は全てなくなります。
その次はちょっとこれだけでは情報が足りないのでmake V=1 zImage としてログを取ります。これで実際に実行したコマンドとその引数が全てわかります。(しかし長いのでここでは省略。)
- arch/arm/boot/Image をzip圧縮したのがpiggy.gz
- piggy.Sはpiggy.gzをバイナリのままインクルードしていて、それをアセンブルしたものがpiggy.o
- piggy.oとzip伸長するためのライブラリとmain関数をリンクしたのが arch/arm/boot/compressed/vmlinux
- さらにそれをobjcopyで実際に実行に必要な部分だけとりだしたのがarch/arm/boot/zImage というわけです。
zImageは単にvmlinuxをzip圧縮したものではありません。シンボル情報が欠落しているので、zImageからvmlinuxに逆変換する方法はありません。
また、zImageを伸長しているのはブートローダではなくて、zImage自身です。つまりzImageは自己解凍型の圧縮ファイルと言えます。
ちなみに
Uncompressing Linux... done, booting the kernel.
という最初のメッセージは arch/arm/boot/compress/misc.c で出しています。
実は私もこうやって調べるまではこのメッセージはブートローダが出しているものだと思っていました。長年の疑問が解けてすっきりしました。