Linux啟動流程
- 作業系統的啟動流程
- 作業系統啟動的流程:
post-->BIOS(Boot Sequence)--->MBR(boot loader,446)-->kernel---> initrd ---> 查詢根檔案系統,啟動根檔案系統-->init(使用者空間的第一個程序);
post
加電自檢:將BIOS
中的程式對映進CPU
可以查詢的記憶體中的地址空間,ROM
對映進RAM
裡面,這些指令用於完成硬體裝置的檢查;- 關於
bootloader
:- 對於不同的作業系統來說是不同的,
Linux
與Windows
的bootloader
是不同的,windows
預設是鎖定MBR
的,不允許其他的操作來替換;Linux
bootloader
包括LILO(Linux Loader)
,不支援大硬碟或者分割槽,嵌入式一般使用這個; GRUB(Grand Unified bootloader)
:包含兩個階段;
stage1
:裝載在MBR
中了,目的是用來引導第二個階段的;stage1.5
:其中為了識別常用的stage2
的檔案系統,引入stage1.5
,用於支援常見的檔案系統;stage2
:第二個階段在/boot/grub/stage2
裡面,MBR
第一階段所訪問的/boot/grub/
是一個基本磁碟裝置,可以進行硬訪問,第二個階段是不受446
位元組的大小限制的設別,可以進行硬訪問;
grub
的stage2
階段的配置檔案/boot/grub/grub.conf
default=0
:表示預設啟動第一個作業系統;timeout
:等待使用者選擇的超時時長splashimage=
:用於指定背景圖圖片;Hiddenmenu
:表示隱藏選單;title
:表示核心標題,作業系統標題;root
:表示核心檔案所在的裝置,如果grub
找不到kernel
的位置,需要進入救援模式來手動探測核心所在的位置;grub
識別硬碟都是按照hd
開頭,第一個為hd0
;kernel
:一行表示kernel
檔案路徑以及傳遞給核心的引數;這一行和/proc/cmdline
檔案是一致的;這個knernel
是直接通過訪問核心所在的分割槽來訪問的,並不銅鼓根檔案系統,因為i這時,根檔案系統還沒有被識別;如果沒有進行單獨分割槽,就需要使用/boot/
initrd
:表示ram disk
檔案路徑,是在作業系統安裝的最後生成的,裡面各種檔案,除了核心檔案之外都有;/boot
:是一個獨立的分割槽,grub
訪問核心時,檔案系統還沒有載入,所以直接訪問磁碟上的/boot
,就不需要根來查詢對應目錄,也就不需要載入核心檔案系統這個操作;
grub
的應用:編輯介面:在系統啟動過程中,按e
進入編輯介面;a
可以用於修改核心引數;c
:可以用於進入命令列介面;b
:用於進行重新啟動;- 如果需要新增
grub
密碼:在title
上面新增password
,使用命令grub-MD5-crypt
:可以用於新增grub
加密後的密碼,格式為password --md5
; - 如果密碼檔案放在了
title
下面.表示在裝載核心時,需要輸入密碼;
- 如果需要新增
- 對於不同的作業系統來說是不同的,
BIOS
:裡面設定這作業系統的順序,一次去查詢這些裝置的MBR
,bootloader
查詢作業系統所在的分割槽,並且載入核心,轉載進入記憶體;最後kernel
獲得控制權,識別檔案系統,探測核心,識別關鍵裝置;- 檢視系統的執行級別:
who -r
:用於檢視當前系統的執行級別;runlevel
:也是用於檢視當前系統的執行級別的,前面的N
表示沒有進行級別切換;
grub
的損壞和修復:- 使用命令破壞前
446
個位元組,dd if/dev/zero of=/dev/sda count=1 bs=400
,建議使用虛擬機器進行測試,不要再真機上面進行測試; - 使用
sync
進行同步; root(hd0,0)
硬碟等裝置,通常被grub
識別為hd
開頭的裝置,通常MBR
位置0
分割槽;setup(hd0)
安裝:- 或者直接使用
grub-install –root-directory=/grub
所在的位置;往其他硬碟上裝載grub
; - 建立三個分割槽:建立一個
boot
目錄,掛載一塊磁碟,使用命令grub-install-root-directory=/mnt/dev/hda
; - 編輯
/mnt/boot/grub/grub.conf
- 新增:
- 使用命令破壞前
defaultlt=0
timeout=5
title Fake linux
root(hd0,0)
kernel /vmlinux
initrd /initrd.img
-
再次強調一下千萬不要拿
grub.conf
開玩笑,不然系統就毀了;否則就得自己寫一個;使用find (hd0,0)/
來查詢核心所在的位置;首先指定root (hd0,0)
在執行kernel/vmlinux-2.6-補全檔案
所在的位置;在指定initrd /initrd-2.6-補全
,然後使用boot
進行重啟; -
核心初始化的過程:
- 1.裝置探測;
- 2.驅動初始化,需要從
initrd
檔案中裝在驅動模組,redhat6
稱為initramfs
- 3.以只讀方式掛載根檔案系統;
- 4.裝載第一個程序
init
,PID
為1
的程序;
-
/sbin/init
:通常讀取的檔案是/etc/inittab
upstart
:一個可執行程式,速度比較快redhat6.0
以後開始使用,可以用於並行啟動程序;systemd
:並行啟動多個程序的init
程序,並行能力更強,但是可能不太穩定,基於事件啟動;redhat5
和redhat6
上面的init
程序是不相同的,配置檔案也不相同;init
都是inittaab
切割後的各種片,每一個檔案都是基於事件驅動的方式來啟動的;
-
redhat5
的/etc/inittab
檔案:
- 三個冒號分開的四段:
ID
:表示識別符號,必須與每一行都不相同;runlevel
:表示在那個級別下執行這個動作;action
:表示執行的動作,什麼時候執行這個動作;sysinit
:表示系統初始化;wait
:表示級別切換到次級別時,執行一次;respawn
:一旦程式終止,會重新啟動;
process
:要執行的程序程式;如果不指定級別,表示的就是所有級別;
K
開頭的表示停止,S
開頭的表示啟動,檔案裡面的大多數表示的是連結檔案,其實各個執行的級別後面代表的都是一個個服務或者指令碼檔案,然後通過一個指令碼來同一控制這些指令碼的執行;/etc/inittab
執行的任務:- 1.設定預設的執行級別;
- 2.執行系統的初始化指令碼;
- 3.執行指定執行級別對應目錄下的指令碼;
- 4.設定
Ctrl+Alt+delete
組合鍵的操作; - 5.啟動虛擬終端
(2345)
; - 6.啟動圖形終端(
5
級別); - 7.定義
UPS
電源在電源故障時,恢復時執行的指令碼
- 三個冒號分開的四段:
-
/etc/rc.d/rc.sysinit
完成的任務:
#!/bin/bash
#
# /etc/rc.d/rc.sysinit - run once at boot time
#
# Taken in part from Miquel van Smoorenburg's bcheckrc.
#
HOSTNAME=$(/bin/hostname)
set -m
if [ -f /etc/sysconfig/network ]; then
. /etc/sysconfig/network
fi
if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then
HOSTNAME=localhost
fi
if [ ! -e /proc/mounts ]; then
mount -n -t proc /proc /proc
mount -n -t sysfs /sys /sys >/dev/null 2>&1
fi
if [ ! -d /proc/bus/usb ]; then
modprobe usbcore >/dev/null 2>&1 && mount -n -t usbfs /proc/bus/usb /proc/bus/usb
else
mount -n -t usbfs /proc/bus/usb /proc/bus/usb
fi
#remount /dev/shm to set attributes from fstab #669700
mount -n -o remount /dev/shm >/dev/null 2>&1
#remount /proc to set attributes from fstab #984003
mount -n -o remount /proc >/dev/null 2>&1
. /etc/init.d/functions
* 1.啟用`udev` 和 `selinux`;
* 2.根據`/etc/systl.conf`檔案來設定核心引數;
* 3.設定時區時鐘;
* 4.裝載鍵盤對映;
* 5.啟用交換分割槽;
* 6.設定主機名;
* 7.根檔案系統檢測,並且以只讀方式重新掛載;
* 8.啟用`RAID`裝置和`LVM`裝置;
* 9.啟用磁碟配額;
* 10.根據`/etc/fstab`,檢查並掛載其他檔案系統;
* 11.清理過期的的鎖和`PID`檔案;
-
init
:使用者空間的主導程式,使用者空間的管理都由init
管理; -
核心的設計風格
-
在核心啟動之前,檔案系統是沒有啟動的,核心所在的分割槽是由
bootloader
來識別的,所以bootloader
需要來識別檔案系統;根檔案系統是訪問其他目錄或者檔案的入口,根檔案系統是自引用的,這個過程由核心完成,核心必須可以探測訪問核心所在的分割槽,但是由於磁碟硬體的不同,這些驅動不可以全部做入核心,所以存在兩種核心設計理念; -
單核心設計:把所有功能都做進核心,檔案系統,程序管理等功能,邏輯上簡單,但是導致核心系統十分龐大;
-
微核心設計:將上述功能做成一個子系統,驅動程式,檔案系統作為子系統,一個子系統壞掉,不影響正常啟動,彼此之間的協調很複雜;
-
Linux
是單核心設計支援LWP
輕量級程序,Linux
對於執行緒的支援並不是很好;核心程式碼十分龐大,按照自己的實際需要進行編譯安裝,Linux
同時也引入了微核心的思想;核心的設計是模組化的,有核心和其他模組組成,核心核心可以動態的載入所需要的核心模組,在/lib/modules/
裡面核心版本號命名的目錄/模組之間是有依賴關係,有一個檔案來解決依賴;命令一般為vmlunuz-2.6.32
目錄在裡面有檔案系統,驅動程式,加密解密程式等; -
linux
採用模組化設計,由核心模組和外為模組組成;- 核心的核心功能稱為
ko
,核心核心本身很小,在需要使用的時候,如果已經完成過編譯,就只需要進行載入就可以了; - 外圍模組: 大多數模組都在目錄
/lib/modules/核心版本號碼
裡面,也就是核心所需要的模組在某個裝置上,而訪問該裝置的驅動程式也在這個裝置上; - 所以需要在核心和需要訪問的是裝置之間新增一個程式檔案,這個檔案不是事先編譯好的,而這個程式檔案,也就是這個檔案並不是事先在編譯核心是就提供的,而是根據核心和
BISO
生成的相關硬體配置資訊,在安裝作業系統時生成的一個檔案,這個裝置可以成為橋接裝置;- 這個裝置檔案提供一個獨立的檔案系統,用於核心來訪問,這是一個偽檔案系統,用於臨時的根切換,同時將該檔案系統的
/proc
,/sys
,/dev
,轉到真正的根檔案系統;
- 這個裝置檔案提供一個獨立的檔案系統,用於核心來訪問,這是一個偽檔案系統,用於臨時的根切換,同時將該檔案系統的
- 在
redhat6
的bash-shell
使用的是命令chroot
,但是在rhel5
上面使用的是nash
提供的命令switch-root
,
- 核心的核心功能稱為
-
/lib/modules/核心版本號碼
:
dep
:表示的都是核心依賴檔案;alias
:表示的是核心別名檔案;map
:表示的是核心對映關係;kernel
:
arch
:表示和平臺相關的檔案;crypto
:表示和加解密相關的檔案;drivers
:表示和驅動相關的檔案;fs
:表示和檔案系統相關的檔案;lib
:表示依賴的庫檔案;mm
:表示的是記憶體管理相關的檔案;net
:表示網路相關的檔案,通常是驅動協議,不是驅動程式;sound
:表示和聲音相關的檔案;
-
在
nash shell
中提供了一個switch root
來完成根切換;偽檔案系統裡面的檔案可以講記憶體中的一段空間模擬成硬碟來使用,這段空間稱為ramdisk
或者ram filesystem
,使用這段空間來展開偽檔案系統中的檔案,核心訪問根檔案系統需要驅動程式和檔案系統來進行訪問; -
這段地址空間在
rhel5
上面稱為ramdisk--->initrd
,在rhel6
上面ramfs-->initramfs
-
使用者空間的命令用於實現根切換的命令是
chroot
;- 首先建立一個目錄
chroot
- 然後建立
/bin/bash
,在chroot
裡面的目錄,也就是./bin/bash
- 使用
ldd /bin/bash
依賴的庫檔案,並且建立庫檔案的相對目錄,複製庫檔案到對應的目錄裡面; - 按照上面的過程同時還可以複製一些常見的命令檔案過去,在這個目錄底下,就可以執行這些檔案;
- 首先建立一個目錄
-
bootloader
是完成kernel
和initrd
的載入的,最後將initrd
交給kernel
使用; -
Init
的功能:- 定義作業系統的執行級別:
0
:表示halt
,表示停止作業系統,但是不關閉電源;1
:single user root
表示單使用者模式,直接登入管理員,不適用密碼登入,使用s或者 S
或者single
都可以進入單使用者模式;2
:multi user root
:表示多使用者模式,啟用網路功能,但是不啟用NFS
等網路檔案系統;3
:multi user root
:多使用者模式,啟用正常的系統功能,但是是文字模式;4
:reserved
:保留級別,暫時沒有定義;5
:multi user root
:多使用者啟動圖形介面;6
:reboot
:重啟,如果定義為這個級別,系統會一直重新啟動;
- 定義作業系統的執行級別:
-
/etc/rc.d/rc.sysinit
檔案的內容:Si::sysinit:/etc/rc.d/rc.sysinit
.完成OS
的初始化,裡面對應的K
開頭的檔案和S
開頭的檔案,都是按照級別等級需要執行的,這些指令碼都是Linux
執行的服務指令碼,對於這些指令碼至少需要接受四個引數:start stop restart status
,以及reload configtest
;- 指令碼的規範:
- 服務指令碼都有相同意義的兩行
chkconfig
:用來定義定義這個指令碼來建立一個連結,三組數字分別表示為:- 啟動的執行級別:也就是這些程式在哪些執行級別下面執行;
SS
啟動的優先順序:表示相對於其他應用程式的啟動優先順序;KK
關閉的優先順序:表示相對於其他應用程式的關閉優先級別;description
:這個指令碼檔案完成的工作的一個大致的介紹;
- 服務指令碼都有相同意義的兩行
- 當
chkconfig
命令為此指令碼來建立連結時,runlevels
表示建立預設為S
開頭的連線,除此之外的級別預設建立為K
開頭的連結;S
後面的啟動優先順序為SS
所表示的數字,K
後面關閉優先順序為KK
所代表的數字;runlevel
後面可以為–
表示預設沒有開頭為S
的連結; chkconfig
命令:--list
:用於列出所有獨立守護程序的啟動設定,可以使用chkconfig –list SERVICE_NAME
檢視某個具體的服務;--add SERVICE_NAME
:用於自動建立服務指令碼所使用的連結;--del SERVICE_NAME
:用於刪除服務的連結檔案;--level runlecvels SERVICE_NAME {on | off}
:用於指定在那個級別開啟或者關閉,如果省略級別指定預設為2345
級別;
/etc/rc.d/rc.local
檔案,本質上是一個連結檔案- 系統最後執行的一個指令碼,可以用於自定義一些自己需要的服務,不方便寫成指令碼的
服務,感覺很有用;
- 系統最後執行的一個指令碼,可以用於自定義一些自己需要的服務,不方便寫成指令碼的
-
使用
chkconfig
管理的服務通常稱為獨立守護服務,就是自己來管理自己應該在那些級別下面啟動,在那些情況下開啟; -
守護程序型別
-
獨立守護程序:服務的關閉啟動等是自己進行管理,這種型別的程序適合於長時線上的服務;
-
瞬時守護程序:不需要關聯至執行級別;由
xinetd
來負責進行管理,xinetd
也稱為超級守護程序,但是超級守護程序xinetd
是需要關聯至執行級別的,超級守護程序是記錄自己守護的瞬時守護程序是按需進行開啟的,當需要訪問時,xinetd
通知相關的瞬時守護程序,完成服務後,瞬時守護程序就會關閉;