Vmlinux

Linuxシステムにおいて、vmlinuxとは、内部にLinuxカーネル本体を包含する静的リンクされた実行ファイルである。ELF、COFF 、a.outのような実行可能バイナリ形式に準じた形式が利用されるが、通常の実行可能バイナリと異なりカーネル（のexecシステムコール）が対応している形式ではなく、ブートローダーが対応している形式でなければならない。vmlinuxファイルはカーネルデバッグ、カーネルのシンボルテーブル生成、またはその他の用途で利用される。通常、コンパイラが生成するバイナリから、さらに全てのシンボルを取り除き、圧縮をかけ、マルチブート用ヘッダ、ブートセクタ、BIOS用ローレベルブートセットアップルーチン、自己伸長ルーチンなどを追加して最終的に、ブート可能なイメージが完成する（ブート用に付加的な部分を追加し、圧縮（オプション）したカーネルのことをカーネルイメージと呼んで区別する場合もある）。
通常はカーネルのビルドが正常終了すると、（ビルド完了後には同名や類似した名前の中間ファイルが幾多もあるため注意が必要であるが、）ソースコードのトップディレクトリにこのファイルが存在する。

語源

古くから、UNIXのカーネルイメージはunixというファイル名であり、cp (作成したイメージのファイル名) /unixのようにコピーしてインストールされていた。BSDで仮想記憶が実装され、仮想記憶をサポートしたカーネルであることを示すvm-という接頭辞を付けvmunixという名前が使われるようになった。vmlinuxという名前はそのvmunixを基にした命名法によるものである。さらにLinuxでは圧縮イメージという機能も追加され、vmlinuzという名前が付けられた。vmlinuxを圧縮したものであることを表す文字z（zipped）を後尾に付している。

ロード

Unix系システムにおける古くからの慣習で、カーネルはルートディレクトリ (/) に置かれることが多かった。しかし、Linuxに限らずPC-UNIXでは、ブートローダがハードディスクアクセスにBIOSを使用するため、ハードディスクの先頭1024シリンダー (Cylinder 1024) までしかアクセスできないという制限があるシステムがあった（BIOS割り込みルーチン・INT 13H (0x13) を参照せよ）。
この制限に対処するため、Linuxディストリビューターは、ユーザにハードディスクの先頭にブートのためのファイルシステム、すなわちカーネルと、システムのブートに必要なファイルを置くパーティションを作成するよう推奨した（正確にはファイルシステムに含まれるもの以外に、ブートのためにはそのパーティションの先頭のen:Volume boot recordも正しく設定される必要がある。XFSは実装上そのための空間が確保されないため、このファイルシステムには使えない。あるいはブート手順中のそこを迂回する何らかの別の方法が必要となる）。
慣習として、ブート後にそれとは別のパーティションにあるファイルシステムをルートとする場合は、このブート専用ファイルシステムはブート後は /boot にマウントされた（安全のため、カーネルのアップデート時など以外はマウントしない運用とすることもある）。のちにこれはFilesystem Hierarchy Standard (FHS) により標準化された。詳しくは、FHSバージョン2.3のセクション3.5.2を参照してほしい。

圧縮

旧来より、ブート可能なカーネルイメージを生成した際、カーネルはまた、zlibアルゴリズムを用い圧縮されている。Linuxカーネルバージョン2.6.30からはこれに加え、圧縮率が高いLZMAやBZIP2アルゴリズムによる圧縮もサポートされている。システムに電源を投入し、BIOSがブートローダを読み込み、ブートローダが圧縮されたカーネルイメージコードを読み込む。このコードからカーネルコードが伸長（展開）されると、いくつかのシステムでは、ブートプロセスが進行するにつれコンソールにドット(.)が何個も表示される。
圧縮ルーチンは、いくつかのアーキテクチャ、とりわけ、i386のようにブート時に読み込めるデータサイズが極端に制限される場合必須であったが、bzImageが開発された現在においては、ブートプロセスにおいては、取るに足らない要素である。
x86アーキテクチャとは異なり、SPARCアーキテクチャにおいては、カーネルイメージはvmlinuxファイル自体を単にgzipで圧縮したものである。これはSPARC Linuxシステムにおいて使用される、SILOブートローダがgzipで圧縮されたイメージを透過的に伸長できるからである。
ブートイメージのファイル名はさほど重要ではなく（なぜなら近年のブートローダはイメージを設定ファイルで指定可能、もしくはブート時に指定可能だからである）、しかし、慣習的には、vmlinuz または zImageとなる場合が多い。

bzImage

Linuxカーネル開発が成熟するにつれて、ユーザーが生成するカーネルのサイズはいくつかのアーキテクチャにおいて課される制限である、圧縮されたカーネルコードが保持可能なサイズを越えるまでになってきた。
この制限に対処するため、カーネルを不連続なメモリ領域にうまく分離した、bzImage (big zImage) フォーマットが開発された。
bzImageはzlibアルゴリズムを用い圧縮されている。また2.6.30からは更によりよいアルゴリズムで圧縮可能である。もっともらしい誤解は、bzがファイル名の接頭辞にあるため、このイメージがbzip2で圧縮されているのだということが語られるが、そうとは限らない。（確かに、bzip2パッケージは"bz"の接頭辞のついたツールともに配布されている。例えば、bzip2で圧縮されたテキストファイルをlessページャを通して透過的に読むことができる、bzless、同様にcatコマンドに対するbzcatなどが付属している。）

カーネルイメージの伸長

現時点ではbzImageファイルを伸長する特定のツールはない。しかし、カーネルソースコードのアーカイブ内にscripts/extract-ikconfigというbashベースの簡易なシェルスクリプトが存在する。このスクリプトは、引数に与えたイメージを伸長し、イメージからカーネルビルドコンフィグレーション(Kconfig)を抽出する。場合によっては、伸長したイメージを直接得るため、bzImageを改変することも可能である。いくつかのディストリビューション、例として、RedHatとそのクローン(CentOSなど)にはカーネルのRPMパッケージに対応するvmlinuxファイルを持つkernel-debuginfoなるパッケージがあるかもしれない。概して、そのようなパッケージは/usr/lib/debug/lib/modules/`uname -r`/vmlinuxにインストールされる。

オブジェクトファイルフォーマット

以下は、x86-64アーキテクチャにおけるGentoo Linuxで稼働する、カーネル（バージョン2.6.29）の実行可能イメージからヘッダ情報を抽出したものである（GNU Binutilsパッケージに付属するreadelfコマンドは、ELF定義済みヘッダを出力するコマンドである）。

$ readelf -h vmlinux
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x1000000
  Start of program headers:          64 (bytes into file)
  Start of section headers:          13951312 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         5
  Size of section headers:           64 (bytes)
  Number of section headers:         45
  Section header string table index: 42
ちなみに、同じコマンドをbzImageに実行しても次のようなエラーが返されるだけである。

$ readelf -h arch/x86/boot/bzImage
readelf: Error: Unable to seek to 0xc031f2eb for section headers
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
bzImageは前述の通りELFヘッダを持たないrawバイナリである。