3,709 瀏覽數

Linux 開機流程

Linux開機流程
Step 1 : Boot Loader(GRUB or LILO )從 BIOS 取得控制權
Step 2 : 載入 kernel
Step 3 : 載入 initrd (必須在 Boot Loader 指定才會載入)
Step 4 : kernel 執行的第一個程式/sbin/init
Step 5 : init 執行的第一個script:/etc/rc.d/rc.sysinit
Step 6 : init 執行 run-level 目錄下的scripts
Step 7 : 執行 /etc/rc.d/rc.local script
Step 8 : 最後執行 /bin/login 程式
Step 9 : 關機 shutdown 與重新啟動系統 Reboot

Step 1 : Boot Loader(GRUB or LILO )從 BIOS 取得控制權

RedHat Linux 預設使用 GRUB(GRand Unified Bootloader) 為 Boot Loader,關於 boot loader 設定請參考 GRUB的設定檔 下面是 GRUB 的一般範例設定.

[root@benjr ~]# cat /boot/grub/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You do not have a /boot partition. This means that
# all kernel and initrd paths are relative to /, eg.
# root (hd0,1)
# kernel /boot/vmlinuz-version ro root=/dev/hda2
# initrd /boot/initrd-version.img
#boot=/dev/hda
default=0
timeout=10
splashimage=(hd0,1)/boot/grub/splash.xpm.gz
title Red Hat Linux (2.4.18-3)
root (hd0,1)
kernel /boot/vmlinuz-2.4.18-3 ro root=/dev/hda2
initrd /boot/initrd-2.4.18-3.img

Boot loader 在載入時可以分為兩個 stages

  • first stage: BIOS 的 IPL(Initial Program Loader) 會將開機硬碟的前 512 bytes 載入系統.
  • second stage: 讀取 /boot 磁區的資料,通常看到開機選項項已經是 second stage.

Step 2 : 載入 kernel

kernel 最主要工作是

  1. 偵測裝置
  2. 初始化裝置
  3. 接下來系統會以唯讀方式去掛載 " / " (root)
  4. 執行 init (若 bootloader 有指定 initrd 時, initrd 會先去執行)

Step 3 : 載入 initrd (必須在 Boot Loader 指定才會載入)

initrd 主要的動作是先掛載系統必須的 modules 等….而載入 initrd 後會去執行 linuxrc (linuxrc 包在 initrd 檔裡面,下面會說明),我們先來看看 RedHat 安裝好後的 initrd 做些什麼.

[root@benjr ~]# ll /boot/*.img
-rw-r--r-- 1 root root 151233 Sep 6 20:27 initrd-2.4.20-8.img

先複製到 /root 下,改名稱為 .gz ,因為 initrd-2.4.20-8.img 檔是 gzip 壓縮過的檔案格式,所以要解壓縮.

[root@benjr ~]# cp /boot/initrd-2.4.20-8.img /root/initrd-2.4.20-8.img.gz
[root@benjr ~]# gunzip /root/initrd-2.4.20-8.img.gz

initrd 是映像檔,所以 mount 要加 -o loop 的參數

[root@benjr ~]# mount -o loop /root/initrd-2.4.20-8.img /mnt/tmp

Linux 2.6 核心採用新版的 initial RAM disks "initramfs" 壓法也些不同了所以要用下面的方式解開.

[root@benjr ~]# cpio -div < initrd-2.6.31.img

現在可以看到 initrd 檔的內容.

[root@benjr ~]# cd /mnt/tmp
[root@benjr ~]# ll
total 8
drwxr-xr-x 2 root root 1024 Aug 12 02:45 bin
drwxr-xr-x 2 root root 1024 Aug 12 02:45 dev
drwxr-xr-x 2 root root 1024 Aug 12 02:45 etc
drwxr-xr-x 2 root root 1024 Aug 12 02:45 lib
-rwxr-xr-x 1 root root 829 Sep 6 20:26 linuxrc
drwxr-xr-x 2 root root 1024 Aug 12 02:45 loopfs
drwxr-xr-x 2 root root 1024 Aug 12 02:45 proc
lrwxrwxrwx 1 root root 3 Aug 12 02:45 sbin->bin
drwxr-xr-x 2 root root 1024 Aug 12 02:45 sysroot

系統載入 initrd 時會先去執行 linuxrc 這個 script ,至於其他檔是做什麼的,請參考無磁碟系統 http://benjr.tw/20794 我們就來看看 linuxrc 寫了些什麼.

