上
上圖就是系統引導流程的流程圖,我們一個部分一個部分來分別介紹:
一、固件:電腦按下電源以后,首先都是加載固件,叫做firmwall,PC上面應用最多的就是CMOS/BIOS(CMOS是固化在硬件上的那段程序,BIOS是基于這個程序的圖形化管理界面),它既不是硬件也不是軟件,它主要的功能是在硬件層面進行加電自檢(通常是檢查線連上沒,硬件可以識別沒)。在SUN的系統里不叫cmos而叫prom,也不叫bios而叫openbooter,所以名字雖然不同但是原理是差不多的,要學習這些固件,在購買服務器的時候,會有操作手冊,上面會有各種命令的解釋。固件設置里面只講一點就是硬件時鐘和軟件時鐘的設置(hwclock與date)。
二、自居程序:在進行完加電自檢,電腦會開始讀硬盤,首先讀的是MBR(master boot recorder)主引導記錄,主引導記錄在0柱面0磁頭1扇區的位置。主引導記錄分3個部分:自居程序bootloader,磁盤分區表Partition table,結束標志字magic number。
自居程序在所有的操作系統里面都有,在linux自居程序中廣泛應用的是grub(windows的自居程序在C盤可以查看到,NTloader)。那自居程序grub有什么用呢?它最重要的作用就是載入內核。其實內核在/boot文件夾是可以查看到的,內核其實是一個可執行文件而不是一堆文件。一堆文件的那個是內核的源代碼文件而不是可以使用的內核程序。內核的版本號和名字等配置信息可以在/etc/grab.conf配置文件查看,該配置文件具體的內容將在后續中詳細剖析。
三、載入內核:在載入內核以后,工作就交給了內核。內核在引導期間,其實最主要只做兩個事情:1.首先是驅動硬件,所謂驅動就是使系統認識硬件,并調用硬件。一個系統最龐大的部分就是驅動,通常根據需要對驅動進行裁剪,就成了裁決系統。2然后就是啟動一個進程,叫做init進程。它應該是系統存在的第一個進程。
四、啟動進程init:該進程的的PID(進程ID)恒為1,一般情況下PID是隨即分配的,但是init進程是固定的。PPID稱為父進程ID,可以看出init進程的父進程的PID為0,其實PID為0的進程是內核調度器(kernel scheduler)它負責對進程進行調度,即CPU時間片的分配。
在父子進程關系中,按道理父進程死了,子進程必須死。但是有時候父進程死了,但是子進程因為某種特殊情況并沒有死,這樣子進程就成了孤兒進程,linux檢查到孤兒進程,會把該孤兒進程的PPID變成1。另外一種情況,就是子進程死了,父進程不知道,導致子進程變成僵尸進程。
五、讀取配置文件inittab:在啟動進程init以后,就會讀取/etc/inittab配置文件。使用more /etc/inittab打開inittab文件,首先看到的是關于系統運行級別的信息。
Linux運行級別(runlevel)一共有7種:
0halt(關機)
1.Singgle user mode(但用戶,類似windows的安全模式)
2.Multiuser(沒有NFS網絡文件共享服務的多用戶模式,命令行)
3.Full multiuer mode(和3一樣,多加了NFS)
4.Unuerd(還未使用)
5.X11(默認使用,圖形界面)
6.Reboot(重啟)
如上所述默認的一般是5.通過命令runlevel可以查看當前運行級別。通過init num或者telinit num可以動態切換運行界別。(其實通過ls -l 'which telinit'可以得知telinit是init的一個軟鏈接)。
接著繼續學習inittab配置文件,使用grep -v '^#' /etc/inittab | more 得到沒有注釋的配置文件。通過man init可以得知,所有init配置文件里面的每行都是通過格式
id : runlevels : action : process
id:標識符,標記條目的唯一性,一般為兩位字母或者數字
runlevels:指定運行級別,如果為空,表示所有運行級別都可以。
action:指定腳本或者命令的運行狀態
process:指定要運行的腳本或者命令
下面對action的取值進行介紹:
1.initdefault:指定系統缺省啟動的運行級別
2.sysinit:系統啟動時,執行process指定的腳本或命令
3.wait:執行process指定的命令或者腳本,并在執行完成以后才運行其他的條目.
4.once:執行process命令或者腳本,但不等待其結束。
5.Ctrlaltdel:按下ctrl+alt+del鍵,執行process
6.Respawn:一旦該process終止,則重新運行該process指定的命令或。
7.Powerfail:電源出錯執行process
8.Powerokwait:電源恢復執行的process
上述第三個action值wait的例子中,其實通過ls -l /etc/rc.d/rc可以得知,rc其實是一個可執行文件(其實也是腳本)。在rc.d這個目錄下其實并不只有rc這一個文件,還有許多文件或者目錄。
可以看到有從rc0.d到rc6.d共7個目錄。他們是相應運行級別需要啟動的服務目錄文件。系統是通過action:initdefault的運行級別來匹配這里的服務目錄的。現在以rc3.d為例:
可以看到rc3.d目錄下有很多服務程序,從他們的名稱中,我可以可以得知它們的作用,名稱都是有3個部分組成:
第一個大寫字母+數字+名字
第一個大寫字母S(start)表示啟動服務,K(kill)表示殺死服務
數字表示啟動順序,數字越小越先啟動,數字相同,按照創建時間啟動,名字根據作用而定。
所以在這里我們可以根據自己應用的需要,把有用的進程開啟,無用的關閉,比如如果無用的不想開啟,可以把S改成s,就不會啟動了。
此處加一個專題,就是我們如何在系統啟動好以后來動態開啟和關閉服務呢?
首先我們要知道,系統所有的服務都是在/etc/rc.d/init.d目錄下。我們可以通過start、stop、restart、status來啟動、終止、重新啟動、查看狀態來操作服務。例如:用sshd服務為例:現在我們如果要把一個服務變成開機啟動有3種方法:
(1)第一個就是在/etc/rc.d/rcn.d的服務目錄中創建一個名為SXXX的軟鏈接,指向一個腳本就可以了。
(2)使用chkconfig命令設置進程是否啟動
(3)使用ntsysv進入圖形化設置進程是否啟動