啟動流程、模塊管理、BootLoader(Grub2)

系統啟動是一項非常復雜的程序,因為內核得先檢測硬件并加載適當的驅動程序后,接下來則必須要調用程序來準備好系統運行的環境,讓用戶能夠順利操作主機系統。

如果你能夠理解開機的原理,那么將有助于你在系統出問題時能夠快速修復系統。而且還能夠順利的配置多重操作系統的多重引導問題。

為了多重引導,就不能不學grub2這個Linux下優秀的引導裝載程序(boot loader)。而且在系統運作期間,你也要學會管理內核模塊。


1、Linux的啟動流程分析

如果想要多重開機,如果root密碼忘記,如果/etc/fstab設置錯誤等,如何解決?

1.1、啟動流程一覽

目前各大Linux distributions使用的主流 boot loader為grub2,早期是grub1或LILO。

以個人Linux主機為例,當按下電源后,電腦硬件會主動讀取BIOS或UEFI BIOS來載入硬件信息及進行硬件系統的自我測試。之后系統會主動去讀取第一個可開機的設備(由BIOS設置),此時就可以讀入引導裝載程序。

引導裝載程序可以指定使用哪個內核文件來啟動,并實際加載內核到內存當中解壓縮與執行,此時內核就可以在內存中運行,并檢測所有硬件信息與加載適當的驅動程序來使這部主機運行。等到內核檢測硬件與加載驅動程序完畢后,操作系統已在你的PC上面跑起來了。

主機系統運行后,Linux才會調用外部程序開始準備軟件執行的環境,并實際加載系統運行所需的軟件程序。最后系統就會開始等待你的登錄與操作。

系統啟動過程如下:

1,加載BIOS的硬件信息與進行自檢,并依據設置取得第一個可啟動的設備(硬盤,光盤,U盤);

2,讀取并執行第一個啟動設備內MBR(主引導分區)的 boot loader(如grub2);

3,依據 boot loader的設置加載Kernel,Kernel會開始檢測硬件與加載驅動程序;

4,在硬件驅動成功后,Kernel會主動調用systemd進程(原來的init進程),并以default.targert流程開機;

systemd執行sysinit.target初始化系統及basic.target準備作業系統;

systemd啟動multi-user.target下的本機與服務器服務;

systemd執行multi-user.target下的/etc/rc.d/rc.local文件;

systemd執行multi-user.target下的getty.target及登錄服務;

systemd執行graphical需要的服務

1.2、BIOS,boot loader與Kernel加載

BIOS:不論傳統的BIOS還是UEFI BIOS都會被稱為BIOS;

MBR:雖然分割表有傳統MBR以及新式的GPT,不過GPT也保留一塊相容的MBR的區塊,因此,底下的說明在安裝boot loader的部分,都簡稱MBR。總之,MBR就代表該磁盤最前面可安裝boot loader的那個區塊。

BIOS,開機自檢與MBR/GPT

由于不同的操作系統的文件格式各不相同,因此我們必須要以一個開機管理程序來處理核心文件載入(load)的問題,因此這個開機管理程序就被稱為 boot loader。boot loader安裝在開機裝置的第一個扇區(sector)內,也就是我們一直談論的MBR。

只要BIOS能夠檢測到你的磁盤(無論SATA還是IDE接口),那它就有辦法通過INT 13 這條信道來讀取該磁盤的第一個扇區內的MBR,這樣boot loader也就能夠被執行。

Tips:

我們知道每科硬盤的最前面區塊含有MBR或GPT分割表的提供loader的區塊,那么如果我的主機上面有兩個硬盤,系統會去哪個硬盤的最前面區塊讀取boot loader呢?這個就要看BIOS的設定了。

基本上,我們常常講的 "系統的MBR" 其實指的是第一個開機裝置的MBR才對。需要注意。

Boot Loader的功能

loader最主要的功能是要認識操作系統的文件格式并載入內核到內存中去執行,由于不同的操作系統的文件格式不一致,因此每種作業系統都有自己的boot loader。