[root@benjr ~]# cat linuxrc
#!/bin/nash
echo "Loading jbd.o module"
insmod /lib/jbd.o
echo "Loading ext3.o module"
insmod /lib/ext3.o
echo Mounting /proc filesystem
mount -t proc /proc /proc
echo Creating block devices
mkdevices /dev
echo Creating root device
mkrootdev /dev/root
echo 0x0100 > /proc/sys/kernel/real-root-dev
echo Mounting root filesystem
mount -o defaults --ro -t ext3 /dev/root /sysroot
pivot_root /sysroot /sysroot/initrd
umount /initrd/proc

這裡主要的動作是先掛載系統必須的 modules 等….

Step 4 : kernel 執行的第一個程式/sbin/init

剛開機 init 會依據 /etc/inittab 檔案來決定做何種設定,我們來看看 /etc/inittab 做了什麼設定.

[root@benjr ~]# cat /etc/inittab
#
# inittab This file describes how the INIT process should set up
# the system in a certain run-level.
#
# Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
# Modified for RHS Linux by Marc Ewing and Donnie Barnes
#
# Default runlevel. The runlevels used by RHS are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:5:initdefault:
# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
# Things to run in every runlevel.
ud::once:/sbin/update
# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
# When our UPS tells us power has failed, assume we have a few minutes
# of power left. Schedule a shutdown for 2 minutes from now.
# This does, of course, assume you have powerd installed and your
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
# Run xdm in runlevel 5
# xdm is now a separate service
x:5:respawn:/etc/X11/prefdm -nodaemon
  • 決定開機的Level
    id:5:initdefault:
    下面是各個 runlevel 的定義
    runlevel 0 – halt (Do NOT set initdefault to this)
    runlevel 1 – Single user mode
    runlevel 2 – Multiuser, without NFS (The same as 3, if you do not have networking)
    runlevel 3 – Full multiuser mode
    runlevel 4 – unused
    runlevel 5 – X11
    runlevel 6 – reboot (Do NOT set initdefault to this)
    不同的 runlevel 決定不同的服務是否啟動或關閉.
  • II.system initialization scripts,而 rc.sysinit 將是 init 第一個要執行的 script.
    si::sysinit:/etc/rc.d/rc.sysinit
  • III.run level specific script directories
    l0:0:wait:/etc/rc.d/rc 0
    l1:1:wait:/etc/rc.d/rc 1
    l2:2:wait:/etc/rc.d/rc 2
    l3:3:wait:/etc/rc.d/rc 3
    l4:4:wait:/etc/rc.d/rc 4
    l5:5:wait:/etc/rc.d/rc 5
    l6:6:wait:/etc/rc.d/rc 6
    # Things to run in every runlevel.
    ud::once:/sbin/update
  • IV.trap certain key sequences
    # Trap CTRL-ALT-DELETE
    ca::ctrlaltdel:/sbin/shutdown -t3 -r now
    使用者可以按 "ctrl-alt-delete" 來 Reboot 系統,建議將他 "#" 起來,以防止其他使用者關掉系統.
  • V.Define UPS power fail/restore scripts
    # When our UPS tells us power has failed, assume we have a few minutes
    # of power left. Schedule a shutdown for 2 minutes from now.
    # This does, of course, assume you have powerd installed and your
    # UPS connected and working correctly.
    pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
    # If power was restored before the shutdown kicked in, cancel it.
    pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
  • VI.spawn gettys on virtual consoles
    # Run gettys in standard runlevels
    1:2345:respawn:/sbin/mingetty tty1
    2:2345:respawn:/sbin/mingetty tty2
    3:2345:respawn:/sbin/mingetty tty3
    4:2345:respawn:/sbin/mingetty tty4
    5:2345:respawn:/sbin/mingetty tty5
    6:2345:respawn:/sbin/mingetty tty6
    系統開機後可使用哪一些 virtual console
    如果要讓系統直接進入 Text mode 可以對 mingetty 下參數
    1:2345:respawn:/sbin/mingetty tty1 –autologin root
    這樣下次重開機 root 就會直接登入 tty1 的 console.
  • VII.系統的 runlvel 為 5 時, init 會去執行 prefdm 這支 script , prefdm 會去參考 /etc/sysconfig/desktop 來決定使用哪種 display manager (GNOME , KDE or XDM)
    # xdm is now a separate service
    x:5:respawn:/etc/X11/prefdm -nodaemon

Step 5 : init 執行的第一個script:/etc/rc.d/rc.sysinit

