特集記事
Last updated 2002-06-14

インターフェース 2002年7月号 特集記事・関連ファイル解説

インターフェース 2002/7月号特集号「Linux徹底詳解 ― ブート&ルートファイルシステム」で使用した、関連ファイルの内容について解説します。関連ファイルはふたつのファイルにまとめました。ひとつは if301_linux_src.tgz (3.3MB)、もうひとつは if301_linux_bin.tgz (3.4MB)です。前者にはソースツリー、後者には完成したフロッピーディスクイメージが含まれています。誌上で十分に解説出来なかった部分については、説明を補足していますので、本文と併せてお読みください。

それではこのソースツリーを利用して、是非ご自分の手でオリジナルのブートディスク、ブートルートディスクを作成してみてください。100のCソースをコーディングするよりも、遙かに深くPC-UNIX を理解できるはずです。

西 田 亙 (NISHIDA Wataru)

if_301_linux_src.tgz

Top directory

展開後のディレクトリには、以下のように3つのサブディレクトリが作成されます。

.
|-- chapter1
|-- chapter2-3
`-- chapter4

x
第1章
第 2・3章
第4章

chapter1

3つのCソースファイルが用意されています。

.
|-- hello.c
|-- hello-sys.c
`-- hello-asm.c

x
教科書的 Hello, world! プログラムソース
標準入出力をシステムコールに置き換えたバージョン
拡張アセンブラーを用いてシステムコールを直接呼び出すバージョン

"gcc -O2 hello-asm.c" で実行可能ファイル a.out が出来上がります。"./a.out ; echo $?" でプログラムが正常に作動するかどうか、確認してみましょう。なお、コンパイル時に "warning: return type of `main' is not `int'" という警告メッセージが表示されますが、これは無視して結構です。

chapter2-3

第2・3章では、BIOS 版 Hello, world! プログラムを土台にして、ひとつひとつ機能を積み重ねながら最終的な Linux カーネルローダーを完成させます。誌上ではこの過程が分かりづらいのですが、ソースツリー内部では継承ソースリストはシンボリックリンクで参照し、新しく追加したソースファイルだけをディレクトリに配置していく方法を取っていますので、コードが進化して行く様子を楽しんで頂けると思います。

chapter2-3 には、以下のように6つのサブディレクトリがあります。

.
|-- hello
|-- pass-param
|-- load-images
|-- bzip2-1.0.2-wn
|-- bunzip
`-- boot-kernel


BIOS 版 Hello, world! (stage1)
stage2 読み込み部分を追加し、ブートパラメーターの引き渡しをチェック
stage3 / 圧縮カーネルイメージの読み込みおよび転送部分を追加
libbzip2 に改変を施したソースツリー
上記から必要な展開ルーチンだけを抜き出したもの
Linux カーネル・ブートローダー

chapter2-3/hello (Bochs 起動画面)

"make" でブートシグナチャなしのブートセクターイメージ hello が出来上がります。BIOS によってはこのバージョンでも起動可能なのですが、失敗した場合は "make -f Makefile-sig" で hello-sig を作成してください。こちらはブートシグナチャ付きの512バイトのブートセクターイメージです。ブート用のフロッピーディスクを作成する場合は、ドライブにフォーマット済みのディスケットを用意し "dd if=hello-sig of=/dev/fd0" を実行してください。

chapter2-3/pass-param (Bochs 起動画面)

"make" でブート・フロッピーディスク・イメージ pass-param.bin が出来上がります。テストを行う前に、新しく作成されたブートパラメーター設定ユーティリティー config を実行してください。stage2 のプログラムサイズは960バイトありますので、stage2 のセクターサイズは2となります(512バイト/セクター)。よって、起動前に ./config pass-param.bin "mem=4M" 1 0 256 2 3 4 のように stage2 サイズを2に設定してください。他のパラメーターは好きなように設定して構いませんが、stage2 サイズだけは2を指定しないとプログラムが暴走してしまうので、注意してください。Bochs で起動する場合は bochs "floppya: 1_44=pass-param.bin, status=inserted" "boot: a" と指定します。

chapter2-3/load-images (Bochs 起動画面)

"make" でブート・フロッピーディスク・イメージ load-images.bin が出来上がります。テストを行う前に、pass-param.bin と 同様に config を実行してください。stage2 のプログラムサイズは1696バイトありますので、stage2 のセクターサイズは4となります。起動前に ./config pass-param.bin "mem=4M" 1 0 256 4 4 512 のように stage2 サイズを4に設定する必要があります。まだ stage3 / 圧縮カーネルイメージは書き込んでいませんので、両者のサイズは好きな値で構いません。

chapter2-3/bzip2-1.0.2-wn

bzip2 (v1.0.2) ソースパッケージに Makefile-lib / mbunzip2.c の2つのファイルを追加し、bzlib.c に修正を加えたものです。普通通りに make を実行すると、bzip2 / bzip2recover / libbz2.a が出来上がり、make -f Makefile-lib を実行すると libbz2.a と libbz2.o が作成されます。mbunzip2.c はオンメモリーで bunzip2 機能を実行するためのテストプログラムです。gcc -o mbunzip2 mbunzip2.c libbz2.o で、実行ファイルが出来上がりますので、あらかじめ bzip2 で圧縮したファイルを展開してみてください。この時、bzip2 の圧縮レベルを変化させると興味深い結果が得られます。

$ cp /usr/src/linux/vmlinux ./
$ bzip2 -v9c vmlinux > vmlinux.9.bz2
vmlinux: 2.442:1, 3.276 bits/byte, 59.04% saved, 2590459 in, 1060933 out.
$ bzip2 -v1c vmlinux > vmlinux.1.bz2
vmlinux: 2.372:1, 3.372 bits/byte, 57.85% saved, 2590459 in, 1091950 out.
$ wc -c vmlinux*.bz2
1091950 vmlinux.1.bz2
1060933 vmlinux.9.bz2
2152883 total
$ ./mbunzip2 vmlinux.1.bz2 vmlinux.1
vmlinux.1.bz2: 1091950 bytes read.
malloc: 64116 bytes
malloc: 400000 bytes
Decompressed image size is 2590459 bytes.
$ diff vmlinux vmlinux.1 ; echo $?
0
$ ./mbunzip2 vmlinux.9.bz2 vmlinux.9
vmlinux.9.bz2: 1060933 bytes read.
malloc: 64116 bytes
malloc: 3600000 bytes
Decompressed image size is 2590459 bytes.
$ diff vmlinux vmlinux.9 ; echo $?
0

vmlinux をコピー
レベル9で圧縮
1060933 バイトへ

レベル1で圧縮
1091950 バイトへ





レベル1圧縮ファイルを展開


作業エリアとして 464KB



レベル9圧縮ファイルを展開


作業エリアとして 3.6MB

x

レベル1で圧縮した場合、展開時に必要なワークエリアは 464KB ですが、レベル9で圧縮すると一気に 3.6MB ものメモリーが必要になる点に注意しましょう。

chapter2-3/bunzip

bzip2 のソースツリーから展開に必要な部分だけを抽出したものです。make で作成される bz_decomp.o のサイズは libbz2.o の約半分 (20KB) しかありません。

chapter2-3/boot-kernel (Bochs 起動画面)

いよいよ、オリジナルブートローダーの完成です。"make 一発" で Linux ブートディスク・イメージ boot-kernel.bin が出来上がります。なお、boot-kernel.bin を作成する前に、bunzip ディレクトリに bz_decomp.o が用意されているかどうか確認してください。起動カーネルには /usr/src/linux/vmlinux を利用しますので、前もって適切なコンフィギュレーションを行い(make menuconfig)、make bzImage を実行しておく必要があります。

chapter4

ルートファイルシステム実装を実体験するためのソースツリーです。ディスクイメージを自動作成するための、Makefile を用意しましたので、活用してください(誌上では紹介していません)。

5つのサブディレクトリが存在します。

.
|-- minimum-kernel
|-- boot-disk
|-- boot-root-disk-static
|-- boot-root-disk-shared1
`-- boot-root-disk-shared2


