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的設定檔 – https://benjr.tw/134下面是 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 最主要工作是
- 偵測裝置
- 初始化裝置
- 接下來系統會以唯讀方式去掛載 " / " (root)
- 執行 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 ,至於其他檔是做什麼的,請參考無磁碟系統 https://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 決定不同的服務是否啟動或關閉. - 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 - trap certain key sequences
# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
使用者可以按 "ctrl-alt-delete" 來 Reboot 系統,建議將他 "#" 起來,以防止其他使用者關掉系統. - 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" - 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. - 系統的 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 -> ../init.d/rhnsd lrwxrwxrwx 1 root root 11 Aug 12 02:45 S99local -> ../rc.local lrwxrwxrwx 1 root root 19 Aug 12 03:31 S99mdmonitor -> ../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
- /etc/profile
- /etc/profile.d
- ~/.bash_profile
- ~/.bashrc
- /etc/bashrc
logout system 會用到的 shell
- ~/.bash_logout
Step 9 : 關機 shutdown 與重新啟動系統 Reboot
關機:
- # shutdown -h now .
- # halt .
- # poweroff .
- # init 0 .
重新啟動系統:
- # shutdown – r now .
- # reboot .
- # init 6.
2 thoughts on “Linux – 開機流程”