LPIC-2 - 201試験 - 202:システムの起動 - 202.1 システムの起動とブートプロセスのカスタマイズ

Last Update : September 18 2014 21:34:18

     

a. システム起動プロセス

Linux は HDD の基本領域にも論理領域にもインストールが可能であり、該当パーティションのアクティブ フラグがアクティブである必要もない。こうした機能は Linux のローダである grub や LILO によって実現されています。
grub はファイル サイズが大きく MBR のサイズ (1 セクタ) におさまらないため、"プライマリ" と "セカンダリ" の 2つのファイルに分割され、それぞれを stage1, stage2 と呼んでいます。
またはGRUB Legacyの場合は、三段階(stage1 + stage1.5 + stage2)の場合もあります。

stage1 を MBR、stage2 を Linux のパーティション内に配置し、stage1 が stage2 をロード、stage2 が Linux をロードして行きます。
stage1 は特定のファイルシステムに依存せず、直接アドレスを指定 (LBA を用いてハードディスクのセクタを直接指定) することでディスクアクセスを行います。
stage1.5 は/bootパーティションがハードディスクの1024シリンダ以降にある場合や、LBAモードが使用されている場合に必要となります。


アドレシング モード 】 (Addressing Mode)

 ハードディスクのアクセスやファイル管理は、記録単位のセクタを特定 (位置指定) することで行います。 セクタの位置に関する情報をアドレスと呼び、その指定方法は次の2つの方式があります。

CHS 方式
ハードディスク登場時からの方式で、C/H/S (シリンダ/ヘッド/セクタ) の 3 つのパラメータを用いてディスクへのアクセスや管理を行います。 各パラメータは次のように決められています。
  1. シリンダ (Cylinder)
    ディスク記録面の同一トラックを仮想的にまとめた円筒 (シリンダ) 形をシリンダと呼び、外周側から番号が振られます。 物理的な記録面が一つしかなくてもシリンダは構成されます。
  2. ヘッド (Head)
    ディスクの 面ごとに配置された磁気ヘッドに、重ねられた順に番号を割り当てます。裏表に1つずつある場合もあります。
    複数ディスクで構成されたハードディスクでも、磁気ヘッド番号の指定でディスク面を特定できます。サイドと呼ぶこともあります。
  3. セクタ (Sector)
    トラックを細かく分割した記録領域をセクタと呼び、ディスクの回転方向に番号を振ります。 PC/AT 互換機の場合、1 セクタは 512 バイトです。 UNIX 系の OS ではブロックと呼ぶ。
LBA 方式
記録密度の上昇に伴い、シリンダ/ヘッド/セクタ を指定する従来の方式ではディスク上の実記録位置を管理しきれなくなってしまいました(外周と内周のセクタ数が異なり、8GB の限界もある) 。 ハードディスクの大容量化に対処するため、一元的な通し番号による LBA (Logical Block Addressing) 方式が考案されました。
  • LBA 方式はハードディスク内のすべてのセクタに、シリンダ 0, ヘッド 0, セクタ 1 を "0" とし、そこから順番に通し番号を割り当て、その番号によってセクタ位置 (アドレス) を管理・指定します。
  • LBA への対応は E-IDE (Enhanced IDE) 規格以降から盛り込まれ、BIOS も拡張オプション (下記) を用意することで対応できます。
     INT 13h AH = 4xh
    LBA から実際のセクタ位置を導くのは、IDE コントローラが行います。
  • 通し番号の表現サイズ (ビット数) を拡張すればディスク サイズに限界はなくなりますが、あまり大きなビット数は現実的でありません。  現在の E-IDE と SCSI では 32bit LBA を採用しており、2TB が上限です。 BigDrive という 48bit LBA を採用した規格もあるが、特定のチップセットに限られています。

● GRUBの起動手順

GRUB は、二段階(stage1 + stage2)、または三段階(stage1 + stage1.5 + stage2)の手順を経て起動します。
stage1 はMBRにあるIPLです。
stage1.5 は、MBRの次のセクタから連続した数セクタに入っています。
stage2 は、ファイルシステム(ext2(Linux), ffs(FreeBSD等), minix, FAT(MS-DOS, Win95/98等))上にあるファイルになっています。

● stage2までの起動方法

a. stage1 + stage2 の場合

stage1 は、stage2 の実体が格納されているディスク上のアドレスを記憶しており、そのアドレスから連続した領域をメモリに読み込み、 それに処理を移します。

b. stage1 + stage1.5 + stage2 の場合

stage1 は、C/H/S=0/0/1 に格納されている stage1.5 をメモリに読み込み、それに処理を移します。
stage1.5 は、stage2 のあるファイルシステムを読めるので、stage2のあるパスを探して、ディスク上にどのような形で格納されているのかを確認し(FATならFAT chain をたどる)、メモリに読み込み、それに処理を移します。
stage2 が読まれるとstage2 は、メニューやコマンドプロンンプトを表示して、ユーザの指示に合ったカーネルをロードして起動します。

