ハードウェア

ハードウェアか?と言われそうな物もあります;-)

■IBM PC/AT互換機の起動の流れ(概要)

●BIOS : POST(Power On Self Test)
CPU、ビデオカード、メインメモリなどの初期化

●BIOS : 起動ドライブの選定

●BIOS : INT13H
BIOS ROM内部の16bitコードで書かれているPC/ATの基本入出力サブルーチンを実行し、起動ドライブの先頭セクターをロードします。
HDのMBR(マスターブートレコード、PC/AT標準)かFDのブートセクター(OS固有)を読み込んで実行します。
FD立った場合は下記のMBRの実行はされずにブートセクターの実行まで飛びます。

●MBR : マスターブートローダー(イニシャルプログラムローダー、ブートストラップローダー)の実行
510バイト目にあるブートシグネチャー(0xAA55)を参照してMBRが有効なのを確かめ、MBRの先頭にあるコードを実行します。

●MBR : マスターブートローダー
446バイト目から16バイトづつ4レコード並んでいるパーティションテーブルの中からアクティブ(起動可能)フラグが立っている基本領域を探し、そのパーティションの先頭のセクター(ブートセクター)をロードして実行します。
見付からない場合はPCは停止してしまいます。

●ブートセクター
OS固有の物なので、ここから先はOSによります。


※liloやgrubは、windowsなどで使うPC/AT標準のマスターブートローダーを書き換えて、独自の起動シーケンスを実現しています。(一般的な物に戻すのは、 win9xのコマンドでfdisk /mbr)
※liloやgrubは、ブートセクターを使用しませんが、後のことを考えてデータ領域として使わず空にしてあります。


■MBR(マスターブートレコード)

ハードディスクの先頭のセクターです。
下記のような構造をしています。

先頭アドレス内容
0000プログラム領域
(マスターブートローダー)
0446パーティションテーブルエントリー1
0462パーティションテーブルエントリー2
0478パーティションテーブルエントリー3
0494パーティションテーブルエントリー4
0510ブートシグネチャー



■パーティション

パーティションテーブルの4つのエントリに示されたパーティションのことを、基本領域(Primary Partition)と呼びます。

IBMとMSの共同規定により、最所のパーティションは第2トラック(シリンダー0、ヘッド1)から始めなければいけません。(第2トラック規定)
また、パーティションは必ずシリンダー境界で作成しなければなりません。(シリンダー境界規定)
(このため一般のHDDはMBRから第一パーティションまで31KBの空き領域があります)


4つの基本領域のうち1つだけを拡張領域とすることができます。
拡張領域は他の基本領域と違い、それ自身ではファイルシステムを作成してOSが使うことが出来ません。拡張領域はその中に一つ以上の論理領域(Logical Partition)を作ることが出来ます。
論理領域は
ファイルシステムを作成してOSが使うことが出来ます。
論理領域数の上限は一応ありません。


拡張領域1
EPBR論理領域1拡張領域2
EPBR論理領域2拡張領域3
EPBR論理領域3拡張領域
EPBR論理領域4




※EPBR=拡張パーティションブートレコード

■拡張パーティションブートレコード(EPBR)512バイト

MBRと同じ構造になっています。

●ブートストラップ(空)446バイト

●パーティションテーブル(16バイトx4)先頭2個使用で入れ子構造を再現。後ろ二個は空。

●ブートシグネチャー(2バイト)


PC/AT互換機の一般仕様では、拡張領域からはブート出来ません。
Win9x系でパーティションの作成をする「FDISK」というコマンドは、基本領域は一 つしか作れません。既に基本領域があると、もう一つ基本領域を作ることができないので、複数の領域を作りたい場合は必ず拡張領域が必要になります。




■ブートシーケンス概略

■HDD(MS)

bios->mbr->bootsector->kernel


■FDD(MS)

bios->bootsector->kernel


NTのインストーラは、ブートセクターがDOSの物であると、これをNTのものに書き換える前にbootsect.dosというファイルに退避します。
この場合、NTLDRが出す「Microsoft Windows」というメニューを選ぶと、bootsect.dosが読み込まれ、その中のコードが実行されます。この後はMBRのマスターブートローダーがブートセクターを読んだ場合と同じになります。

■LILO(HDD MBR install)

1stbootloader(MBR)->2ndbootloader(ルートパーティション)->kernel


■LILO(HDD rootパーティション install)

ブートローダー(MBR)->1stbootloader(ブートセクター)->2ndbootloader(ルートパーティション)->kernel


LILOをよくMBRにインストールするか、ルートパーティションにインストールするか、フロッピーディスクにインストールするか選択しますが、この選択によってインストール先が変わるのは1stBootloaderだけです。


Linuxを起動するにはLinuxカーネルを読み込まみますが、Linuxカーネル自身にもローダーがあって、フロッピー起動の場合はLinuxカーネル自身のローダで起動されることが出来ます。
これはHDDでは使えません。
FDDでは、緊急ブートディスクなどはこの手法で起動されるのが一般的のようです。

lilo等を使わない場合、rdevコマンドでカーネルの504バイト目RAM ディスクサイズ、506バイト目のVGA モード、508バイト目のルートデバイスのハードコードされた設定を変更します。
これはPC/AT互換機でしか使えず、manマニュアルなどにも「いにしえのハックなので使わないように」されています。




L ---1stBootLoaderが実行を開始した。

I ---2ndBootLoaderのロードが完了した。

L ---2ndBootLoaderが実行を開始した。