最小カーネルのための .config ファイル、および vmlinux/bzImage
open_dev.c および init-hello.c ソースリスト
静的リンク版ブート・ルートディスク
共有ライブラリ版ブート・ルートディスク・その1
共有ライブラリ版ブート・ルートディスク・その2

chapter4/minimum-kernel

誌上で利用した最小カーネルの .config ファイルと、このファイルを利用して作成した vmlinux および bzImage が格納されています。以降のサブディレクトリは、すべて ../minimum-kernel/bzImage を参照していますので注意してください。

chapter4/boot-disk (Bochs 起動画面)

open_dev.c は UNIX におけるファイルとデバイスの等価性を確認するためのプログラムです。init-hello.c は /sbin/init の代わりに、カーネル起動時に実行されるプログラムです。1秒置きに Hello, wordl! を表示します。

Makefile は、../minimum-kernel/bzImage および init-hello.c (init) を利用してブートディスクイメージ boot.bin と ルートディスクイメージ root.bin を作成するためのものです。カーネル起動時に "VFS: Insert root floppy and press ENTER" と表示されている点に注目しましょう。

chapter4/boot-root-disk-static (Bochs 起動画面)

2枚の boot.bin と root.bin イメージを1枚の boot_root.bin にまとめるための Makefile です。但し、搭載されるプログラムは静的にリンクされた init です。boot.bin/root.bin 2枚組の時とは異なり、"RAMDISK: Compressed image found at block 293" と表示されている点に注意してください。

chapter4/boot-root-disk-shared1 (Bochs 起動画面)

bash と ls コマンドを共有ライブリーと共に my_boot_root.bin に実装します。しかし、デフォルトでルートファイルシステムは Read only mode でマウントされますので、書き込みができません。そこで、rdev -R my_boot_root.bin 0 を実行し、Read / write mode でマウントします (Bochs 起動画面) 。

chapter4/boot-root-disk-shared2 (Bochs 起動画面)

最後に、いくつかのシステムコマンドやエディター e3 を my_boot_root2.bin に実装します。また /etc/fstab を用意することで、カーネル起動時にルートデバイスと proc file system をマウントします。

if_301_linux_bin.tgz

Top directory

各ソースディレクトリで作成された、ビルド済みフロッピーディスクイメージです。詳細については、上記の説明を参照してください。

hello.bin
pass-param.bin
load-images.bin
boot-kernel.bin
boot.bin
root.bin
boot_root.bin
my_boot_root.bin
my_boot_root2.bin

Your SysOp is Wataru Nishida , M.D., Ph.D.