多重操作系統?必須要使用自己的loader才能夠載入屬于自己的操作系統內核;但系統的MBR只有一個,那么怎么樣同時在一臺主機上面安裝Linux和Windows呢?

其實每個文件系統(filesystem)分區(partition)都會保留一塊開機磁區(boot sector)提供作業系統安裝boot loader,而通常操作系統默認會安裝一份loader到他根目錄所在的文件系統的boot sector上。

boot sector與操作系統的關系

如圖所示,每個操作系統都會安裝一套boot loader到它自己的文件系統中。Linux安裝時,可以選擇將boot loader安裝到MBR去,也可以選擇不安裝。Windows默認將MBR和boot sector都安裝boot loader。所以,你會發現安裝多重操作系統時,你的MBR常常會被不同的操作系統的boot loader所覆蓋。

雖然各個操作系統都可以安裝一份boot loader到他們的boot sector中,這樣操作系統可以通過自己的boot loader來載入核心。可問題是MBR只有一個,要如何執行boot sector內的loader呢?

boot loader的主要功能是:

提供選單,使用者可以選擇不同的開機項目,這也是多重開機的功能;

載入核心文檔,直接指向可開機的程序區段來開始作業系統;

轉交其他loader,將開機管理功能轉交給其他loader負責;

由于具有控制權轉交的功能,因此可以載入其他boot sector內的loader。不過Windows的loader默認不具有控制權轉交功能,因此不能使用Windows的loader來載入Linux的loader,所以為什么需要先裝Windows再裝Linux。


引導裝載程序菜單功能與控制權轉交示意圖

選單一:MBR(grub2) --> kernel file --> booting;

選單二:MBR(grub2) --> boot sector(Windows loader) --> Windows kernel --> booting;

選單三:MBR(grub2) --> boot sector(grub2) --> kernel file --> booting;

加載內核檢測硬件與initramfs的功能

當由boot loader的管理而開始讀取內核文件后,Linux就會將內核解壓縮到內存中,并利用內核的功能開始測試與驅動各周邊設備。此時,Linux內核會以自己的功能重新偵測一次硬件,而不一定會使用BIOS檢測的硬件。

一般來說,內核文件放置在/boot里,并取名為/boot/vmlinuz。

Linux內核模塊放置在/lib/modules/ 目錄內(/lib不可與/放置于不同的分區),因為在開機過程中內核必須要先掛載根目錄,這樣才能夠讀取內核模塊來載入驅動程序。


一般來說,非必要的功能且可以編譯成模塊的內核功能,目前的Linux distributions都會將它編譯成模塊。如USB,SATA等設備的驅動程序通常都是以模塊的方式存在的。

但是,內核根本不認識SATA磁盤,所以需要載入SATA磁盤的驅動,否則根本就無法掛載根目錄。但是SATA的驅動在/lib/modules內,你根本無法掛載 /目錄 又怎么讀取到/lib/modules內的驅動呢?


這時候就需要通過虛擬文件系統來解決了。虛擬文件系統(Initial RAM Disk(Filesystem)),一般的文件名為/boot/initrd或/boot/initramfs。它能夠通過boot loader來載入到內存中,然后這個文檔會被解壓縮并且在內存中模擬成一個根目錄,且此模擬在內存中的文件系統能夠提供一支可執行的程序,通過該程序來載入開機過程中所需要的核心模塊,通常這些模塊就是USB,RAID,LVM,SCSI等文件系統與磁盤的驅動程序。

BIOS與boot loader及內核載入流程

在核心完整載入后,你的主機應該就開始正常的運作了,接下來就要開始執行系統的第一支進程:systemd!

1.3、第一個進程systemd及使用default.target進入開機程序分析

在內核載入完畢,硬件檢測驅動載入后,此時內核就會主動呼叫第一個進程--systemd(PID為1)。systemd最主要的功能就是準備軟件執行的環境(包括系統主機名、網絡、語系、文件系統格式及其他服務的啟動)。所有的動作都會通過systemd的預設啟動服務集合,亦即/etc/systemd/system/default.target來規劃。另外,systemd已經舍棄沿用多年的system V的runlevel了哦!

常見的操作環境target與相同的runlevel等級

