1、請詳細描述CentOS系統的啟動流程(詳細到每個過程系統做了哪些事情)
啟動過程 (PC架構)
POST –> Boot Sequence(BIOS) –> Boot Loader (MBR)–>GRUB—> Kernel(ramdisk) –> rootfs –> switchroot –> /sbin/init–>(/etc/inittab, /etc/init/*.conf) –> 設定默認運行級別> 系統初始化腳本 –> 關閉或啟動對應級別下的服務 –> 啟動終端
系統啟動過程簡介:
1、加載BIOS的硬件信息與進行自我檢測,并依據設置取得第一個可啟動的設備;
2、讀取并執行第一個啟動設備內的MBR的 boot loader (既是grub,spfdisk等程序);
3、依據boot loader的設置加載Kernel, kernel會開始重新檢測硬件,加載驅動程序;
4、在硬件驅動成功后,Kernel會主動調動init進程,而init會取得run-level信息;
5、init執行/etc/rc.d/rc.sysinit文件來準備軟件執行的操作環境(如網絡、時區等);
6、init執行run-level的各個服務的啟動(script方式);
7、init執行/etc/rc.d/rc.local文件;
8、init執行終端機模擬程序mingetty來啟動login程序,最后等待用戶登錄。
第一步:加電自檢(POST)
系統加電之后,首先進行的硬件自檢,一但通電后主板會自動讀取ROM(只讀)中的程序,進行加載,計算機會首先加載BIOS信息,BIOS信息是如此的重要,以至于計算機必須在最開始就找到它。檢查各種硬件設備是否完整存在,如內存,硬盤,顯示,IO設備等。如果有硬件故障的話將按兩種情況理:對于嚴重故障(致命性故障)則停機,此時由于各種初始化操作還沒完成,不能給出任何提示或信號;對于非嚴重故障則給出提示或聲音報警信號,等待用戶處理),如果沒有故障,POST完成自己
的接力任務,將尾部工作交接給BIOS處理。
第二步:系統引導過程Boot Sequence(BIOS)
POST 過程結束后,系統的控制權從 BIOS 轉交到 boot loader。Boot loader 一般存儲在系統的硬盤上(傳統的 BIOS/MBR 系統),這個時候機器不能獲取外部的存儲或者網絡信息,一些重要的值(日期、時間、其他外部值)都是從CMOS里讀取.
POST(POST-power on self test)—>ROM->CMOS(互補金屬氧化物)->BIOS (Basic Input Output System,基礎輸入輸出系統)
BIOS(Basic Input/Output System)啟動初始化硬件的工作,包括屏幕和鍵盤,內存檢測,這個過程也被成為 POST(Power On Self Test),通過ROM加載自檢程序,然后按照 CMOS RAM 中設置的啟動設備查找順序,來尋找可啟動設備 。注:BIOS 程序嵌在主板的 ROM 芯片上的。
第三步:啟動加載器階段Master Boot Loader(MBR)
硬盤上第0磁道第一個扇區被稱為MBR,也就是Master Boot Record,即主引導記錄,決定啟動介質按照BIOS所設定的系統啟動流程,根據引導次序(Boot Sequence)自上而下的尋找對應存儲設備上操作系統的MBR。它的大小僅有512字節,但里面卻存放了預啟動信息、分區表信息。可分為兩部分:
第一部分為引導(PRE-BOOT)區,占了 446個字節;
第二部分為分區表(PARTITION TABLE),共有64個字節,每個主分區占用16字節,記錄硬盤的分區信息。(這就是為什么一塊硬盤只能有4個主分區)分區表有效性標記會占用2字節。
預引導區的作用之一是找到標記為活動(ACTIVE)的分區,并將活動分區的引導區讀入內存。剩余兩個字節為結束標記。尋找 grub,讀取配置文件/etc/grub.conf,決定默認啟動項根據MBR所指引的活動分區上尋找系統分區中的 bootloader.在bootloader當中配置了所要引導操作系統的內核所在的位置,因此BIOS被載入內存以后,當它實現將控制權限轉交給bootloader以后,bootloader接收整個系統的控制權限,而后根據用戶的選擇去讀取相應操作系統中的內核,并將內核裝載入內存的某個空間位置,解壓縮,這時kernel就可以在內存中活動,并根據kernel本身功能在內存當中探索硬件并加載硬件驅動程序并完成內核初始化,bootloader會將控制權限轉交給內核。
第四步:引導加載器階段(GRUB加載器)
對于GRUB來說,一個比較好的方面就是它包含了linux文件系統的知識。GRUB能夠從ext2或者ext3文件系統中加載linux內核。一旦Bootloader的第一階段已完成MBR(啟動加載器階段),并能找到實際的引導加載程序位置,第1階段啟動加載器加載引導程序到內存中開始第二階段。GRUB引導加載器階段它是通過將本來兩階段的boot loader轉換成三個階段的boot loader。
stage1個階段 :BIOS加載MBR里面的GRUB(屬于第1階段的文件),由于只有GRUB只占用446字節所以不能實現太多的功能,所以就有此階段里面的文件來加載第1.5階段的文件(/boot/grub下的文件)
stage1.5個階段:這個階段里面的就是加載識別文件系統的程序,來識別文件系統,不加載就無法識別文件系統,進而就找不到boot目錄,由于GRUB是無法識別LVM,所以你不能把/boot分區設置為LVM,所以必須要把/boot單獨分區
stage2個階段:這里面才是正在的開始尋找內核的過程,然后是啟動內核
(當stage1.5的boot loader被加載并運行時,stage2 的boot loader才能被加載。)
當stage2被加載時,GRUB能根據請求的情況顯示一個可選內核的清單(在 /etc/grub.conf 中進行定義,同時還有幾個軟符號鏈接 /etc/grub/menu.lst 和 /etc/grub.conf)。你可以選擇一個內核,修改其附加的內核參數。同時,你可以選擇使用命令行的shell來對啟動過程進行更深層次的手工控制。
GRUB的配置文件中的配置哪些信息
在第二階段boot loader加載到內存中后,就可以對文件系統進行查詢了,同時,默認的內核鏡像以及初始化內存盤鏡像也被加載到內存中。
根據grub設定的內核映像所在路徑,系統讀取內存映像,并進行解壓縮操作。此時,屏幕一般會輸出“Uncompressing Linux(解壓內核中)”的提示。當解壓縮內核完成后,屏幕輸出“OK, booting the kernel(正在啟動內核)”。
第五步:加載kernel
GRUB把內核加載到內存后展開并運行,此時GRUB的任務已經完成,接下來內核將會接管并完成:
探測硬件—>加載驅動—>掛載根文件系統—>切換至根文件系統(rootfs)—>運行/sbin/init完成系統初始化
內核一般都是壓縮的,所以它的首要任務是解壓縮,然后檢查和分析系統的硬件并初始化內核里的硬件驅動程序。內核剛加載到內存的時候,文件系統還不能使用,它使用的是 Boot Loader 加載進內存的 initramfs。系統將解壓后的內核放置在內存之中,并調用start_kernel()函數來啟動一系列的初始化函數并初始化各種設備,完成Linux核心環境的建立。至此,Linux內核已經建立起來了,基于Linux的程序應該可以正常運行了。
第六步:初始化initrd /etc/inittab
在核心加載完畢,進行完硬件偵測與驅動程序加載后,內核會啟動第一個進程/sbin/init, init進程將會讀取/etc/inittab,init進程是系統所有進程的起點,你可以把它比擬成系統所有進程的老祖宗,沒有這個進程,系統中任何進程都不會啟動。
/etc/inittab最主要的功能就是準備軟件運行的環境,包括系統的主機名稱、網絡配置、語系處理、文件系統格式及其他服務的啟動等,而所有的動作都根據在/etc/inittab中的配置.將會執行/etc/inittab來設定系統運行的默認級別,
init進程首先會讀取/etc/inittab文件,根據inittab文件中的內容依次執行
設定系統運行的默認級別(id:3:initdefault:)
執行系統初始化腳本文件(si::sysinit:/etc/rc.d/rc.sysinit)
執行在該運行級別下所啟動或關閉對應的服務(l3:3:wait:/etc/rc.d/rc 3)
啟動6個虛擬終端
0-6:7個級別的定義
0:關機, shutdown
1:單用戶模式(singleuser),root用戶,無須認證;維護模式;
2:多用戶模式(multiuser),會啟動網絡功能,但不會啟動NFS;維護模式;
3:多用戶模式(mutliuser),完全功能模式;文本界面;
4:預留級別:目前無特別使用目的,但習慣以同3級別功能使用;
5:多用戶模式(multi user),完全功能模式,圖形界面;
6:重啟,reboot
許多程序需要開機啟動。它們在Windows叫做”服務”(service),在Linux就叫做”守護進程”(daemon)。init進程的一大任務,就是去運行這些開機啟動的程序。但是,不同的場合需要啟動不同的程序,比如用作服務器時,需要啟動Apache,用作桌面就不需要。
Linux允許為不同的場合,分配不同的開機啟動程序,這就叫做”運行級別”(runlevel)。也就是說,啟動時根據”運行級別”,確定要運行哪些程序。
要訪問根文件系統必須要加載根文件系統所在的設備,而這時根文件系統又沒有掛載,要掛載根文件系統有需要根文件系統的驅動程序,這是一個典型的先有雞先有蛋的問題!為解決這個問題,GRUB在加載內核同時,也把initrd加載到內存中并運行.那么initrd又起到了什么作用哪?
initrd展開后的文件
linux中/下的文件
我們可以看到,其實initrd文件其實是一個虛擬的根文件系統,里面有bin、lib、lib64、sys、var、etc、sysroot、dev、proc、tmp等根目錄,它的功能就是講內核與真正的根建立聯系,內核通過它加載根文件系統的驅動程序,然后以讀寫方式掛載根文件系統,至此,內核加載完成。
第七步:運行/sbin/init,進行系統初始化
/sbin/init 最主要的功能就是準備軟件運行的環境,包括系統的主機名稱、網絡配置、語系處理、文件系統格式及其他服務的啟動等,而所有的動作都根據在/etc/inittab中的配置.init首先運行/etc/init/rcS.conf腳本,如下圖
第八步:啟動系統服務/etc/rc.d/rc.sysinit
可以看到,init進程通過執行/etc/rc.d/rcS.conf首先調用了/etc/rc.d/rc.sysinit,對系統做初始化設置,設置好整個系統環境。我們來看看這個腳本都是做了些什么哪? 事實上init執行/etc/rc.d/rc.sysinit的初始化將會做很多設置:
1、獲得網絡環境
2、掛載設備
3、開機啟動畫面Plymouth(取替了過往的 RHGB)
4、判斷是否啟用SELinux
5、顯示于開機過程中的歡迎畫面
6、初始化硬件
7、用戶自定義模塊的加載
8、配置內核的參數
9、設置主機名
10、同步存儲器
11、設備映射器及相關的初始化
12、初始化軟件磁盤陣列(RAID)
13、初始化 LVM 的文件系統功能
14、檢驗磁盤文件系統(fsck)
15、設置磁盤配額(quota)
16、重新以可讀寫模式掛載系統磁盤
17、更新quota(非必要)
18、啟動系統虛擬隨機數生成器
19、配置機器(非必要)
20、清除開機過程當中的臨時文件
21、創建ICE目錄
22、啟動交換分區(swap)
23、將開機信息寫入/var/log/dmesg文件中
第九步:啟動配置文件/etc/rc.d/rc.n
設定玩系統默認運行級別以后,接著調用/etc/rc.d/rc腳本,/etc/rc.d, 里面存放了rc.local, rc.sysinit, init.d, rcX.d (X包括0-6對應相對runlevel).這個腳本接收默認運行級別參數后,依腳本設置啟用或停止/etc/rc.d/rc[0-6].d/中相應的程序,如下圖,看一下我系統運行默認級別(級別)3下的內容吧
如圖示,/etc/rc.d/rc3].d/下的腳本文件在系統初始化階段,腳本名字以K開頭的,表示STOP動作(關閉),名字以S開頭,表示Start動作(啟動),文件名K/S 后面的的數字代表優先級,名稱中的數字表示執行次序(優先級),數字越小表示越先執行,優先級越高
第十步:用戶自定義開機啟動程序 (/etc/rc.d/rc.local)
系統根據runlevel啟動完rcX.d中的腳本之后,會調用rc.local腳本,如果你有一個腳本命令不論在3和5都想開機啟動,那么就添加于此,免去rc3.d和rc5.d分別增加啟動腳本工作量.最后,將執行/etc/rc.d/rc.local腳本,可以根據自己的需求將一些執行命令或者腳本寫到其中,當開機時就可以加載。
第十一步:打印登錄提示符
系統初始化完成后,init給出用戶登錄提示符(login)或者圖形化登錄界面,用戶輸入用戶和密碼登陸后,系統會為用戶分配一個用戶ID(uid)和組ID(gid),這兩個ID是用戶的身份標識,用于檢測用戶運行程序時的身份驗證。登錄成功后,整個系統啟動流程運行完畢!
2、為運行于虛擬機上的CentOS 6添加一塊新硬件,提供兩個主分區;
(1) 為硬盤新建兩個主分區;并為其安裝grub;
(2) 為硬盤的第一個主分區提供內核和ramdisk文件; 為第二個分區提供rootfs;
(3) 為rootfs提供bash、ls、cat程序及所依賴的庫文件;
(4) 為grub提供配置文件;
(5) 將新的硬盤設置為第一啟動項并能夠正常啟動目標主機;
新建兩個主分區
Disk identifier: 0x474f70eb
Device Boot Start End Blocks Id System
/dev/sdb1 1 66 530113+ 83 Linux
/dev/sdb2 67 1372 10490445 83 Linux
掛載
mount /dev/sdb1 /mnt
安裝grub到分區
# grub-install –root-directory=/mnt /dev/sdb
Probing devices to guess BIOS drives. This may take a long time.
Installation finished. No error reported.
This is the contents of the device map /mnt/boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install’.
(fd0)/dev/fd0
(hd0)/dev/sda
(hd1)/dev/sdb
復制虛擬文件系統,內核文件
cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/initramfs
cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/vmlinuz
創建grub.conf文件
~]# vim /mnt/boot/grub/grub.conf
default=0
timeout=5
title CentOS6(test)
root (hd0,0)
kernel /vmlinuz ro root=/dev/sdb2 selinux=0 init=/bin/bash
initrd /initramfs
掛載sdb2,并創建rootfs相關目錄
~]# umount /dev/sdb1
~]# mount /dev/sdb2 /mnt
~]# mkdir -p /mnt/{bin,sbin,lib,lib64,etc,home,root,media,mnt,dev,tmp}
~]# mkdir -p /mnt/{usr/{bin,sbin,lib,lib64},var/{lib,lib64,log,local,cache},proc,sys,selinux}
~]# which ls
alias ls=’ls –color=auto’
/bin/ls
~]# which bash
/bin/bash
~]# which cat
/bin/cat
~]# cp /bin/{bash,ls,cat} /mnt/bin
ldd命令:
– print shared library dependencies
ldd [OPTION]… FILE…
~]# ldd /bin/{bash,ls,cat}|grep -Eo “/lib.*[[:space:]]”| sort -u
/lib64/ld-linux-x86-64.so.2
/lib64/libacl.so.1
/lib64/libattr.so.1
/lib64/libcap.so.2
/lib64/libc.so.6
/lib64/libdl.so.2
/lib64/libpthread.so.0
/lib64/librt.so.1
/lib64/libselinux.so.1
/lib64/libtinfo.so.5
~]# cp `ldd /bin/{bash,ls,cat}|grep -Eo “/lib.*[[:space:]]”| sort -u` /mnt/lib64
~]# sync 同步sync – flush file system buffers
~]#init 6
重啟后進入bios設置 調整硬盤啟動順序后保存退出。
3、制作一個kickstart文件以及一個引導鏡像。描述其過程。
1、centos系統安裝完成后,anaconda會根據本次系統安裝的配置,生成一個與本次安裝設置相同的kickstart文件,文件位于/root/anaconda-ks.cfg,可以使用vim對這個文件進行修改來使用。
2、圖形化配置 kickstart 文件的工具: system-config-kickstart,能夠在圖形界面下選擇安裝選項并將結果保存為 kickstart 文件。yum install system-config-kickstart
可以直接手動編輯或使用工具在桌面模式下用system-config-kickstart(centos6.x)來創建ks.cfg #命令段 firewall --disabled//禁用防火墻 install//執行新安裝 cdrom//用光盤安裝 lang en_US.UTF-8//默認安裝語言 keyboard us//選擇鍵盤 rootpw --iscrypted $6$AF1u4TWzFxa/SzHI$yJvJdbhyw/2rG8dtr.PY6c15sZ.qNc6US/z7PMQ4lADdlIis/qIMO738b9czXK/rX1YDiL7Uv/C6Bi99ig8ov0//管理員加密密碼 authconfig --enableshadow --passalgo=sha512 selinux --enforcing//激活selinux logging --level=info//信息等級 timezone --utc Asia/Shanghai//系統時區 bootloader --location=mbr --driveorder=sdb --append="crashkernel=auto rhgb quiet" clearpart --all//刪除所有現在分區 part /boot --fstype=ext4 --size=200//分區掛載 part / --fstype=ext4 --size=40960 part swap --size=4096 #腳本段 %pre//安裝前腳本 echo "start install" %end %post//安裝后腳本 echo "install end" #程序包段 %packages @chinese-support//中文支持 @development//開發工具 @graphical-desktop-clients//圖形化工具 @remote-desktop-clients//遠程桌面客戶端 %end 簡單引導鏡像光盤制作: 1、復制安裝系統光盤引導文件和配置好的ks.cfg文件到一自制目錄(/centos6.6) mkdir myboot cd /myboot cp -r /media/cdrom/isolinux/./ cp /root/ks.cfg ks.cfg 2、在isolinux.cfg中指明kickstart文件位置,可以實現完全自動化安裝。也可以在“boot:”提示符下手動指定 append initrd=initrd.img ks=cdrom:/ks.cfg 3、創建ISO啟動鏡像 mkisofs -R -J -T -v --no-emul-boot --boot-load-size 4 --boot-info-table -V "CentOS 6.6 x86_64 boot" -c isolinux/boot.cat -b isolinux/isolinux.bin -o isolinux/boot.iso
4、寫一個腳本
(1) 能接受四個參數:start, stop, restart, status start: 輸出“starting 腳本名 finished.” …
(2) 其它任意參數,均報錯退出;
#!/bin/bash # case $1 in start) echo "start $0 finished." ;; stop) echo "stop $0 finished." ;; restart) echo "restart $0 finished." ;; status) echo "status $0 ok." ;; *) echo "error" exit 1 ;; esac
5、寫一個腳本,判斷給定的用戶是否登錄了當前系統;
(1) 如果登錄了,則顯示用戶登錄,腳本終止;
(2) 每3秒鐘,查看一次用戶是否登錄;
#!/bin/bash if [ $# -lt 1 ];then echo "at least one arg" exit 1 fi while true;do if w | grep $1 &>/dev/null;then echo "the user $1 is login" break else echo "waiting" sleep 3 fi done
6、寫一個腳本,顯示用戶選定要查看的信息;
cpu) display cpu info
mem) display memory info
disk) display disk info
quit) quit
非此四項選擇,則提示錯誤,并要求用戶重新選擇,只到其給出正確的選擇為止;
#!/bin/bash # cat << EOF cpu) display cpu information mem) display memory infomation disk) display disks information quit) quit EOF read -p "Enter your option: " option while [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ]; do echo "cpu, mem, disk, quit" read -p "Enter your option again: " option done if [ "$option" == "cpu" ]; then lscpu elif [ "$option" == "mem" ]; then free -m elif [ "$option" == "disk" ]; then fdisk -l /dev/[hs]d[a-z] else echo "quit" exit 0 fi
7、寫一個腳本
(1) 用函數實現返回一個用戶的UID和SHELL;用戶名通過參數傳遞而來;
(2) 提示用戶輸入一個用戶名或輸入“quit”退出;
當輸入的是用戶名,則調用函數顯示用戶信息;
當用戶輸入quit,則退出腳本;進一步地:顯示鍵入的用戶相關信息后,再次提醒輸出用戶名或quit: ”
#!/bin/bash function user_id( ) { if id $username &> /dev/null; then grep "^$username" /etc/passwd | awk -F: '{print "UID is:"$3, " Shell is:"$7}' else echo "none user" fi } while true;do read -p "please enter username or quit:" username if [ $username == "quit" ];then exit 0 else user_id $username fi done
原創文章,作者:victorli88,如若轉載,請注明出處:http://www.www58058.com/67100
總結的很好,圖文并茂,Linux的啟動流程可以畫一張圖,加油?。?!