O ---2ndBootLoaderがマップ情報の読み込みを完了した。




■LIで止まる理由

2ndBootLoaderの実体は通常/boot/boot.bというファイルの一部です。
マップインストーラ実行時に1stBootLoaderの内部にこの2ndBootLoaderの位置がハードディスクディスク上の絶対番地で記録されます。
1stBootLoaderは実行時に自分の内部に記録された2ndBootLoaderの絶対番地をBIOSに示してロードしてもらいます。

何らかの理由で2ndBootLoaderが無くなってしまうか、移動させられると、その絶対番地には別のものになってしまいます。
1stBootLoaderはそのデータが2ndBootLoaderで無くてもメモリにロードして、「I」と表示します。
そしてそこに制御を移した時に続行不能になり停止してしまいます。
/boot/boot.bを単に別のところへ移して、また/boot/boot.bに戻しても、物理的なハードディスク上の絶対番地が変わった場合「LI」で停止してしまいます。



工事中


$ dd if=KERNEL of=/dev/fd0 bs=1k
$ rdev /dev/fd0 /dev/fd0
$ rdev -R /dev/fd0 0
#フロッピーにブートローダーを使わずにカーネルを直書きする。
# rdevについて
i386 の Linux カーネルのブート可能なイメージには、ルートデバイス・ビデオモード・ RAM ディスクサイズを指定するための数バイトの領域がある。デフォルトでは、これらの領域はカーネルイメージのオフセット 504 (10 進) から始まる
rdev ユーティリティの、現在のルートデバイス名を表示する以外の機能は、カーネルイメージの決め打ちのオフセットに決め打ちの数値を書き込むことによって動作 する、いにしえのハックである。これは i386 以外のアーキテクチャでは動作しない。これの使用は全く推奨できない。 SysLinux や LILO のようなブートローダを代わりに使うこと。

$ カーネルイメージの ramdisk 変数にはルートファイルシステムの位置に関係するオプション等が指定されています.この変数には rdev コマンドでアクセスすることができます。
第 0-10ビット: RAM ディスク先頭位置へのオフセットアドレス.
1024 バイトのブロックが単位になります.
第11-13ビット: 未使用です.
第 14ビット: RAM ディスクをロードするかどうかのフラグです.
第 15 ビット: ルートファイルシステムをロードする前にフロッピー
交換のプロンプトを出すかどうかのフラグです.

$ 第 15 ビットがセットされていると,ブート時に 2 枚目のフロッピーをドライブに入れるようにというプロンプトが出ます.ディスク 2 枚からなるブートシステムではこのフラグが必要になります.

1枚のブート/ルートディスクを作るか,2枚組の「ブート+ルート」ディスクを作るかによって,手順は2つに分かれます.

1. 1 枚のディスクで作る場合,圧縮形式のルートファイルシステムをカーネルの直後に置きます.つまり,オフセット位置は最初の空きブロックです(これは KERNEL_BLOCKS に等しいはずです).第14ビットに1を,第15ビットに0をセットします. 例えば,1 枚組のディスクを構築しようとしていて,ルートファイルシステムをブロック 253 (10 進値)から始めようとしているとします.ramdisk 変数の値は 253 (10 進値)のはずであり,ビット 14 に 1 がセットされ,ビット 15 に 0 がセットされています.この値を計算するには,単に 10 進値を足し合わせてください.すなわち「253 + (2^14) = 253 + 16384 = 16637」です.この数値の由来が良く分からなければ,この値を関数電卓に入れて 2 進値に変換してみてください.
2. 2 枚組のディスクを作る場合,ルートファイルシステムは 2 枚目のディスクの第 0 ブロックから始まります.つまり,オフセット位置は 0 です.第 14, 15 ビットにはそれぞれ 1 をセットします.この場合,10 進値は 2^14 + 2^15 = 49152 となります.

ramdisk 変数がしっかりと計算できたら,rdev -r コマンドを使って設定します.設定の際には 10 進数を使ってください.LILO を使っている場合には,rdev に渡す引き数はマウントされるカーネルのパス(例: /mnt/vmlinuz)でなければなりません.カーネルを dd でコピーした場合は,この代わりにフロッピーのデバイス名(例: /dev/fd0) を使います.

rdev -r KERNEL_OR_FLOPPY_DRIVE VALUE

$ dd if=rootfs.gz of=/dev/fd0 bs=1k seek=KERNEL_BLOCKS
# disk2
$ dd if=rootfs.gz of=/dev/fd0 bs=1k

#floppyへのgrubのインストール
$ dd if=/usr/local/share/grub/i386-pc/stage1 of=/dev/fd0 count=1
$ dd if=/usr/local/share/grub/i386-pc/stage2 of=/dev/fd0 seek=1
#または
# grub-install '(fd0)'

#hddへのgrubのインストール
# /usr/local/sbin/grub-install /dev/hda2
#または
$ grub/grub
grub> root (hd0,1)
grub> setup (hd0)
grub> quit
GRUBではハードディスクドライブはhd0, hd1, hd2...の様に表します.SCSI とIDEの区別無く,BIOS から見た1台目のHDDがhd0,2台目のHDDがhd1になります.FDDも同様に1台目からfd0, fd1...になります.
パーティションも0から数えます.したがって, `hd0,1'は一台目のハードディスクの2番目のパーティションを表します.

grubはmbrにインストールされていれば、カーネルイメージを増やしても、コンフィグを書き換えるだけでで、liloの用に実行しなくても大丈夫。






戻る