過去的system V使用的是runlevel(執行等級)的概念來啟動系統,systemd也與runlevel相結合。

對應關系
對應關系

systemd的處理流程

當我們取得了/etc/systemd/system/default.target這個預設操作界面的設置之后,系統會到/usr/lib/systemd/system/這個目錄下去取得multi-user.target或graphical.target之一。

假設我們使用的是graphical.target,接下來systemd回去找兩個地方的設置:

/etc/systemd/system/graphical.target.wants/ :使用者設置載入的unit;

/usr/lib/systemd/system/graphical.target.wants/:系統預設載入的unit;

/usr/lig/systemd/system/graphical.target

上圖表示graphical.target必須要完成multi-user.target之后才能進行,進行完graphical.target之后,還得要display-manager.service才行。那通過同樣的方式,我們來看看multi-user.target的啟動需要載入那些項目。

/usr/lib/systemd/system/multi-user.target

如上,multi-user.target需要在basic運行完畢后才能載入上訴許多unit哩。

Tips:

要知道系統的服務啟用流程,最簡單可使用“ systemctl list-dependencies graphcial.target”,如果想要知道背后的設定意義,那就分別找出/etc與/usr/lib下面的wants文件,當然還有Requires這個設定值。

基本上Centos7.x開機流程是這樣:

1,local-fs.target+swap.target:這兩個主要掛載本機/etc/fstab里面與相關內存交換空間;

2,sysinit.target:主要檢測硬件,載入所需的內核模塊等;

3,basic.target:載入主要的硬件驅動與防火墻相關任務;

4,multi-user.target:載入其他一般系統或網絡服務載入;

5,graphical.target:載入圖形界面相關服務。


1.4、systemd執行sysinit.target初始化系統,basic.target準備系統

基本上,可以把sysinit.target這些服務分成幾大類:

特殊文件系統設備的掛載;

特殊文件系統的啟用;

開機過程的信息傳輸與動畫執行;

日志文件的使用;

載入額外內核模塊;

設定終端機(console)字形;

啟動動態設備管理員;


不論使用哪種操作環境來使用系統,這個sysinit.target都是必要的工作。


basic.target這個項目,它主要啟動的服務有:

載入alsa音效驅動;

載入firewalld防火墻;

載入CPU的微指令功能;

啟動與設置SELinux的安全文本;

將目前的開機所產生的信息寫入/var/log/dmesg中;