rc.sysinit 是一個 script ,有興趣的可以看看.它工作包括下列

  • Sets Kernel parameters in "/etc/sysctl.conf"
  • Sets the system clock
  • Loads keymaps
  • Enables swap paritions
  • Sets hostname define in "/etc/sysconfig/network"
  • Root filesystem check and mount define in "/etc/fstab"
  • Add RAID devices define in "/etc/raidtab"
  • Enable disk quotas define in "/etc/fstab"
  • Check and mount other filesystems define in "/etc/fstab"
  • Cleans up stale locks and PID files

Step 6 : init 執行 run-level 目錄下的scripts(這些 script 大多是用來啟動一些服務 service 如:samba,http…)

首先來看看和開機有關的目錄 /etc/rc.d下的檔案

[root@benjr ~]# ll /etc/rc.d/
total 64
drwxr-xr-x 2 root root 4096 Oct 9 22:52 init.d
-rwxr-xr-x 1 root root 3108 Sep 21 2001 rc
drwxr-xr-x 2 root root 4096 Oct 9 22:53 rc0.d
drwxr-xr-x 2 root root 4096 Oct 9 22:53 rc1.d
drwxr-xr-x 2 root root 4096 Oct 9 22:53 rc2.d
drwxr-xr-x 2 root root 4096 Oct 9 22:53 rc3.d
drwxr-xr-x 2 root root 4096 Oct 9 22:53 rc4.d
drwxr-xr-x 2 root root 4096 Oct 9 22:53 rc5.d
drwxr-xr-x 2 root root 4096 Oct 9 22:53 rc6.d
-rwxr-xr-x 1 root root 220 Jul 11 2001 rc.local
-rwxr-xr-x 1 root root 22379 Apr 19 17:55 rc.sysinit

這裡存放各個不同 runlevel 需要執行的 script . 要跑哪一個 runlevel 則定義在 /etc/inittab 檔案中.我們來看看 runlevel 的 rc5.d 目錄下有什麼

[root@benjr ~]# ll /etc/rc.d/rc5.d/
total 0
lrwxrwxrwx 1 root root 14 Aug 12 03:28 K05innd -> ../init.d/innd
lrwxrwxrwx 1 root root 19 Aug 12 02:46 K05saslauthd -> ../init.d/saslauthd
.......................................略...........................................................................
lrwxrwxrwx 1 root root 15 Aug 12 02:47 S97rhnsd -&gt; ../init.d/rhnsd
lrwxrwxrwx 1 root root 11 Aug 12 02:45 S99local -&gt; ../rc.local
lrwxrwxrwx 1 root root 19 Aug 12 03:31 S99mdmonitor -&gt; ../init.d/mdmonitor

其實這裡都是連結到 /etc/rc.d/init.d 目錄下,所以真正的 script 是存在 /etc/rc.d/init.d 下的,其中的名稱都是以 S 或 K 開頭再加上一串數字, S 代表在這個 runlevel 是要開啟這個 daemon ,而 K 代表在這個 runlevel 是要關閉的,數字則代表他們執行的先後順序.

最後你會發現 runlevel 2,3,4,5 目錄下皆有 S99local 並且指向 ../rc.local (ex:/etc/rc.d/rc5.d/S99local -> ../rc.local) ,所以最後系統會在去執行 /etc/rc.d/rc.local 這支 script.

Step 7 : 執行 /etc/rc.d/rc.local script

[root@benjr ~]# cat /etc/rc.d/rc.local
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.<br />
touch /var/lock/subsys/local

runlevel 2,3,4,5會執行 rc.local 這個 script,其中只有定義一行,你可以在這裡加入你想要執行的 script 等….

Step 8 : 最後執行 /bin/login 程式

相關的用到的檔案 /etc/issue,/etc/issue.net

[root@benjr ~]# cat /etc/issue
Red Hat Linux release 9 (Shrike)
Kernel \r on an \m

這就是 text mode 開機時顯示的訊息,如果從網路登入則要參考 /etc/issue.net
login system 會用到的 shell

  1. /etc/profile
  2. /etc/profile.d
  3. ~/.bash_profile
  4. ~/.bashrc
  5. /etc/bashrc

logout system 會用到的 shell

  1. ~/.bash_logout

Step 9 : 關機 shutdown 與重新啟動系統 Reboot

關機:

  1. # shutdown -h now .
  2. # halt .
  3. # poweroff .
  4. # init 0 .

重新啟動系統:

  1. # shutdown – r now .
  2. # reboot .
  3. # init 6.

2 個網友的想法 “Linux 開機流程

  1. 自動參照通知: Busybox | Benjr.tw

  2. 自動參照通知: Xinted | Benjr.tw

發表迴響