Linux從開機到用戶登入期間發生的事情
一、BIOS 加電自檢
當你按電源開關開機時,電腦會首先去啟動BIOS(基本輸入輸出系統),BIOS一般是集成在主板上的.
BIOS 的工作
1.檢測連接硬件,比如顯卡,內存,磁盤等等,檢測的目的是以後把這些設備信息提供給操作系統
2.尋找啟動磁盤,每一種BIOS都會有開機啟動菜單,可以在菜單裡設置以哪個設備啟動系統
比如:光驅,硬盤,網絡等等,這個菜單可以設置多個選項,依照設置次序在設備上尋找啟動信息
3.找到了啟動硬盤,接著BIOS就會在磁盤上找啟動扇區,找到內核啟動系統.
二,加載MBR
眾所周知,硬盤上第0磁道第一個扇區被稱為MBR,也就是Master Boot Record,即主引導記錄,它的大小是512字節,別看地方不大,可裡面卻存放了預啟動信息、分區表信息。
系統找到BIOS所指定的硬盤的MBR後,就會將其復制到0x7c00地址所在的物理內存中。其實被復制到物理內存的內容就是Boot Loader,而具體到你的電腦,那就是lilo或者grub了。
三,Boot Loader
Boot Loader 就是在操作系統內核運行之前運行的一段小程序。通過這段小程序,我們可以初始化硬件設備、建立內存空間的映射圖,從而將系統的軟硬件環境帶到一個合適的狀態,以便為最終調用操作系統內核做好一切准備。
Boot Loader有若干種,其中Grub、Lilo和spfdisk是常見的Loader。
我們以Grub為例來講解吧,畢竟用lilo和spfdisk的人並不多。
系統讀取內存中的grub配置信息(一般為menu.lst或grub.lst),並依照此配置信息來啟動不同的操作系統。
那麼我們就看看grub的內容 它存在於 /boot/grub中
GRUB有幾個重要的文件,STAGE1、STAGE1.5、STAGE2
STAGE1:它只有512字節,通常放在MBR中,它的作用很簡單,就是在系統啟動時用於裝載STAGE2並將控制權交給它。
STAGE2:GRUB的核心,所有的功能都是由它實現。
STAGE1.5:介於STAGE1和STAGE2之間,是它們的橋梁,因為STAGE2較大,通常都是放在一個文件系統當中的,但是STAGE1並不能識別文件系統格式,
所以才需要STAGE1.5來引導位於某個文件系統當中的STAGE2。根據文件系統格式的不同,STAGE1.5也需要相應的文件,如:e2fsstage15,fatstage15,分別用於識別ext和fat的文件系統格式。它存放於1-63的柱面之間.
引導順序如下:STAGE1->;STAGE1.5->;STAGE2,
以下是我的linux中的grub.conf中的內容:
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/sda2
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-279.el6.i686)
root (hd0,0)
kernel /vmlinuz-2.6.32-279.el6.i686 ro root=UUID=b48a3c42-c2a0-42a2-a47f-1cb6b1d9f5c9 rdNOLUKS rdNOLVM LANG=enUS.UTF-8 rdNOMD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rdNO_DM rhgb quiet
initrd /initramfs-2.6.32-279.el6.i686.img
最重要的內容已經加黑,root (hd0,0) 用來設置kernel與initrd兩項內容的根地址。kernel表示內核,initrd是用在內核啟動時能過訪問硬盤文件的。title:一個操作系統引動的標頭,可以使多個
root :指明所需文件存在於哪個磁盤哪個分區上 (hd0,0)表示第一個硬盤,第一個分區,可參考/boot/grub/device.map
kernel:內核文件的名字,並且會有一些加載內核時的參數 or代表以只讀方式加載
initrd:包含一些附加的驅動程序
四,加載內核
內核啟動後會向bios查詢電腦的所有硬件信息,然後自己接手下來管理這些設備,以便提供給linux使用
內核會試著驅動這些設備,這些設備的驅動一部分包含在內核中,叫做靜態驅動,一部分以模塊的方式(動態)存放文件系統中,由
於此時還未掛載任何文件系統,因此還不能使用文件系統中的模塊,這裡只能驅動在內核中存在的硬件驅動程序的對應設備.想驅動內核中未包含的硬件驅動就需要加載文件系統.
內核會嘗試掛載根文件系統,根文件系統至少包含 /etc /bin /sbin /lib /dev 這5大目錄
他們5個缺一不可.都會導致系統無法啟動
根文件系統掛載是以只讀方式掛載的,因為這時linux還在啟動階段,並不穩定,避免破壞系統資料
五, 調用init
(依據inittab文件來設定運行等級)
內核被加載後,第一個運行的程序便是/sbin/init
執行init程序
/etc/rc.d/rc.sysinit # 由init執行的第一個腳本
/etc/rc.d/rc $RUNLEVEL # $RUNLEVEL為缺省的運行模式
/etc/rc.d/rc.local
/sbin/mingetty # 等待用戶登錄
sysinit:
/etc/rc.d/rc.sysinit主要做在各個運行模式中相同的初始化工作,包括:
調入keymap以及系統字體
啟動swapping
設置主機名
設置NIS域名
檢查(fsck)並mount文件系統
打開quota
裝載聲卡模塊
設置系統時鐘
等等。
inittab:
其實/etc/inittab文件最主要的作用就是設定Linux的運行等級,其設定形式是“:id:5:initdefault:”,這就表明Linux需要運行在等級5上。Linux的運行等級設定如下:
0:關機
1:單用戶模式
2:無網絡支持的多用戶模式
3:有網絡支持的多用戶模式
4:保留,未使用
5:有網絡支持有X-Window支持的多用戶模式
6:重新引導系統,即重啟
rc.local:
你如果打開了此文件,裡面有一句話,讀過之後,你就會對此命令的作用一目了然:
# 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.
rc.local就是在一切初始化工作後,Linux留給用戶進行個性化的地方。你可以把你想設置和啟動的東西放到這裡。
init進程是非內核進程中第一個被啟動運行的,因此它的進程編號PID的值總是1。init讀它的配置文件/etc/inittab,決定需要啟動的運行級別(Runlevel)。從根本上說,運行級別規定了整個系統的行為,每個級別(分別由0到6的整數表示)滿足特定的目的。如果定義了initdefault級別,這個值就直接被選中,否則需要由用戶輸入一個代表運行級別的數值。
輸入代表運行級別的數字之後,init根據/etc/inittab文件中的定義執行一個命令腳本程序。缺省的運行級別取決於安裝階段對登錄程序的選擇:是使用基於文本的,還是使用基於X-Window的登錄程序。
rc命令腳本程序我們已經知道,當運行級別發生改變時,將由/etc/inittab文件定義需要運行哪一個命令腳本程序。這些命令腳本程序負責啟動或者停止該運行級別特定的各種服務。由於需要管理的服務數量很多,因此需要使用rc命令腳本程序。其中,最主要的一個是/etc/rc.d/rc,它負責為每一個運行級別按照正確的順序調用相應的命令腳本程序。我們可以想象,這樣一個命令腳本程序很容易變得難以控制!為了防止這類事件的發生,需要使用精心設計的方案。
對每一個運行級別來說,在/etc/rc.d子目錄中都有一個對應的下級目錄。這些運行級別的下級子目錄的命名方法是rcX.d,其中的X就是代表運行級別的數字。比如說,運行級別3的全部命令腳本程序都保存在/etc/rc.d/rc3.d子目錄中。在各個運行級別的子目錄中,都建立有到/etc/rc.d/init.d子目錄中命令腳本程序的符號鏈接,但是,這些符號鏈接並不使用命令腳本程序在/etc/rc.d/init.d子目錄中原來的名字。如果命令腳本程序是用來啟動一個服務的,其符號鏈接的名字就以字母S打頭;如果命令腳本程序是用來關閉一個服務的,其符號鏈接的名字就以字母K打頭。
許多情況下,這些命令腳本程序的執行順序都很重要。如果沒有先配置網絡接口,就沒有辦法使用DNS服務解析主機名!為了安排它們的執行順序,在字母S或者K的後面緊跟著一個兩位數字,數值小的在數值大的前面執行。如:/etc/rc.d/rc3.d/S50inet就會在/etc/rc.d/rc3.d/S55named之前執行(S50inet配置網絡設置,55named啟動DNS服務器)。存放在/etc/rc.d/init.d子目錄中的、被符號鏈接上的命令腳本程序是真正的實干家,是它們完成了啟動或者停止各種服務的操作過程。當/etc/rc.d/rc運行通過每個特定的運行級別子目錄的時候,它會根據數字的順序依次調用各個命令腳本程序執行。它先運行以字母K打頭的命令腳本程序,然後再運行以字母S打頭的命令腳本程序。對以字母K打頭的命令腳本程序來說,會傳遞Stop參數;類似地對以字母S打頭的命令腳本程序來說,會傳遞Start參數。編寫自己的rc命令腳本在維護Linux系統運轉的日子裡,肯定會遇到需要系統管理員對開機或者關機命令腳本進行修改的情況。