由/etc/sysconfig/modules/*.modules及/etc/rc.modules載入管理員指定的模塊;

載入systemd支援的timer功能;

在這個階段完成后,系統已經可以順利運作。就差一堆你需要的登錄服務、網絡服務、認證服務等。


1.5、systemd啟動multi-user.target下的服務

一般來說,服務的啟動腳本設置都放置于一下目錄:

/usr/lib/systemd/system??(系統默認服務啟動腳本)??

/etc/systemd/system??(管理員自己開發與設置的腳本)??


使用者針對主機的服務的各項unit若要enable的話,就是將它放到/etc/systemd/system/multi-user.target.wants/目錄下面去做個連接,這樣就可以在開機時會自動啟動它。

mongod開機自啟詳細


相容的system V的rc-local.service

老版的Linux里,系統完成開機后還想要讓系統額外執行某些程序,可以將該程序或腳本放入到/etc/rc.d/rc.local下去。

新版Linux的systemctl機制中,建議直接寫一個systemd的啟動腳本文件到/etc/systemd/system下,然后用systemctl enable啟動它。

但是放置到/etc/rc.d/rc.local下的腳本systemd也支持,那就是rc-local.service這個服務。這個服務不需要啟動,它會判斷/etc/rc.d/rc.local是否具有可執行的權限來判斷要不要啟動這個服務。

/etc/rc.d/rc.local


提供tty界面與登入的服務

能不能提供登錄服務也是multi-user.target底下的內容,包括systemd-logind.service,systemd-user-sessions.service等服務。

如果getty服務先啟動完畢,你會發現有可用的終端嘗試讓你登錄系統。問題是,如果systemd-logind.service或systemd-user-sessions.service服務未啟動完畢的話,那么你還是無法登錄系統的。這就能解釋為什么我們在剛開機時可能輸入了正確的賬號密碼卻無法登錄系統。


1.6、systemd啟動graphical.target底下的服務

graphical.target,systemd就會開始載入用戶管理服務與圖形界面管理員(window display manager,DM)等,啟動圖形界面來讓用戶以圖形的界面登錄系統。

graphical.target啟動依賴


multi-user.target啟動依賴

graphical.target相較于multi-user.target多的那幾項大多數是圖形界面賬號管理的功能,gdm.service是讓使用者利用圖形界面登錄的服務。


1.7、開機過程中會用到的主要配置文件

基本上,systemd有自己的配置文件處理方式,不過為了相容于system V,很多的服務腳本文件還是會讀取位于/etc/sysconfig/ 下的配置文件。


關于模塊:/etc/modprobe.d/*.conf以及/etc/modules-load.d/*.conf

有兩個地方可以處理模塊載入問題:

/etc/modules-load.d/*.conf ? ?#單純要內核載入模塊的位置;

/etc/modprobe.d/*.conf ? ?#可以加上模塊參數的位置;

如果你有某些特定的參數要處理時,就得要在這兩者進行。

/etc/sysconfig/*

/etc/sysconfig/

authconfig:

規范使用者的身份認證機制,包括是否使用本機的/etc/passwd,/etc/shadow等,以及/etc/shadow密碼記錄使用何種加密算法等。使用“authconfig-tui指令來修改較佳!”

cpupower:

如果有啟動cpupower.service這個服務,他就會讀取這個配置文件。主要是Linux核心如何操作CPU的原則。

firewalld,iptables-config,ip6tables-config,ebtables-config:

與防火墻服務啟動的參數有關。

network-scripts/:

主要用于網卡配置。



2、內核與內核模塊

在開機過程中,是否能夠成功的驅動我們主機的硬件設備,是內核(Kernel)的工作!而內核一般都是壓縮檔,因此在使用內核之前,得先將它解壓縮后,才能加載到內存中。

目前的內核都是具有可讀取模塊化驅動程序的功能,即所謂的“modules”(模塊化)功能,所謂的模塊化可以將它想象出一個插件,該插件可能由硬件開發廠商提供或我們的內核本來就支持。

內核與內核模塊放在哪?

內核:/boot/vmlinuz;

內核解壓縮所需RAMDisk:/boot/initramfs(/boot/initramsfs-$Version);

核心模塊:/lib/modules/$version/kernel或/lib/modules/$(uname -r)/kernel;

核心原始碼:/usr/src/linux或/usr/src/kernels/(要安裝了才會有,默認不安裝)


如果內核被順利加載到系統中,會有以下幾個信息被記錄下來

內核版本:/proc/version;

系統內核功能:/proc/sys/kernel/


問題來了,如果我有一個新硬件,偏偏我的操作系統不支持,怎么辦?

重新編譯內核,并加入最新的硬件驅動程序源碼;

將該硬件的驅動程序編譯成為模塊,在啟動時加載該模塊。


2.1、內核模塊與依賴性

核心模塊放在/lib/modules/$(uname -r)/kernel中,里面分成這幾個目錄

arch:與硬件平臺有關的項目,如CPU的等級;

crypto:核心所支持的加密技術,如md5或des等;

drivers:一些硬件驅動程序,如顯卡網卡等;

fs:內核所支持的filesystem,如vfat,nfs等;

lib:一些函數庫;

net:與網絡有關的各項協定資料,防火墻模塊等;

sound:與音效有關模塊組


Linux提供了一些模塊組依賴性解決方案,那就是檢查/lib/modules/$(uanme -r)/modules.dep這個文件,它記錄了在核心支援的模塊的各項依賴性。利用depmod命令即可。

depmod命令

Kernel內核模塊擴展名一定是以.ko結尾的。


2.2、內核模塊的查看

lsmod ? ?#查看目前內核加載了多少模塊

lsmod

顯示內容有:

模塊名稱(Module);

模塊的大小(Size);

模塊是否被其他模塊所使用的(Used by); ? ?#如上,nf_nat_masquerade_ipv4先被載入后,ipt_MASQUERADE才能進一步載入系統。

使用modinfo命令查詢模塊信息

modinfo命令


2.3、內核模塊的加載如刪除

如何手動加載模塊?

使用 modprobe 這個命令來載入模塊,因為modprobe會主動去搜尋modules.dep的內容,先克服模塊的依賴性才決定需要載入的模塊有哪些。

insmod命令則完全有用戶自行加載一個完整文件名的模塊,并不會主動分析模塊依賴性。使用rmmod刪除這個模塊。

insmod
rmmod


使用insmod或rmmod命令的問題是,你必須自行找到模塊的完整文件名才行,萬一模塊有依賴性的問題時,你將無法直接加載或刪除該模塊。所以,建議使用modprobe命令。

modprobe



3、Boot Loader:Grub2

BootLoader是加載內核的重要工具,沒有BootLoader,Kernel根本無法被載入系統。

Centos7已將沿用多年的BootLoader從grub換成了grub2。


3.1、BootLoader的兩個stage

我們知道,MBR是整個磁盤的第一個sector內的一個區塊,充其量整個大小也才446Byte。即使是GPT也沒有很大的磁區來儲存loader的資料。所以Linux將boot loader的程序代碼執行與設置值加載分成兩個階段(stage)來執行。

Stage1:執行boot loader主程序

第一階段執行boot loader的主程序,這個主程序必須要被安裝在開機區,亦即是MBR或boot sector。但因為MBR實在太小了,所以MBR或boot sector通常僅安裝boot loader的最小主程序,并沒有安裝loader的相關配置文件。

Stage2:主程序加載配置文件

第二階段為通過boot loader加載所有配置文件與相關的環境參數配置文件包括文件系統定義與主要配置文件grub.cfg),一般來說,配置文件都在/boot下。


與grub2有關的文件都放在/boot/grub2:

/boot/grub2


3.2、grub2的配置文件/boot/grub2/grub.cfg

grub2功能挺多的:

認識與支援較多的文件系統,并且可以使用grub2的主程序直接在文件系統中查找內核文件名;

啟動的時候,可以自行編輯與修改啟動設置選項,類似bash的命令模式;

可以動態查找配置文件,而不需要在修改配置文件后重新安裝grub。即只需修改/boot/grub2/grub.cfg里面的設置就行,下次開機就生效。

#其實這三點就是Stage1,2分別安裝在MBR與文件系統中的原因。


硬盤與分割槽在grub2中的代號

grub2是如何識別磁盤的呢?

跟/dev/sda1不相同。其實只要注意這幾個東西就行:

硬盤代號以小括號()包起來;

硬盤以hd表示,后面會接一組數字;

以“查找順序”為硬盤的編號,而不是依照電纜的排序;

第一個查找的硬盤為0號,第二個為1號,以此類推;

每塊硬盤的第一個分區代號為1,依序類推;

所以說,第一個查找到的磁盤為“hd0”,而該磁盤的第一個分區為(hd0,1)。

硬盤代號


/boot/grub2/grub.cfg配置文件

不要隨便改動grub.cfg配置文件。

在grub.cfg開始部分,大多是環境設置與預設值等,比較重要的默認由哪個選項開機(set default)以及默認的秒數(set timeout),再則就是每個選單的設定,在menuentry這個設置值后的項目。包括了--class,--unrestricted等制定項目,之后通過{ }將選單會用到的資料框起來。grub2會載入模塊。

比較重要的三個項目:

set root='hd0,gpt2' ? #這root是指grub2配置文件所在的那個設備;

linux16/vmlinuz-xxxxx/centos-root = xxx ? ?#這是Linux內核文件以及內核執行時所下達的參數;

initrd16/initramfs-3.10... ? ?#這是initramfs所在的文件名


3.3、grub2配置文件維護/etc/default/grub與/etc/grub.d

通過/etc/default/grub這個主要環境配置文件與/etc/grub.d/目錄內相關配置文件來處理grub.cfg比較妥當。


/etc/default/grub主要環境配置文件

/etc/default/grub

幾個重要的設定選項:

倒數時間參數:GRUB_TIMEOUT;

是否隱藏菜單選項:GRUB_TIMEOUT_STYLE;

信息輸出的終端機模式:GRUB_TERMINAL_OUTPUT; ? ?#主要有console,serial,gfxterm,vga_text等;

默認開機選項:GRUB_DEFAULT ? ?#能使用的值包括有saved,數字,title名,ID名等;

內核的額外參數功能:GRUB_CMDLINE_LINUX ? ?#如果你的核心在啟動的時候還需要加入額外的參數,那就在這里加入吧。

#GRUB_CMDLINE_LINUX="..... crashkernel=auto rhgb quiet elevator=deadline"

這些主要環境設置完畢后,必須要使用?grub2-mkconfig?來重建grub.cfg才行。但不必重啟系統,是不是很方便了!

grub2-mkconfig? -o? /boot/grub2/grub.cfg


自己額外設定的項目,就是寫入/etc/default/grub就行了。

假設你需要(1)開機選單等待40 秒鐘、 (2)預設用第一個選單開機、 (3)選單請顯示出來不要隱藏、 (4)核心外帶『elevator=deadline』的參數值, 那應該要如何處理grub.cfg 呢?

自定義


選單建置的腳本/etc/grub.d/*

其實grub2-mkconfig會去分析/etc/grub.d/*里面的文件,然后執行該文件的來構建grub.cfg的啦。一般來說,/etc/grub.d/*下會有這些文件存在:

/etc/grub.d/

00_header:主要在建立初始的顯示項目,包括需要載入的模塊分析、屏幕終端格式,倒數秒數、菜單隱藏等,大部分在/etc/default/grub里所設置的便是,都會在這個腳本中被利用來重建grub.cfg;

10_linux:根據分析/boot下的文件,嘗試找到正確的linux內核與讀取這個內核需要的文件系統模塊與參數等,都在這個腳本運行后找到并設置到grub.cfg中;

30_os-prober:這個腳本默認會到系統上找其他的partition里面可能包含的操作系統,然后將該操作系統做成選項來處理就是了;

40_custom:如果你還有其他想要自己手動加上去的選單項目,或者是其他需求,那么建議在這里補充。


所以,一般來說,我們會修改的僅有40_custom這個文件。我們知道,menuentry就是一個選項,那后續的項目有哪些呢?常見有這幾項:

直接指定內核開機;

通過chainloader的方式移交loader的控制權;


3.4、initramfs的重要性 與 建立initramfs文件

initramfs內所包含的模塊大多是與開機過程有關,而主要以文件系統及硬盤模塊(USB、SCSI等)為主。

一般來說,需要initramfs的時刻為:

根目錄所在磁盤為SATA、USB或SCSI等連接;

根目錄所在磁盤文件系統為LVM、RAID等特殊格式;

根目錄所在文件系統為非傳統Linux認識的文件系統時;

其他必須要在內核加載時提供的模塊;

#早期的IDE硬盤沒有initramfs也可開機(Linux內核能直接識別),但自從SATA硬盤后,沒有initramfs就無法開機,因為內核無法識別需要先載入SCSI模塊來驅動。


一般來說,各distribution提供的內核都會附上initramfs文件,但如果有需要想重制initramfs文件的話,可以使用 dracut(Centos7)/mkinitrd(老版) 來處理。

dracut

dracut


dracut


3.5、測試與安裝grub2

如果Linux主機使用的本來就是grub2就不用安裝了。

首先,必須要使用grub-install將一些文件復制到/boot/grub2里面去。

grub2-install

基本上,grub2-install大概僅能安裝grub2主程序到boot sector中去,如果后面的設備是整個系統(/dev/sda...),那loader程序才會寫入到MBR里去。

如果是從其他boot loader轉成grub2時,得先使用grub2-install安裝grub2配置文件;

如果安裝到分區時,可能需要加上額外的許多參數才能順利安裝;

開始編輯/etc/default/grub及/etc/grub.d/*這幾個重要文件;

使用grub2-mkconfig -o /boot/grub2/grub.cfg來建立開機的配置文件


依據3.3 小節的第一個練習,我們的測試機目前為40 秒倒數,且有一個強制進入圖形界面的『 My graphical CentOS7 』選單!現在我們想要多加兩個選單,一個是回到MBR 的chainloader,一個是使用/dev/vda4 的chainloader,該如何處理?

修改40_custom 成為這樣:


3.6、開機前的額外功能修改

開機的默認選項,還可以進行grub2的修改功能。

grub2開機畫面


由于默認選項沒有隱藏,因此直接看到了五個選項。同時會讀秒。選項部分的畫面其實就是menuentry后面的文字。現在知道如何修改menuentry后面的文字了吧。點擊“Goto MBR”與“Goto /dev/vda4”又會重新回到選項,因為這兩個都是我們自定義的重新讀取選項文件。

有一個?'e'(edit),這是grub2支援修改指令。這是很有用的功能,如你剛剛將grub.cfg的內容寫錯了,導致無法開機。我們就可以查閱menuentry選項并加以修改哦。

按'e'進入以下畫面:

grub2額外的命令編輯模式



3.7、關于開機畫面與終端機畫面的圖形顯示方式

如果想讓開機畫面使用圖形顯示方式,例如使用中文來顯示你的畫面。

效果圖


3.8、為個別選項加上密碼

使用者可以在開機過程中與grub2內選擇進入某個選項,以及進入grub命令模式去修改選項的參數資料等。如何讓某些密碼控制grub2的所有功能,某些密碼則只能進入個別選項開機呢?這就牽涉到grub2的賬號機制了。


grub2的賬號、密碼與選項的設置

grub2有點在模擬Linux的賬號管理方案。在grub2中,有針對兩種身份進行密碼設置:

superusers:設置系統管理員與相關參數還有密碼等,使用這個密碼的用戶,可在grub2內具有所有修改的權限。但一旦設置了這個superusers參數,則所有的指令修改竟會被變成受限制的!

users:設置一般賬號的相關參數與密碼,可以設置多個用戶。使用這個密碼的用戶可以選擇要進入某些選項 。不過,選項也得要搭配相對的賬號才行。

假設你的系統有三個各別的操作系統,分別安裝在(hd0,1), (hd0,2), (hd0,3) 當中。假設(hd0,1) 是所有人都可以選擇進入的系統, (hd0,2) 是只有系統管理員可以進入的系統,(hd0,3)則是另一個一般用戶與系統管理員可以進入的系統。

另外,假設系統管理員的帳號/密碼設定為?zhang/abcd1234, 而一般帳號為 user/dcba4321 ,那該如何設定?

如果依據上述的說明,其實沒有用到Linux 的linux16 與initrd16 的項目,只需要chainloader 的項目而已!

因此,整個grub.cfg 會有點像底下這樣喔:

如上所示,你得要使用superusers來指定那個賬號是管理員。另外,這個賬號與Linux實體賬號無關。這僅是用啦判斷密碼所代表的意思。而密碼的給予有兩種語法:

password_pbkdf2,帳號使用grub2-mkpasswd-pbkdf2所產生的密碼;

password帳號沒加密的明文;


有了帳號密碼之后,再來就是個別選項上?是否要取消限制(--unrestricted)?或者是給予 哪個用戶(--users)的設定項目。所有的系統管理員所屬的密碼應該是能夠修改所有的選項。

grub2密碼設置的文件位置與加密的密碼

還記得/etc/grub.d/*里面的文件嗎,那些數字順序就是grub.cfg的來源順序。因此最早被讀的應該是00_header(不建議修改),自己可以建一個名為01_users的文件,然后將賬號密碼參數寫進去。

向01_users中添加賬戶和密碼


接下來看看每個menuentry要如何修改?

為個別的選項設置賬號密碼的使用模式

根據之前的設置,目前我們的Linux系統選項有五個:

來自/etc/grub.d/10_linux這個文件主動檢測的兩個menuentry;

來自/etc/grub.d/40_custom這個自己設定的三個menuentry;

假設我們在40_custom里面增加一個可以進入救援模式(rescue)的環境,并放置到最后一個選項中,同時僅有知道dmtsai的密碼才能使用。

修改完了不要忘了重建一下grub.cfg啰。重新開機測試一下結果。

默認的選項環境

選項4,5會需要輸入賬號密碼

需要輸入賬號密碼的環境
Problem



4、開機過程的問題解決

很多時候,我們可能做了某些操作導致系統無法正常開機,這時可以進入rescue模式去處理。


4.1、忘記root密碼的解決之道

其實在Linux環境中root密碼忘記時還可以挽救。只要能夠進入并掛載 " / ",然后重設root密碼就可以了。

只是在新版的systemd管理機制中,默認的rescue模式無法直接取得root權限,還是得要使用root密碼才能登錄rescue環境。不過還是可以通過一個名為?"rd.break"?的內核參數來處理。

需要注意,rd.break是在Ram Disk里面的操作系統狀態,因此不能直接取得原本的Linux系統操作環境。所以還需要chroot的支援。可能由于SELinux的問題,你還得加上某些特殊流程才能順利搞定root密碼的救援。

現在來操作一下吧!進入開機grub時按e進入編輯模式,在 linux16那一行末尾使用這個參數。

加上rd.break參數

改完之后不要返回,直接按 [ ctrl + x ]開始開機。

開機完成后會出現如下畫面,此時你應該是在RAM Disk的環境,并不是原本的環境。因此根目錄下面的東西和你原本的系統無關哦!而且,你的系統應該會被掛載到/sysroot目錄下。

接下來這樣做:

echo的內容是你重置后的密碼

需要了解的:

chroot 目錄:代表將你的根目錄 “暫時” 切換到chroot之后的目錄。如上就是/sysroot將會被作為暫時的根目錄。

/.autorelabel:在rd.break的RAM Disk環境下,系統是沒有SELinux的,而你剛剛更改了/etc/shadow(密碼修改)所以這個文件的SELinux安全文本的特性會被取消。如果你沒有讓系統于開機時自動回復SELinux的安全文本,你的系統將無法登錄(在SELinux為Enforcing模式下)。加上./autorelabel就是要讓系統在開機的時候自動使用默認的SELinux type重新寫入SELinux安全文本到每個文件去。


4.2、直接開機就以root執行bash的方法

還可以在開機后直接取得系統根目錄后,讓系統給一個bash給我們用。方法就是將rd.break參數改為 init=/bin/bash 即可。不需要root密碼而有root權限。


重點:

Linux不可隨意關鍵,否則容易造成文件系統錯誤或是其他無法開機的問題;

開機流程主要是:BIOS、MBR、Loader、Kernel+initramfs、systemd;

Loader具有提供選項,加載內核文件,轉交控制權給其他loader等功能;

boot loader可以安裝在MBR或者是每個分割槽的boot sector區域中;

initramfs可以提供內核在開機過程中所需要的最重要的模塊,通常與磁盤和文件系統有關的模塊;

systemd的配置文件主要來自/etc/systemd/system/default.target項目;

額外的設備與模塊對應,可寫入/etc/modprobe.d/*.conf中;

內核模塊的管理可使用lsmod,modinfo,rmmod,insmod,modprobe等命令;

modprobe主要參考/lib/modules/$(uname -r)/modules.dep的設置來載入與卸載內核模塊;

grub2的配置文件與相關文件系統大多放在/boot/grub2目錄下,配置文件為grub.cfg;

grub2對磁盤的代號設置與Linux不同,主要通過檢查的順序來給予設置。如(hd0)及(hd0,1)等;

grub.cfg內每個選項與menuentry有關,而直接指定內核開機時,至少需要Linux16及initrd16兩個項目;

grub.cfg內設置loader控制權移交時,最重要者為chainloader+1這項;

若想要重建initramfs,可使用dracut或mkinitrd處理;

重新安裝grub2到MBR貨boot sector時,可利用grub2-install來處理;

若想進入救援模式(rescue),可與開機選項過程中,在linux16的選項后面加入“rd.break”或"init=/bin/bash”等方式來就如救援模式;

我們可以對grub2的個別選項給予不同的密碼;

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容