Linuxの起動手順に関してまとめました。
起動手順はアーキテクチャによって異なるため、x86系についてまとめました。
Linuxの起動順
Linuxの起動手順は次の手順で起動します。
/etc/inittabに基づいて/etc/rcスクリプトを実行する。
BIOSとUEFI
ここでは、旧来のBIOSとUEFIの2つについて調べてみました。
BIOS(Basic Input / Output System)
Linuxだけでなく、ほとんどのPCにおいて、ローレベルな制御プログラムとして組み込まれているのがBIOSになります。
BIOS(Basic Input/Output System)は不揮発性メモリに格納されており、基本的な入出力の管理を行います。
BIOSは電源投入後に、最初に実行される命令であるリセットベクターが、メモリ内のプログラムを実行することで、
デバイスの初期化を行い、決まった手順に従ってブートローダーにCPUの制御を移行します。
ここの手順は非常に複雑で説明が難しいですが、主な実行される作業内容は以下の通りです。
・ハードウェアの設定の読み込み(自己診断と初期化)
・起動デバイスのチェック
・起動デバイスのブートローダーの実行
これまでBIOSは、マザーボード上にフラッシュメモリーBIOSが主流でしたが、現在はSPI仕様が主流になっているそうです。
旧来のBIOS
旧来のBIOSには次のような不便が多発しました。
・16Bit
旧来のBIOSは、最初に読み込まれるコードが16bitであったため、その後に登場した32bitや64bitのOSに移り変わるにつれて非常に不便な存在になってしまいます。
x86系マシンは、16bitモードのメモリー空間はわずか1MBしか割り当てられえていませんでした。
PCがどれだけ容量の大きいメモリを確保していても、16bitモードからアクセス可能なメモリはわずか1MBと決まってしまいました。
1MBではカーネルを読み込むことどころか、起動するのがやっとな状態です。
・ハードディスクの制限(物理的仕様の制限)
旧来のBIOSによるデバイス管理は、CHS方式を採用していました。
CHS方式は、ハードディスクの記録単位である、シリンダ、ヘッド、セクターを検索し読み込む方式です。(詳しい説明は色んなサイトに掲載されているので割愛)
このシリンダー、ヘッド、セクタを基に、毎回探索しては入出力してを繰り返していました。
ただし、これは旧来のBIOSだからCHS方式を採用していたと言わけではないです。現在は使用が変わっており、LBA方式を採用することが一般的です。
LBA方式は、先頭のセクターから最終セクターまで連番を与え、その番号でディスクの位置を管理しています。
これまでのシリンダ、ヘッド、セクタといったハード依存することなく、ディスク位置や管理をすることが可能となりました。
・容量制限
一部OSにおける起動ドライブの容量制限が2TBと決められている。
UEFI(Unified Extensible Firmware)
旧来のBIOSは現在となっては、かなりレガシーな存在となってしまいました。
BIOSの後継となるファームウェア規格、UEFI(Unified Extensible Firmware)が登場しました。
現在は、UEFIもBIOSといったファームの総称してBIOSと呼ばれることが多いです。
このUEFIは、これまでのBIOSの欠点を解消したものになっています。
BIOSと異なる点
ブート手順
マスターブートレコード
マスターブートレコード(MBR)は、起動デバイスの先頭セクタに格納されている情報です。
この部分では、OSを起動するためのブートローダの一部と、基本パーティションの情報を収めたパーティションテーブルが含まれています。
ブートローダ
ブートローダは、2段階に分かれています。
そもそも、マスターブートレコードとブートローダの2段構えの構造をしている理由は、
マスターブートレコードに格納されているブートローダのサイズが制限されており、ブートローダ全体を格納できないためです。
カーネルの起動
カーネルは、initプロセス(/sbin/init)を最初に必ず実行します。実行内容は以下の通りです。
カーネルが起動時にどのような処理を実行したかを確認するにはdmesgコマンドを使用します。
initプロセスと/etc/inittab
カーネルが最初に起動するプロセスがinitプロセスになります。
このプロセスは、設定ファイル/etc/inittabに基づき、様々な起動処理が実行されます。
ですが、最近/etc/inittabは見当たらないディストリビューションが出てきていると思います。
/etc/inittabの代わりに、ディレクトリ/etc/init/以下に存在する設定ファイルに各々の設定を記述する仕様になっているため、/etc/inittabは存在しません。
/etc/inittab
mxlinux@mxlinux:~ $ cat /etc/inittab # /etc/inittab: init(8) configuration. # $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $ # The default runlevel. id:5:initdefault: # Boot-time system configuration/initialization script. # This is run first except when booting in emergency (-b) mode. si::sysinit:/etc/init.d/rcS # What to do in single-user mode. ~~:S:wait:/sbin/sulogin # /etc/init.d executes the S and K scripts upon change # of runlevel. # # Runlevel 0 is halt. # Runlevel 1 is single-user. # Runlevels 2-5 are multi-user. # Runlevel 6 is reboot. l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 # Normally not reached, but fallthrough in case of emergency. z6:6:respawn:/sbin/sulogin # What to do when CTRL-ALT-DEL is pressed. ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now # Action on special keypress (ALT-UpArrow). #kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work." # What to do when the power fails/returns. pf::powerwait:/etc/init.d/powerfail start pn::powerfailnow:/etc/init.d/powerfail now po::powerokwait:/etc/init.d/powerfail stop # /sbin/getty invocations for the runlevels. # # The "id" field MUST be the same as the last # characters of the device (after "tty"). # # Format: # <id>:<runlevels>:<action>:<process> # # Note that on most Debian systems tty7 is used by the X Window System, # so if you want to add more getty's go ahead but skip tty7 if you run X. # 1:2345:respawn:/sbin/getty --noclear 38400 tty1 2:2345:respawn:/sbin/getty 38400 tty2 3:2345:respawn:/sbin/getty 38400 tty3 4:2345:respawn:/sbin/getty 38400 tty4 5:2345:respawn:/sbin/getty 38400 tty5 6:2345:respawn:/sbin/getty 38400 tty6 # Example how to put a getty on a serial line (for a terminal) # #T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100 #T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100 # Example how to put a getty on a modem line. # #T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3 #-- isdnutils begin # Change the line below for your local requirements and uncomment them. # Use "init q" to reread inittab. # look at the mgetty manpage for more information (mgetty isn't standard!) # #I0:2345:respawn:/sbin/mgetty -D -m '"" ATZ OK AT&Eyourmsnhere OK AT&B512 OK' -s 38400 ttyI0 #-- isdnutils end
/etc/inittabの書式は以下の通りです。
①ID:エントリを認識するためのID
②ランレベル:エントリが行う処理のランレベル
③アクション指定子:どんな処理をどのようなタイミングで実行するかを決定する
④処理内容:initが実行するプロセス内容
そして、以下の表はアクション指定子一覧です。
アクション指定子 | 説明 |
---|---|
boot | システム起動時に実行され。プロセスの終了を待たずに次の処理を行う。 |
bootwait | システム起動時に実行され、プロセスが終了するまでの処理を行わない。 |
ctlaltdel | Ctrlキー+Altキー+Deleatキー同時押しで、SIGNALがinitに送られた場合に実行する |
initdefault | デォルトのランレベルを指定する |
once | 指定したランレベルになった時に一度だけ実行される。プロセスの終了は待たずに次の処理を行う。 |
respawn | 指定したプロセスが終了すれば再起動される。 |
sysint | システム起動時に、bootやbootwaitよりも先に実行される。 |
wait | 指定したランレベルになった時に、一度だけ実行され、プロセスが終了するまで次の処理を行わない。 |
・/etc/init/以下の設定ファイル
mint@mint-VirtualBox:~$ ls -l /etc/init 合計 8 -rw-r--r-- 1 root root 278 5月 30 2017 anacron.conf -rw-r--r-- 1 root root 1444 3月 22 2018 lightdm.conf
起動スクリプト
プロセスやサービスの起動は、ランレベルによってルールづけられています。
どのサービスがどのランレベルで起動するかは、/etc/rc0~6.dディレクトリで確認することができます。
※0~6はランレベル
mxlinux@mxlinux:~ $ ls -ld /etc/rc* -rwxr-xr-x 1 root root 360 4月 28 00:01 /etc/rc.local drwxr-xr-x 2 root root 4096 4月 26 02:18 /etc/rc0.d drwxr-xr-x 2 root root 4096 4月 26 02:18 /etc/rc1.d drwxr-xr-x 2 root root 4096 4月 26 02:18 /etc/rc2.d drwxr-xr-x 2 root root 4096 4月 26 02:18 /etc/rc3.d drwxr-xr-x 2 root root 4096 4月 26 02:18 /etc/rc4.d drwxr-xr-x 2 root root 4096 4月 26 02:18 /etc/rc5.d drwxr-xr-x 2 root root 4096 4月 26 02:18 /etc/rc6.d drwxr-xr-x 2 root root 4096 4月 25 11:25 /etc/rcS.d
例として、ランレベル5のディレクトリを確認します。
mxlinux@mxlinux:~ $ ls -l /etc/rc5.d/ 合計 4 -rw-r--r-- 1 root root 677 2月 15 2019 README lrwxrwxrwx 1 root root 26 2月 10 04:02 S01console-setup.sh -> ../init.d/console-setup.sh lrwxrwxrwx 1 root root 22 2月 10 03:56 S02acpi-fakekey -> ../init.d/acpi-fakekey lrwxrwxrwx 1 root root 19 2月 10 04:02 S02cgmanager -> ../init.d/cgmanager lrwxrwxrwx 1 root root 23 2月 10 04:14 S02lvm2-lvmpolld -> ../init.d/lvm2-lvmpolld lrwxrwxrwx 1 root root 27 4月 25 11:25 S02nfs-kernel-server -> ../init.d/nfs-kernel-server lrwxrwxrwx 1 root root 14 2月 10 04:11 S02nmbd -> ../init.d/nmbd lrwxrwxrwx 1 root root 17 2月 10 03:54 S02rsyslog -> ../init.d/rsyslog lrwxrwxrwx 1 root root 21 2月 10 04:11 S02samba-ad-dc -> ../init.d/samba-ad-dc lrwxrwxrwx 1 root root 23 2月 10 03:54 S02stop-bootlogd -> ../init.d/stop-bootlogd lrwxrwxrwx 1 root root 14 2月 10 03:54 S02sudo -> ../init.d/sudo lrwxrwxrwx 1 root root 13 2月 10 04:05 S02tlp -> ../init.d/tlp lrwxrwxrwx 1 root root 29 2月 10 04:08 S02unattended-upgrades -> ../init.d/unattended-upgrades
以下のルールでファイル名がつけられています。
②「S」に続く数値は起動順を表し、数値が低いほど先に起動
③このランレベルで処理が終了するものは、ファイル名の前に「K」がつく
④サービスやプロセスの登録は、シンボリックリンクを発行する
起動したいサービスやプロセスは、/etc/rc0~6以下のディレクトリに新規にファイルを作成し、そのファイルを対象のサービスにシンボリックリンクを発行します。
サービスの起動や終了の制御は以下のようにコマンドを実行すると、制御可能になります。
sambaプロセスを制御
mxlinux@mxlinux:~ $ /etc/init.d/samba-ad-dc stop [ ok ] Stopping Samba AD DC daemon: samba. mxlinux@mxlinux:~ $ /etc/init.d/samba-ad-dc start mxlinux@mxlinux:~ $ /etc/init.d/samba-ad-dc restart [ ok ] Stopping Samba AD DC daemon: samba. mxlinux@mxlinux:~ $ /etc/init.d/samba-ad-dc status [FAIL] samba is not running ... failed!
主なサービス制御コマンド
コマンド | 説明 |
---|---|
start | サービスを開始 |
stop | サービスを終了 |
restart | サービスを再起動 |
condrestart | サービスが起動している場合のみ再起動 |
status | サービスの状態を表示 |
サービス起動に関する補足
RHEL(Red Hat Enterprise Linux)、Ubuntuでは、servieコマンドを使用した方が主流だと思います。
その理由は、/etc/rcスクリプトで制御する方式に変わり、新たなサービス制御であるUpstartやsystemdが台頭してきているためです。
serviceコマンドと/etc/rcスクリプトは処理内容は変わりませんが、serviceコマンドの方がサービスを統一的に扱えるのも利点になるで、
serviceコマンドで制御する方法使った方が、これからは良さそうです。
参考にした資料・テキスト
コメント