標籤:linux uefi
我手上的版本有archlinux、fedora20、debian7、centos6我主要以以上這些版本為例來描述,BSD init以上版本預設都沒有了,所以無法驗證,描述很可能有漏洞。其中archlinux、fedora20使用systemd,debian7使用system V init,centOS6使用upstart。
在談init之前先說一下linux kernel的啟動過程,在PC上和arm嵌入式開發板上會有所不同。
系統啟動
PC
裝置在上電以後會在指定的位置來運行某段代碼,這個位置0xFFFF0就是固化在主板上的BIOS(現在是UEFI了),BOIS自檢後會從磁碟的某個位置載入程式,如果mbr分區會運行位於磁碟0道0柱1扇區上512位元組的mbr程式,mbr程式會通過446+1位元組的位置讀取64位元組的分區表,並在boot標誌的分區上載入bootload,一般會使grub、lilo。UEFI引導的情況下,UEFI會直接到GPT分區的fat檔案系統下找到efi的引導檔案並載入,這個檔案會載入grub或者其他引導(lilo是否支援有待驗證)。grub本身是一個縮減版的核心,grub本身會包含stage1,stage1.5,stage2 三步。它通過kernel指令載入kernel(grub2是linux指令) vmlinuz檔案並傳遞給核心啟動參數,通過initrd指令載入ram disk檔案,然後核心就被載入進記憶體中運行了。
efi啟動模式下的boot目錄如:
bios啟動模式下的boot目錄如:
vimlinuz-linux是kernel指令載入的kernel檔案,initramfs-linux.publication/image是initrd指令載入的ramfs檔案。
efi目錄如:
efi目錄是掛載的一個fat檔案系統的分區。包括了可以被UEFI載入的多個efi檔案。
grub載入的配置如:
開發板
開發板上電後會從norflash或者nandflash上的某個位置來讀取bootload,然後由bootload載入核心到記憶體,核心直接開始運行。在3.0以後的arm linux上kernel會從flash的某個位置讀取LDS來載入板載資源的配置資訊。
在核心初始化完成後,需要和根檔案系統建立關聯,pc版的kernel會藉助initrd來做橋樑載入根檔案系統,而armlinux則直接根據配置載入跟檔案系統。
早期init 系統簡介
在核心所有的操作完成以後就會從根檔案系統中載入地一個要執行的程式,他是所有程式的父進程,也是我們今天的主角init。恩,前面的廢話太多了,現在才進入正題…
init的曆史很久遠,早期Linux使用的init有兩個版本:sysV和BSD。現在他們仍舊沒有完全被廢棄,現在還有不少發行版本採用這兩個系統比如dibian還採用system V init,archlinux在20jenk12年前後才放棄BSD init切換到systemd。廢話不多說,分別描述一下。
BSD
- 使用/etc目錄下以rc.x作為檔案名稱的檔案來描述init的操作 - rc.sysinit - rc.single單使用者執行 - rc.multi2~5執行 - rc.local是雜項 - init系統會按照以上順序載入運行 - rc.conf包含了相關的配置
system V
- 指令檔目錄在`/etc/init.d/` - `/etc/rc{runlevel}.d`目錄標識相應運行層級的目錄 - 目錄下的檔案以S開頭的是啟動的服務,以K開頭的是不啟動的服務 - 啟動標識後緊跟的數字表示啟動優先順序,數值越小運行越早 - 通過service命令來起停服務 - 通過chkconf來管理服務 - 通過`/etc/inittab`檔案來配置相應的運行層級
以上兩種init系統載入的檔案本身都是一些指令檔,通過這些指令碼可以載入相應的模組或者啟動需要的程式。
BSD init 具體服務的內容:
#!/bin/sh. /etc/rc.subrname="dummy"start_cmd="${name}_start"stop_cmd=":"dummy_start(){ echo "Nothing started."}load_rc_config $namerun_rc_command "$1"
SystemV init具體服務的配置內容:
#! /bin/sh### BEGIN INIT INFO# Provides: sudo# Required-Start: $local_fs $remote_fs# Required-Stop:# X-Start-Before: rmnologin# Default-Start: 2 3 4 5# Default-Stop:# Short-Description: Provide limited super user privileges to specific users# Description: Provide limited super user privileges to specific users.### END INIT INFON=/etc/init.d/sudoset -ecase "$1" in start) # make sure privileges don‘t persist across reboots if [ -d /var/lib/sudo ] then find /var/lib/sudo -exec touch -t 198501010000 ‘{}‘ \; fi ;; stop|reload|restart|force-reload|status) ;; *) echo "Usage: $N {start|stop|restart|force-reload|status}" >&2 exit 1 ;;esacexit 0
從文法角度來看兩者沒有什麼區別。
早期的init系統存在若干問題,比如,無法並行任務,任務之間缺乏有效通訊機制,對進程的監控只能通過PID來進行…
現代init系統簡介
systemd和upstart在這種情況下產生了,他們都是事件驅動的,不得不說的是由於systemd開始時間晚於upstart所以很多特性也借鑒了upstart,同時systemd還借鑒了Mac OS X的Launcher系統。
- systemd
systemd 是 Linux 下的一款系統和服務管理員,相容 SysV 和 LSB 的啟動指令碼。systemd 的特性有:支援並行化任務;同時採用 socket 式與 D-Bus 匯流排式啟用服務;按需啟動守護進程(daemon);利用 Linux 的 cgroups 監視進程;支援快照和系統復原;維護掛載點和自動掛載點;各服務間基於依賴關係進行精密控制。
--維基百科
systemctl來管理systemd,同時也相容service命令
所有的systemd配置在/usr/lib/systemd目錄下,當啟動用後會被連結或者拷貝到/etc/systemd目錄下
systemd和upstart的使用
先分別上一段代碼,sytemd:
[Unit]Description=OpenSSH DaemonWants=sshdgenkeys.serviceAfter=sshdgenkeys.serviceAfter=network.target[Service]ExecStart=/usr/bin/sshd -DExecReload=/bin/kill -HUP $MAINPIDKillMode=processRestart=always[Install]WantedBy=multi-user.target
upstart:
start on fedora.serial-console-available DEV=* and stopped rc RUNLEVEL=[2345]stop on runlevel [S016]instance $DEVrespawnpre-start exec /sbin/securetty $DEVexec /sbin/agetty /dev/$DEV $SPEED vt100-navpost-stop exec /sbin/initctl emit --no-wait fedora.serial-console-available DEV=$DEV SPEED=$SPEEDusage ‘DEV=ttySX SPEED=Y - where X is console id and Y is baud rate‘
看出什麼區別來了嗎?
upstart和systemd是全新的方式,upstart是命令的方式,systemd則是conf形式。
systemd
Unit用來描述服務的相關資訊和依賴關係
Service對服務本身進行描述
Install說明他的運行環境
- 運行層級也通過systemd來進行管理
upstart
- 通過
start on runlevel [012345]和stop on runlevel [!RUNLEVEL]來制定具體運行層級
- 通過
exec來運行相應的程式
- 通過
script ... end script指令可以直接嵌入指令碼
一些更加細節的配置請查閱相關手冊吧。
我們可以通過--init=xxx核心參數來指定所使用的init系統。當然指定的這個init可以是任意的程式,你完全可以直接指定成為你想要的任何程式。
目前大部分Linux發行版本都已經採用systemd作為預設的init系統,ubuntu現在使用的是upstart系統,而Debain也在投票的結果是選擇了systemd,ubuntu也宣布會接受debian的上遊選擇決定。
貌似現在systemd有統一Linux世界init系統的趨勢。
?
Linux init系統