● stage1.5を使うメリット

MBR の stage1 がロードする stage2 の先頭セクタ、および stage2 の先頭セクタがロードする後続のセクタは、ファイルシステム (ext2/ext3) に頼らずセクタ位置を直接指定してロードします。
これは stage2 のファイル名を変更してもディスク上の位置 (セクタ) に変更がなければ grub は正常に起動できるが、見た目は同一ディレクトリ上に stage2 があっても、セクタ位置が変更されていると grub が正常に起動できないことを意味します。

stage2はファイルシステム上のファイルになっているので、容易に移動やコピー、削除ができてしまいます。 したがって、前者の構成ですと

# mv stage2 stage2_orig # cp stage2_orig stage2 # rm stage2_orig # dd if=/dev/zero of=fill_stage2_orig_space_with_zero

等のようなことをすると、stage2 という名前のファイルは最初と同様なものが存在しますが、元々あったstage2 のディスク上のアドレスにはゴミが入っているので、GRUBが起動しなくなります。
また、GRUB version 0.5.93.1 の段階では、stage1 からは 8GB(1024シリンダ) の範囲までしかディスクを読むことができないので、stage2 がこの領域よりも外側にあった場合はやはり起動しません。 この場合は、stage1_lba を使えばいいのですが、stage1_lba はLBAによるアクセスしか行なわないため、フロッピーにインストールしてそのフロッピーから起動する、ということができないという問題があります。
よって、stage1.5を使用する起動方法の方が安全です。

  • stage1
    場所: MBR(C/H/S=0/0/1)にあるIPL。リアルモードで動作する。
    サイズの上限: 446 bytes。 (512(セクタサイズ) - 16 * 4(パーティションテーブル) - 2(ブートシグネチャ 0xAA55))
    処理内容: stage1.5 または stage2 を読み込んで、それに処理を移す。

  • stage1.5
    場所: MBRの次のセクタから、先頭のパーティションの頭までの間のセクタにある。 (C/H/S=0/0/2 ~ 0/0/63)。
    サイズの上限: 31744 bytes。 (512(セクタサイズ) * (63(トラック当たりのセクタ数) - 1(MBRの分)))
    GRUB の info によると、10kB以下となっているが、これは、昔のHDDには1ヘッ ド当たりのセクタ数が63よりも小さいものがあるからそれに対応するためだと 思われる。実際コンパイルすると10kB以下になっている。
    処理内容: 指定されたファイルシステム上の指定されたパスに ある stage2 という名前のファイルを見つけ、データを読み込み、 それに処理を移す。

  • stage2
    場所: どこかのファイルシステム上にある「stage2」とう名前のファイル。
    ファイルシステムとしては、ext2 (Linux)、ffs (FreeBSD等)、minix (Minix)、 FAT (Win95/98, DOS等)がある。
    サイズの上限: 640kB ?
    処理内容: メニューやプロンプトを出し、OSを起動する。

(1)カーネルの読み込み
Linuxを起動するためにカーネル・イメージをメモリー上に読み込む。カーネル・イメージはbzip2やgzipで圧縮されたファイルです。

(2)initrdを読み込み
カーネル・イメージを読み込んだら、次に initrd ファイルを読み込む。initrd ファイルは、Linuxが起動するときに必要なモジュール(ドライバ)や起動スクリプトを含んだファイルです。通常gzipで圧縮されており、カーネル・イメージをメモリー上に読み込んだ後、カーネル起動時にメモリー上にファイル・システムとして展開されます。

(3)カーネルの起動
読み込みが完了したら、GRUBによってカーネルが起動されます。カーネルは自分自身と initrd ファイルを展開して、初期化処理を実施します。その際、展開された initrd ファイルを、起動時に用いるルート・ファイル・システムとしてマウントします。

(4)linuxrcスクリプトの実行
initrd ファイルには「linuxrc」というスクリプトが含まれています。この linuxrc スクリプトにはルート・ファイル・システムをマウントする際に必要なドライバをカーネルに読み込んでから、実際のルート・ファイル・システムをマウントするための処理が記述されています。

 必要なドライバを読み込んでから実際のルート・ファイル・システムをマウントするという処理になるため、PC内のいかなるデバイスにルート・ファイル・システムを保存している場合にも確実にマウントできます。

(5)初期化プロセスの実行
実際のルート・ファイル・システムをマウントしたら、今度はルート・ファイル・システム内にあるファイルを用いて初期化プロセスが実行されます。この初期化プロセスが完了すれば、Linuxが使えるようになります。


ブート時の処理

 Red Hat Linux 7.2では、ブート時に /etc/rc.d/rc.sysinit というスクリプトを実行するようになっています。/etc/inittab の、

# vi /etc/inittab
# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit

という行で定義されています。ざっとその内容を見ると、

  • ネットワークの初期化
  • ホスト名の設定
  • Welcomeバナーの表示
  • /procファイルシステムのマウント
  • カーネルパラメータの設定
  • クロックの設定
  • keymapの読み込み
  • システムフォントの読み込み
  • スワップの有効化
  • USBの初期化
  • 必要に応じてfsckの実行
  • quotaの有効化
  • ハードディスクパラメータの設定
  • カーネルモジュールの読み込み
  • RAIDデバイスの組み込み
  • ファイルシステムのマウント

rcスクリプトの管理の仕組み

rcスクリプトは、Windowsのautoexec.batのようなものです。もちろん、rcスクリプトとautoexec.batでは異なる点があります。rcスクリプトは、対応する作業ごとに1つずつ、複数のファイルで構成されています。また、ランレベルごとに実行するrcスクリプトを変えることができます。

rcスクリプトの実体は、/etc/init.d に収められている単なるシェルスクリプトです。そして、/etc ディレクトリには各ランレベルに対応したディレクトリ /etc/rc0.d?/etc/rc6.d が用意されています。これらのディレクトリに、/etc/init.d 内のrcスクリプトへのシンボリックリンクを作って利用します。例えば、Apacheを起動する「httpd」というスクリプトが /etc/init.d にあり、ランレベル3でApacheを利用する場合は /etc/rc3.dに/etc/init.d/httpd のシンボリックリンクを作るというわけです。

各ディレクトリに作成するシンボリックリンクのファイル名は、原則として「S」+「2けたの数値」(※注1)で始め、その後に実体のファイル名を続けることになっています。例えば、「S85httpd」という具合です。2けたの数字は実行順の制御に使われ、数字が小さいスクリプト→大きいスクリプトの順番で実行されます。

※注1:数値はディストリビューションなどによって異なる場合がある。また、数値を変更することも可能だが、サービスによっては起動順に気をつける必要がある。

ランレベルごとのディレクトリを見ると、ファイル名が「K」で始まるファイルがあります。これは、サービスなどを停止するスクリプトです。 Kで始まるスクリプトが必要になる典型例が、ランレベル1、すなわちシングルユーザーモードに移行する場合です。シングルユーザーモードでは必要最小限のサービスだけにする必要があるので、マルチユーザーモードで動いているサービスを明示的に止めなければなりません。

各ランレベルのディレクトリにあるのはシンボリックリンクです。これによって1つのrcスクリプトを複数のランレベルで共有できます。/etc/rc[0-6].d以下にそれぞれファイルの実体を配置した場合、あるファイルを修正するとそのファイルを必要とする各ディレクトリにコピーしなければなりません。実際にはシンボリックリンクなので、シンボリックリンク元のファイルを変更するだけで/etc/rc[0-6].d以下にも修正が自動的に反映されます。

不要なサービスを停止する場合は、Red Hat Linux 7.2の /etc/rc3.d ディレクトリ(ランレベル3用)には、標準で S09isdn や S90FreeWnn といったシンボリックリンク(※注2)があります。

※注2:S09isdnは/etc/init.d/isdn、S90FreeWnnは/etc/init.d/FreeWnnが実体のスクリプト。

これらによって起動されたサービスを止めるには、root権限でstopを引数にして該当スクリプトを実行します。例えば、FreeWnnを止めるなら、

# /etc/rc3.d/S90FreeWnn stop

また、起動時から不要なサービスであれば、/etc/rc[0-6].dにあるシンボリックリンクを削除します。元のファイルは /etc/init.d に残っているので、必要になった時点でもう一度シンボリックリンクを作成します。GUIベースでこれを行ってくれるツールもありますが、要はシンボリックリンクを作ったり削除したりするだけです。原理が分かっていれば、sshでログインしてコマンドラインで簡単に変更できます。

● System VとBSD

これまでに説明してきた仕組みは、System Vのやりかたです。
rcスクリプトにはもう1つ、BSD風もあり、こちらは/etc/に直接rcスクリプトを配置します。この場合は、まずシングルユーザーモードで起動し、マルチユーザーモードに移行する時点で一般的なrcや各ホスト固有の設定を行うrc.localなどを実行します。
最近主流のRed Hat系のディストリビューションやDebian GNU/LinuxではSystem V方式を取っていますが、Red Hatの前に主流だったSlackwareではBSD風のrcスクリプトが使われています。


z. 出題範囲概要

●主要な知識範囲
LSB(Linux Standard Base Specification:Linux標準仕様)
●重要なファイル、用語、ユーティリティ
/etc/inittab /etc/init.d/ /etc/rc.d/ chkconfig update-rc.d


  [ 例題 ] 
  1. 201:202.1 問01  chkconfig
  2. 201:202.1 問02  insserv
  3. 201:202.1 問03  システムサービス起動中のエラー
  4. 201:202.1 問04  update-rc.d
  5. 201:202.1 問05  システムの起動時に実行される起動スクリプト


     

www.it-shikaku.jp