最近更新日期:2009/09/14
1. Linux 的開機流程分析
1.1 開機流程一覽 1.2 BIOS, boot loader 與 kernel 載入 1.3 第一支程式 init 及設定檔 /etc/inittab 與 runlevel 1.4 init 處理系統初始化流程 (/etc/rc.d/rc.sysinit) 1.5 啟動系統服務與相關啟動設定檔 (/etc/rc.d/rc N & /etc/sysconfig) 1.6 使用者自訂開機啟動程序 (/etc/rc.d/rc.local) 1.7 根據 /etc/inittab 之設定,載入終端機或 X-Window 介面 1.8 開機過程會用到的主要設定檔: /etc/modprobe.conf, /etc/sysconfig/* 1.9 Run level 的切換: runlevel, init 2. 核心與核心模組 2.1 核心模組與相依性: depmod 2.2 核心模組的觀察: lsmod, modinfo 2.3 核心模組的載入與移除:insmod, modprobe, rmmod 2.4 核心模組的額外參數設定:/etc/modprobe.conf 3. Boot loader: Grub 3.1 boot loader 的兩個 stage 3.2 grub 的設定檔 /boot/grub/menu.lst 與選單類型: 磁碟代號, menu.lst 3.3 initrd 的重要性與建立新 initrd 檔案: mkinitrd 3.4 測試與安裝 grub: grub-install, grub shell 3.5 開機前的額外功能修改 3.6 關於核心功能當中的 vga 設定 3.7 BIOS 無法讀取大硬碟的問題 3.8 為個別選單加上密碼: grub-md5-crypt 4. 開機過程的問題解決 4.1 忘記 root 密碼的解決之道 4.2 init 設定檔錯誤 4.3 BIOS 磁碟對應的問題 (device.map) 4.4 因檔案系統錯誤而無法開機 4.5 利用 chroot 切換到另一顆硬碟工作 5. 重點回顧 6. 本章習題 7. 參考資料與延伸閱讀 8. 針對本文的建議:http://phorum.vbird.org/viewtopic.php?t=23891 Linux 的開機流程分析 開機不是只要按一下電源鈕而關機只要關掉電源鈕就可以了嗎?有何大學問?話是這樣沒錯啦,但是由於 Linux 是一套多人多工的作業系統,你難保你在關機時沒有人在線上,如果你關機的時候碰巧一大群人在線上工作, 那會讓當時在線上工作的人馬上斷線的!那不是害死人了!一些資料可是無價之寶哩! 另外 Linux 在執行的時候,雖然你在畫面上只會看到黑壓壓的一片,完全沒有任何畫面,
但其實他是有很多的程序在背景底下執行的,例如登錄檔管控程式、前面提到的例行性工作排程等,
當然還有一大堆網路服務,如郵件伺服器、WWW 伺服器等等。你如果隨便關機的話,
是很容易傷害硬碟及資料傳輸的動作的!所以在 Linux 下關機可是一門大學問喔。 開機流程一覽 既然開機是很嚴肅的一件事,那我們就來瞭解一下整個開機的過程吧! 好讓大家比較容易發現開機過程裡面可能會發生問題的地方,以及出現問題後的解決之道! 不過,由於開機的過程中,那個開機管理程式 (Boot Loader) 使用的軟體可能不一樣,例如目前各大 Linux distributions 的主流為 grub,但早期 Linux 預設是使用 LILO ,台灣地區則很多朋友喜歡使用 spfdisk 。 但無論如何,我們總是得要瞭解整個 boot loader 的工作情況,才能瞭解為何進行多重開機的設定時, 老是聽人家講要先安裝 Windows 再安裝 Linux 的原因∼ 假設以個人電腦架設的 Linux 主機為例 (先回到第零章計算機概論看看相關的硬體常識喔), 當你按下電源按鍵後電腦硬體會主動的讀取 BIOS 來載入硬體資訊及進行硬體系統的自我測試, 之後系統會主動的去讀取第一個可開機的裝置 (由 BIOS 設定的) ,此時就可以讀入開機管理程式了。 開機管理程式可以指定使用哪個核心檔案來開機,並實際載入核心到記憶體當中解壓縮與執行, 此時核心就能夠開始在記憶體內活動,並偵測所有硬體資訊與載入適當的驅動程式來使整部主機開始運作, 等到核心偵測硬體與載入驅動程式完畢後,一個最陽春的作業系統就開始在你的 PC 上面跑了。 主機系統開始運作後,此時 Linux 才會呼叫外部程式開始準備軟體執行的環境, 並且實際的載入所有系統運作所需要的軟體程式哩!最後系統就會開始等待你的登入與操作啦! 簡單來說,系統開機的經過可以彙整成底下的流程的:
大概的流程就是上面寫的那個樣子啦,你會發現 init 這個傢伙佔的比重非常重! 所以我們才會在第十七章的 pstree 指令中談到這傢伙。 那每一個程序的內容主要是在幹嘛呢?底下就分別來談一談吧! BIOS, boot loader 與 kernel 載入 我們在第三章曾經談過簡單的開機流程與 MBR 的功能,
當時為了多重開機而進行的簡短的介紹。現在你已經有足夠的 Linux 基礎了,所以底下讓我們來加強說明啦!
我們在第零章的計算機概論就曾談過電腦主機架構, 在個人電腦架構下,你想要啟動整部系統首先就得要讓系統去載入 BIOS (Basic Input Output System),並透過 BIOS 程式去載入 CMOS 的資訊,並且藉由 CMOS 內的設定值取得主機的各項硬體設定, 例如 CPU 與周邊設備的溝通時脈啊、開機裝置的搜尋順序啊、硬碟的大小與類型啊、 系統時間啊、各周邊匯流排的是否啟動 Plug and Play (PnP, 隨插即用裝置) 啊、 各周邊設備的 I/O 位址啊、以及與 CPU 溝通的 IRQ 岔斷等等的資訊。 在取得這些資訊後,BIOS 還會進行開機自我測試 (Power-on Self Test, POST) (註1)。 然後開始執行硬體偵測的初始化,並設定 PnP 裝置,之後再定義出可開機的裝置順序, 接下來就會開始進行開機裝置的資料讀取了 (MBR 相關的任務開始)。 由於我們的系統軟體大多放置到硬碟中嘛!所以 BIOS 會指定開機的裝置好讓我們可以讀取磁碟中的作業系統核心檔案。 但由於不同的作業系統他的檔案系統格式不相同,因此我們必須要以一個開機管理程式來處理核心檔案載入 (load) 的問題, 因此這個開機管理程式就被稱為 Boot Loader 了。那這個 Boot Loader 程式安裝在哪裡呢?就在開機裝置的第一個磁區 (sector) 內,也就是我們一直談到的 MBR (Master Boot Record, 主要開機記錄區)。 那你會不會覺得很奇怪啊?既然核心檔案需要 loader 來讀取,那每個作業系統的 loader 都不相同, 這樣的話 BIOS 又是如何讀取 MBR 內的 loader 呢?很有趣的問題吧!其實 BIOS 是透過硬體的 INT 13 中斷功能來讀取 MBR 的,也就是說,只要 BIOS 能夠偵測的到你的磁碟 (不論該磁碟是 SATA 還是 IDE 介面),那他就有辦法透過 INT 13 這條通道來讀取該磁碟的第一個磁區內的 MBR 啦!(註2) 這樣 boot loader 也就能夠被執行囉!
剛剛說到 Loader 的最主要功能是要認識作業系統的檔案格式並據以載入核心到主記憶體中去執行。 由於不同作業系統的檔案格式不一致,因此每種作業系統都有自己的 boot loader 啦!用自己的 loader 才有辦法載入核心檔案嘛!那問題就來啦,你應該有聽說過多重作業系統吧?也就是在一部主機上面安裝多種不同的作業系統。 既然你 (1)必須要使用自己的 loader 才能夠載入屬於自己的作業系統核心,而 (2)系統的 MBR 只有一個,那你怎麼會有辦法同時在一部主機上面安裝 Windows 與 Linux 呢? 這就得要回到第八章的磁碟檔案系統去回憶一下檔案系統功能了。 其實每個檔案系統 (filesystem, 或者是 partition) 都會保留一塊開機磁區 (boot sector) 提供作業系統安裝 boot loader , 而通常作業系統預設都會安裝一份 loader 到他根目錄所在的檔案系統的 boot sector 上。如果我們在一部主機上面安裝 Windows 與 Linux 後,該 boot sector, boot loader 與 MBR 的相關性會有點像下圖: 圖 1.2.1、 boot loader 安裝在 MBR, boot sector 與作業系統的關係 如上圖所示,每個作業系統預設是會安裝一套 boot loader 到他自己的檔案系統中 (就是每個 filesystem 左下角的方框),而在 Linux 系統安裝時,你可以選擇將 boot loader 安裝到 MBR 去,也可以選擇不安裝。 如果選擇安裝到 MBR 的話,那理論上你在 MBR 與 boot sector 都會保有一份 boot loader 程式的。 至於 Windows 安裝時,他預設會主動的將 MBR 與 boot sector 都裝上一份 boot loader!所以啦, 你會發現安裝多重作業系統時,你的 MBR 常常會被不同的作業系統的 boot loader 所覆蓋啦! ^_^ 我們剛剛提到的兩個問題還是沒有解決啊!雖然各個作業系統都可以安裝一份 boot loader 到他們的 boot sector 中, 這樣作業系統可以透過自己的 boot loader 來載入核心了。問題是系統的 MBR 只有一個哩! 你要怎麼執行 boot sector 裡面的 loader 啊?這個我們得要回憶一下第三章約略提過的 boot loader 的功能了。boot loader 主要的功能如下:
由於具有選單功能,因此我們可以選擇不同的核心來開機。而由於具有控制權轉交的功能,因此我們可以載入其他 boot sector 內的 loader 啦!不過 Windows 的 loader 預設不具有控制權轉交的功能,因此你不能使用 Windows 的 loader 來載入 Linux 的 loader 喔!這也是為啥第三章談到 MBR 與多重開機時,會特別強調先裝 Windows 再裝 Linux 的緣故。 我們將上述的三個功能以底下的圖示來解釋你就看的懂了!(與第三章的圖示也非常類似啦!) 圖 1.2.2、 開機管理程式的選單功能與控制權轉交功能示意圖 如上圖所示,我的 MBR 使用 Linux 的 grub 這個開機管理程式,並且裡面假設已經有了三個選單, 第一個選單可以直接指向 Linux 的核心檔案並且直接載入核心來開機;第二個選單可以將開機管理程式控制權交給 Windows 來管理,此時 Windows 的 loader 會接管開機流程,這個時候他就能夠啟動 windows 了。第三個選單則是使用 Linux 在 boot sector 內的開機管理程式,此時就會跳出另一個 grub 的選單啦!瞭解了嗎? 而最終 boot loader 的功能就是『載入 kernel 檔案』啦!
當我們藉由 boot loader 的管理而開始讀取核心檔案後,接下來, Linux 就會將核心解壓縮到主記憶體當中, 並且利用核心的功能,開始測試與驅動各個周邊裝置,包括儲存裝置、CPU、網路卡、音效卡等等。 此時 Linux 核心會以自己的功能重新偵測一次硬體,而不一定會使用 BIOS 偵測到的硬體資訊喔!也就是說,核心此時才開始接管 BIOS 後的工作了。 那麼核心檔案在哪裡啊?一般來說,他會被放置到 /boot 裡面,並且取名為 /boot/vmlinuz 才對!
從上表我們也可以知道此版本的 Linux 核心為 2.6.18-92.el5 這個版本!為了硬體開發商與其他核心功能開發者的便利, 因此 Linux 核心是可以透過動態載入核心模組的 (就請想成驅動程式即可),這些核心模組就放置在 /lib/modules/ 目錄內。 由於模組放置到磁碟根目錄內 (要記得 /lib 不可以與 / 分別放在不同的 partition !), 因此在開機的過程中核心必須要掛載根目錄,這樣才能夠讀取核心模組提供載入驅動程式的功能。 而且為了擔心影響到磁碟內的檔案系統,因此開機過程中根目錄是以唯讀的方式來掛載的喔。 一般來說,非必要的功能且可以編譯成為模組的核心功能,目前的 Linux distributions 都會將他編譯成為模組。 因此 USB, SATA, SCSI... 等磁碟裝置的驅動程式通常都是以模組的方式來存在的。 現在來思考一種情況,假設你的 linux 是安裝在 SATA 磁碟上面的,你可以透過 BIOS 的 INT 13 取得 boot loader 與 kernel 檔案來開機,然後 kernel 會開始接管系統並且偵測硬體及嘗試掛載根目錄來取得額外的驅動程式。 問題是,核心根本不認識 SATA 磁碟,所以需要載入 SATA 磁碟的驅動程式, 否則根本就無法掛載根目錄。但是 SATA 的驅動程式在 /lib/modules 內,你根本無法掛載根目錄又怎麼讀取到 /lib/modules/ 內的驅動程式?是吧!非常的兩難吧!在這個情況之下,你的 Linux 是無法順利開機的! 那怎辦?沒關係,我們可以透過虛擬檔案系統來處理這個問題。 虛擬檔案系統 (Initial RAM Disk) 一般使用的檔名為 /boot/initrd ,這個檔案的特色是,他也能夠透過 boot loader 來載入到記憶體中, 然後這個檔案會被解壓縮並且在記憶體當中模擬成一個根目錄, 且此模擬在記憶體當中的檔案系統能夠提供一支可執行的程式,透過該程式來載入開機過程中所最需要的核心模組, 通常這些模組就是 USB, RAID, LVM, SCSI 等檔案系統與磁碟介面的驅動程式啦!等載入完成後, 會幫助核心重新呼叫 /sbin/init 來開始後續的正常開機流程。 圖 1.2.3、 BIOS 與 boot loader 及核心載入流程示意圖 如上圖所示,boot loader 可以載入 kernel 與 initrd ,然後在記憶體中讓 initrd 解壓縮成為根目錄, kernel 就能夠藉此載入適當的驅動程式,最終釋放虛擬檔案系統,並掛載實際的根目錄檔案系統, 就能夠開始後續的正常開機流程。更詳細的 initrd 說明,你可以自行使用 man initrd 去查閱看看。 底下讓我們來瞭解一下 CentOS 5.x 的 initrd 檔案內容有什麼吧! ^_^
嘿嘿!透過上述執行檔的內容,我們可以知道 initrd 有載入模組並且嘗試掛載了虛擬檔案系統。 接下來就能夠順利的運作啦!那麼是否一定需要 initrd 呢?
在核心完整的載入後,您的主機應該就開始正確的運作了,接下來,就是要開始執行系統的第一支程式: /sbin/init。 第一支程式 init 及設定檔 /etc/inittab 與 runlevel 在核心載入完畢、進行完硬體偵測與驅動程式載入後,此時你的主機硬體應該已經準備就緒了 (ready) ,
此時核心會主動的呼叫第一支程式,那就是 /sbin/init 囉。這也是為啥第十七章的 pstree 指令介紹時,你會發現 init 的 PID 號碼是一號啦。
/sbin/init 最主要的功能就是準備軟體執行的環境,包括系統的主機名稱、網路設定、語系處理、檔案系統格式及其他服務的啟動等。
而所有的動作都會透過 init 的設定檔,亦即是 /etc/inittab 來規劃,而
inittab 內還有一個很重要的設定項目,那就是預設的 runlevel (開機執行等級) 啦!
那麼什麼是 run level 呢?他有什麼功用啊?其實很簡單啦, Linux 就是藉由設定 run level 來規定系統使用不同的服務來啟動,讓 Linux 的使用環境不同。基本上,依據有無網路與有無 X Window 而將 run level 分為 7 個等級,分別是:
由於 run level 0, 4, 6 不是關機、重新開機就是系統保留的,所以:『
您當然不能將預設的 run level 設定為這三個值 』,
否則系統就會不斷的自動關機或自動重新開機....
好了,那麼我們開機時,到底是如何取得系統的 run level 的?當然是 /etc/inittab 所設定的囉!
那麼 /etc/inittab 到底有什麼資訊呢?我們先來看看這個檔案的內容好了:
讓我們解析一下這個檔案吧!首先,這個檔案的語法是利用冒號 (:) 將設定分隔成為四個欄位,每個欄位的意義與說明如下:
事實上 /etc/inittab 的設定也有點類似 shell script 啦,因為該檔案內容的設定也是一行一行的從上往下處理的, 因此我們可以知道 CentOS 的 init 依據 inittab 設定的處理流程會是:
現在你可以知道為啥 [ctrl]+[alt]+[del] 可以重新開機而我們預設提供 6 個虛擬終端機 (tty1~tty6) 給你使用了吧!由於整個設定都是依據 /etc/inittab 來決定的,因此如果你想要修改任何細節的話, 可以這樣做喔:
所以說,你現在會自行修改登入時的預設 run level 設定值了嗎?夠簡單的吧? 一般來說,我們預設都是 3 或者是 5 來作為預設的 run level 的。但有時後可能需要進入 run level 1, 也就是單人維護模式的環境當中。這個 run level 1 有點像是 Windows 系統當中的『安全模式』啦, 專門用來處理當系統有問題時的操作環境。此外,當系統發現有問題時,舉例來說,不正常關機造成 filesystem 的不一致現象時,系統會主動的進入單人維護模式呢! 好了, init 在取得 run level 之後,接下來要幹嘛? 上面 /etc/inittab 檔案內容不是有提到 sysinit 嗎?準備初始化系統了吧! init 處理系統初始化流程 (/etc/rc.d/rc.sysinit) 還記得上面提到 /etc/inittab 裡頭有這一句『 si::sysinit:/etc/rc.d/rc.sysinit 』吧? 這表示:『我開始載入各項系統服務之前,得先做好整個系統環境,我主要利用 /etc/rc.d/rc.sysinit 這個 shell script 來設定好我的系統環境的。』夠清楚了吧? 所以,我想要知道到底 CentOS 開機的過程當中幫我進行了什麼動作,就得要仔細的分析 /etc/rc.d/rc.sysinit 囉。
如果你使用 vim 去查閱過 /etc/rc.d/rc.sysinit 的話,那麼可以發現他主要的工作大抵有這幾項:
在 /etc/rc.d/rc.sysinit 將基本的系統設定資料都寫好了,也將系統的資料設定完整! 而如果你想要知道到底開機的過程中發生了什麼事情呢?那麼就執行『 dmesg 』吧。 另外,基本上,在這個檔案當中所進行的很多工作的預設設定檔,其實都在 /etc/sysconfig/ 當中呢! 所以,請記得將 /etc/sysconfig/ 內的檔案好好的瞧一瞧喔! ^_^ 在這個過程當中,比較值得注意的是自訂模組的載入!在 CentOS 當中,如果我們想要載入核心模組的話, 可以將整個模組寫入到 /etc/sysconfig/modules/*.modules 當中,在該目錄下, 只要記得檔名最後是以 .modules 結尾即可。 這個過程是非必要的,因為我們目前的預設模組實在已經很夠用了,除非是您的主機硬體實在太新了, 非要自己載入新的模組不可,否則,在經過 /etc/rc.d/rc.sysinit 的處理後, 你的主機系統應該是已經跑得很順暢了啦!就等著你將系統相關的服務與網路服務啟動囉! 啟動系統服務與相關啟動設定檔 (/etc/rc.d/rc N & /etc/sysconfig) 載入核心讓整個系統準備接受指令來工作,再經過 /etc/rc.d/rc.sysinit 的系統模組與相關硬體資訊的初始化後,你的 CentOS 系統應該已經順利工作了。 只是,我們還得要啟動系統所需要的各項『服務』啊!這樣主機才能提供我們相關的網路或者是主機功能嘛! 這個時候,依據我們在 /etc/inittab 裡面提到的 run level 設定值,就可以來決定啟動的服務項目了。 舉例來說,使用 run level 3 當然就不需要啟動 X Window 的相關服務囉,您說是吧? 那麼各個不同的 run level 服務啟動的各個 shell script 放在哪?還記得 /etc/inittab 裡面提到的:
上面提到的就是各個 run level 要執行的各項腳本放置處啦!主要是透過 /etc/rc.d/rc 這個指令來處理相關任務! 由於鳥哥使用預設的 runlevel 5 ,因此我們主要針對上述特殊字體那行來解釋好了: /etc/rc.d/rc 5 的意義是這樣的 (建議您自行使用 vim 去觀察一下 /etc/rc.d/rc 這個檔案,你會更有概念!):
透過上面的說明我們可以知道所有的項目都與 /etc/rc5.d/ 有關,那麼我們就來瞧瞧這個目錄下有些什麼玩意兒吧!
在這個目錄下的檔案很有趣,主要具有幾個特點:
我們在第十八章談過服務的啟動主要是以『/etc/init.d/服務檔名 {start,stop}』來啟動與關閉的,那麼透過剛剛 /etc/rc.d/rc 程式的解說,我們可以清楚的瞭解到了 /etc/rc5.d/[SK]xx 其實就是跑到 /etc/init.d/ 去找到相對應的服務腳本, 然後分別進行 start (Sxx) 或 stop (Kxx) 的動作而已啦!舉例來說,以上述的表格內的 K91capi 及 S10network 為例好了, 透過 /etc/rc.d/rc 5 的執行,這兩個檔案會這樣進行:
所以說,你有想要啟動該 runlevel 時就執行的服務,那麼利用 Sxx 並指向 /etc/init.d/ 的特定服務啟動腳本後, 該服務就能夠在開機時啟動啦!就這麼簡單!問題是,你需要自行處理這個 K, S 開頭的連結檔嗎? 並不需要的,第十八章談到的 chkconfig 就是在負責處理這個連結檔啦!這樣有沒有跟第十八章的觀念串在一起了呢? ^_^ 那麼為什麼 K 與 S 後面要有數字呢?因為各不同的服務其實還是互有關係的。舉例來說,如果要啟動 WWW 服務,總是得要有網路吧?所以 /etc/init.d/network 就會比較先被啟動啦!那麼您就會知道在 S 或者是 K 後面接的數字是啥意思了吧?嘿嘿,那就是執行的順序啦!那麼哪個檔案被最後執行呢? 看到最後一個被執行的項目是啥?沒錯,就是 S99local ,亦即是: /etc/rc.d/rc.local 這個檔案啦! 使用者自訂開機啟動程序 (/etc/rc.d/rc.local) 在完成預設 runlevel 指定的各項服務的啟動後,如果我還有其他的動作想要完成時,舉例來說, 我還想要寄一封 mail 給某個系統管理帳號,通知他,系統剛剛重新開機完畢,那麼是否應該要製作一個 shell script 放置在 /etc/init.d/ 裡面,然後再以連結方式連結到 /etc/rc5.d/ 裡面呢?呵呵!當然不需要!還記得上一小節提到的 /etc/rc.d/rc.local 吧? 這個檔案就可以執行您自己想要執行的系統指令了。 也就是說,我有任何想要在開機時就進行的工作時,直接將他寫入 /etc/rc.d/rc.local , 那麼該工作就會在開機的時候自動被載入喔!而不必等我們登入系統去啟動呢! 是否很方便啊!一般來說,鳥哥就很喜歡把自己製作的 shell script 完整檔名寫入 /etc/rc.d/rc.local ,如此一來,開機就會將我的 shell script 執行過,真是好棒那! 根據 /etc/inittab 之設定,載入終端機或 X-Window 介面 在完成了系統所有服務的啟動後,接下來 Linux 就會啟動終端機或者是 X Window 來等待使用者登入啦! 實際參考的項目是 /etc/inittab 內的這一段:
這一段代表,在 run level 2, 3, 4, 5 時,都會執行 /sbin/mingetty 這個咚咚, 而且執行六個,這也是為何我們 Linux 會提供『六個純文字終端機』的設定所在啊! 因為 mingetty 就是在啟動終端機的指令說。 要注意的是那個 respawn 的 init 動作項目,他代表『當後面的指令被終止 (terminal) 時, init 會主動的重新啟動該項目。』這也是為何我們登入 tty1 終端機介面後,以 exit 離開後, 系統還是會重新顯示等待使用者輸入的畫面的原因啊! 如果改天您不想要有六個終端機時,可以取消某些終端機介面嗎?當然可以啊! 就將上面表格當中的某些項目註解掉即可!例如不想要 tty5 與 tty6 ,就將那兩行註解, 則下次重新開機後,您的 Linux 就只剩下『 F1 ~ F4 』有效而已,這樣說,可以瞭解吧!!^_^ 至於如果我們使用的是 run level 5 呢?那麼除了這六個終端機之外, init 還會執行 /etc/X11/prefdm -nodaemon 那個指令喔!該指令我們會在第二十四章、X Window 再來詳談! 他主要的功能就是在啟動 X Window 啦! 開機過程會用到的主要設定檔 我們在 /sbin/init 的運作過程中有談到許多執行腳本,包括 /etc/rc.d/rc.sysinit 以及 /etc/rc.d/rc 等等,
其實這些腳本都會使用到相當多的系統設定檔,這些開機過程會用到的設定檔則大多放置在 /etc/sysconfig/ 目錄下。
同時,由於核心還是需要載入一些驅動程式 (核心模組),此時系統自訂的裝置與模組對應檔 (/etc/modprobe.conf)
就顯的挺重要了喔!
還記得我們在 /etc/rc.d/rc.sysinit 當中談到的載入使用者自訂模組的地方嗎?就是在 /etc/sysconfig/modules/ 目錄下啊! 雖然核心提供的預設模組已經很足夠我們使用了,但是,某些條件下我們還是得對模組進行一些參數的規劃, 此時就得要使用到 /etc/modprobe.conf 囉!舉例來說,鳥哥的 CentOS 主機的 modprobe.conf 有點像這樣:
這個檔案大多在指定系統內的硬體所使用的模組啦!這個檔案通常系統是可以自行產生的,所以你不必手動去訂正他! 不過,如果系統捉到錯誤的驅動程式,或者是你想要使用更新的驅動程式來對應相關的硬體配備時, 你就得要自行手動的處理一下這個檔案了。 以上表的第一行為例,鳥哥使用螃蟹卡 (Realtek 的晶片組) 來作為我的網路卡,那螃蟹卡使用的模組就是 8139too
啦!這樣看的懂了吧?當我要啟動網路卡時,系統會跑到這個檔案來查閱一下,然後載入 8139too
驅動程式來驅動網路卡囉!更多的相關說明,請 man modprobe.conf 喔!
不說您也知道,整個開機的過程當中,老是讀取的一些服務的相關設定檔都是記錄在 /etc/sysconfig 目錄下的!那麼該目錄底下有些啥玩意兒?我們找幾個重要的檔案來談談:
總而言之一句話,這個目錄下的檔案很重要的啦!開機過程裡面常常會讀取到的! Run level 的切換 在我們完成上面的所有資訊後,其實整個 Linux 主機就已經在等待我們使用者的登入啦! 但是,相信您應該還是會有一點疑問的地方,那就是:『我該如何切換 run level 呢?』會不會很難啊?不會啦!很簡單∼但是依據執行的時間而有不同的方式啊! 事實上,與 run level 有關的啟動其實是在 /etc/rc.d/rc.sysinit 執行完畢之後。也就是說,其實 run level 的不同僅是 /etc/rc[0-6].d 裡面啟動的服務不同而已。不過,依據開機是否自動進入不同 run level 的設定,我們可以說:
假設原本我們是以 run level 5 登入系統的,但是因為某些因素,想要切換成為 run level 3 時, 該怎麼辦呢?很簡單啊,執行『 init 3 』即可切換。但是 init 3 這個動作到底做了什麼呢? 我們不是說了嗎?事實上,不同的 run level 只是載入的服務不同罷了, 亦即是 /etc/rc5.d/ 還有 /etc/rc3.d 內的 Sxxname 與 Kxxname 有差異而已。 所以說,當執行 init 3 時,系統會:
也就是說,兩個 run level 都存在的服務就不會被關閉啦!如此一來,就很容易切換 run level 了, 而且還不需要重新開機呢!真方便。那我怎麼知道目前的 run level 是多少呢? 直接在 bash 當中輸入 runlevel 即可啊!
那麼你能不能利用 init 來進行關機與重新開機呢?可以的啦!利用『 init 0 』就能夠關機, 而『 init 6 』就能夠重新開機!為什麼?往前翻一下 runlevel 的定義即可瞭解吧! 核心與核心模組 談完了整個開機的流程,您應該會知道,在整個開機的過程當中,是否能夠成功的驅動我們主機的硬體配備, 是核心 (kernel) 的工作!而核心一般都是壓縮檔,因此在使用核心之前,就得要將他解壓縮後, 才能載入主記憶體當中。 另外,為了應付日新月異的硬體,目前的核心都是具有『可讀取模組化驅動程式』的功能, 亦即是所謂的『 modules (模組化)』的功能啦!所謂的模組化可以將他想成是一個『外掛程式』, 該外掛程式可能由硬體開發廠商提供,也有可能我們的核心本來就支援∼不過,較新的硬體, 通常都需要硬體開發商提供驅動程式模組啦! 那麼核心與核心模組放在哪?
如果該核心被順利的載入系統當中了,那麼就會有幾個資訊紀錄下來:
問題來啦,如果我有個新的硬體,偏偏我的作業系統不支援,該怎麼辦?很簡單啊!
上面第一點還很好理解,反正就是重新編譯核心就是了。不過,核心編譯很不容易啊!
我們會在後續章節約略介紹核心編譯的整個程序。比較有趣的則是將該硬體的驅動程式編譯成為模組啦!
關於編譯的方法,可以參考後續的第二十二章、原始碼與 tarball的介紹。
我們這個章節僅是說明一下,如果想要載入一個已經存在的模組時,該如何是好? 核心模組與相依性 既然要處理核心模組,自然就得要瞭解瞭解我們核心提供的模組之間的相關性啦! 基本上,核心模組的放置處是在 /lib/modules/$(uname -r)/kernel 當中,裡面主要還分成幾個目錄:
如果要我們一個一個的去檢查這些模組的主要資訊,然後定義出他們的相依性, 我們可能會瘋掉吧!所以說,我們的 Linux 當然會提供一些模組相依性的解決方案囉∼ 對啦!那就是檢查 /lib/modules/$(uname -r)/modules.dep 這個檔案啦!他記錄了在核心支援的模組的各項相依性。 那麼這個檔案如何建立呢?挺簡單!利用 depmod 這個指令就可以達到建立該檔案的需求了!
以上面的範例一為例,我們的 Linux kernel 2.6.x 版本的核心模組副檔名一定是 .ko 結尾的, 當你使用 depmod 之後,該程式會跑到模組標準放置目錄 /lib/modules/$(uname -r)/kernel , 並依據相關目錄的定義將全部的模組捉出來分析,最終才將分析的結果寫入 modules.dep 檔案中的吶! 這個檔案很重要喔!因為他會影響到本章稍後會介紹的 modprobe 指令的應用! 核心模組的觀察 那你到底曉不曉得目前核心載入了多少的模組呢?粉簡單啦!利用 lsmod 即可!
使用 lsmod 之後,系統會顯示出目前已經存在於核心當中的模組,顯示的內容包括有:
也就是說,模組其實真的有相依性喔!舉上表為例, mii 這個模組會被 8139too 所使用。 簡單的說,就是『當你要載入 8139too 時,需要先載入 mii 這個模組才可以順利的載入 8139too』的意思。 那麼除了顯示出目前的模組外,我還可以查閱每個模組的資訊嗎?舉例來說,我們知道 8139too 是螃蟹卡的驅動程式,那麼 mii 是什麼咚咚?就用 modinfo 來觀察吧!
事實上,這個 modinfo 除了可以『查閱在核心內的模組』之外,還可以檢查『某個模組檔案』, 因此,如果你想要知道某個檔案代表的意義為何,利用 modinfo 加上完整檔名吧! 看看就曉得是啥玩意兒囉! ^_^ 核心模組的載入與移除 好了,如果我想要自行手動載入模組,又該如何是好?有很多方法啦,最簡單而且建議的,是使用 modprobe 這個指令來載入模組, 這是因為 modprobe 會主動的去搜尋 modules.dep 的內容,先克服了模組的相依性後, 才決定需要載入的模組有哪些,很方便。至於 insmod 則完全由使用者自行載入一個完整檔名的模組, 並不會主動的分析模組相依性啊!
他立刻就將該模組載入囉∼但是 insmod 後面接的模組必須要是完整的『檔名』才行!那如何移除這個模組呢?
使用 insmod 與 rmmod 的問題就是,你必須要自行找到模組的完整檔名才行,而且如同上述範例二的結果, 萬一模組有相依屬性的問題時,你將無法直接載入或移除該模組呢!所以近年來我們都建議直接使用 modprobe 來處理模組載入的問題,這個指令的用法是:
使用 modprobe 真的是要比 insmod 方便很多!因為他是直接去搜尋 modules.dep 的紀錄, 所以囉,當然可以克服模組的相依性問題,而且還不需要知道該模組的詳細路徑呢! 好方便! ^_^
核心模組的額外參數設定: /etc/modprobe.conf 這個檔案我們之前已經談過了,這裡只是再強調一下而已,如果您想要修改某些模組的額外參數設定, 就在這個檔案內設定吧!我們假設一個案例好了,假設我的網路卡 eth0 是使用 ne , 但是 eth1 同樣也使用 ne ,為了避免同一個模組會導致網路卡的錯亂, 因此,我可以先找到 eth0 與 eth1 的 I/O 與 IRQ ,假設:
則:
嘿嘿!如此一來,我的 Linux 就不會捉錯網路卡的對應囉!因為被我強制指定某個 I/O 咯嘛! ^_^ Boot Loader: Grub 在看完了前面的整個開機流程,以及核心模組的整理之後,你應該會發現到一件事情,
那就是『 boot loader 是載入核心的重要工具』啊!沒有 boot loader 的話,那麼
kernel 根本就沒有辦法被系統載入的呢!所以,底下我們會先談一談 boot loader 的功能,
然後再講一講現階段 Linux 裡頭最主流的 grub 這個 boot loader 吧! boot loader 的兩個 stage 我們在第一小節開機流程的地方曾經講過,在 BIOS 讀完資訊後,接下來就是會到第一個開機裝置的 MBR 去讀取 boot loader 了。這個 boot loader 可以具有選單功能、直接載入核心檔案以及控制權移交的功能等, 系統必須要有 loader 才有辦法載入該作業系統的核心就是了。但是我們都知道, MBR 是整個硬碟的第一個 sector 內的一個區塊,充其量整個大小也才 446 bytes 而已。 我們的 loader 功能這麼強,光是程式碼與設定資料不可能只佔不到 446 bytes 的容量吧?那如何安裝? 為了解決這個問題,所以 Linux 將 boot loader 的程式碼執行與設定值載入分成兩個階段 (stage) 來執行:
那麼這些設定檔是放在哪裡啊?這些與 grub 有關的檔案都放置到 /boot/grub 中,那我們就來看看有哪些檔案吧!
從上面的說明你可以知道 /boot/grub/ 目錄下最重要的就是設定檔 (menu.lst) 以及各種檔案系統的定義! 我們的 loader 讀取了這種檔案系統定義資料後,就能夠認識檔案系統並讀取在該檔案系統內的核心檔案囉。 至於 grub 的設定檔檔名,其實應該是 menu.lst 的,只是在 Red Hat 裡面被定義成為 /boot/grub.conf 而已。 鳥哥建議您還是記憶 menu.lst 比較好喔! 所以從上面的檔案來看, grub 認識的檔案系統真的非常多喔!正因為如此,所以 grub 才會取代 Lilo 這個老牌的 boot loader 嘛!好了,接下來就來瞧瞧設定檔內有啥設定值吧! grub 的設定檔 /boot/grub/menu.lst 與選單類型 grub 是目前使用最廣泛的 Linux 開機管理程式,舊的 Lilo 這個開機管理程式現在已經很少見了, 所以本章才會將 Lilo 的介紹捨棄的說。grub 的優點挺多的,包括有:
上面第三點其實就是 Stage 1, Stage 2 分別安裝在 MBR (主程式) 與檔案系統當中 (設定檔與定義檔) 的原因啦!
好了,接下來,讓我們好好瞭解一下 grub 的設定檔: /boot/grub/menu.lst 這玩意兒吧!
要注意喔,那個 lst 是 LST 的小寫,不要搞錯囉!
安裝在 MBR 的 grub 主程式,最重要的任務之一就是從磁碟當中載入核心檔案, 以讓核心能夠順利的驅動整個系統的硬體。所以囉, grub 必須要認識硬碟才行啊!那麼 grub 到底是如何認識硬碟的呢? 嘿嘿! grub 對硬碟的代號設定與傳統的 Linux 磁碟代號可完全是不同的!grub 對硬碟的識別使用的是如下的代號: (hd0,0) 夠神了吧?跟 /dev/hda1 風馬牛不相干∼怎麼辦啊?其實只要注意幾個東西即可,那就是:
所以說,第一顆『搜尋到的硬碟』代號為:『(hd0)』,而該顆硬碟的第一號分割槽為『(hd0,0)』,這樣說瞭解了吧? 反正你要記得,在 grub 裡面,他開始的數字是 0 而不是 1 就是了!
所以說,整個硬碟代號為:
這樣應該比較好看出來了吧?第一顆硬碟的 MBR 安裝處的硬碟代號就是『(hd0)』, 而第一顆硬碟的第一個分割槽的 boot sector 代號就是『(hd0,0)』第一顆硬碟的第一個邏輯分割槽的 boot sector 代號為『(hd0,4)』瞭了吧!
瞭解了 grub 當中最麻煩的硬碟代號後,接下來,我們就可以瞧一瞧設定檔的內容了。先看一下鳥哥的 CentOS 內的 /boot/grub/menu.lst 好了:
在 title 以前的四行,都是屬於 grub 的整體設定,包括預設的等待時間與預設的開機項目, 還有顯示的畫面特性等等。至於 title 後面才是指定開機的核心檔案或者是 boot loader 控制權。 在整體設定方面的項目主要常見的有:
整體設定的地方大概是這樣,而底下那個 title 則是顯示開機的設定項目。如同前一小節提到的,開機時可以選擇 (1)直接指定核心檔案開機或 (2)將 boot loader 控制權轉移到下個 loader (此過程稱為 chain-loader)。每個 title 後面接的是『該開機項目名稱的顯示』,亦即是在選單出現時,選單上面的名稱而已。 那麼這兩種方式的設定有啥不同呢?
initrd 的重要性與建立新 initrd 檔案 我們在本章稍早之前『 boot loader 與 kernel 載入』的地方已經提到過 initrd 這玩意兒,他的目的在於提供開機過程中所需要的最重要核心模組,以讓系統開機過程可以順利完成。 會需要 initrd 的原因,是因為核心模組放置於 /lib/modules/$(uname -r)/kernel/ 當中, 這些模組必須要根目錄 (/) 被掛載時才能夠被讀取。但是如果核心本身不具備磁碟的驅動程式時, 當然無法掛載根目錄,也就沒有辦法取得驅動程式,因此造成兩難的地步。 initrd 可以將 /lib/modules/.... 內的『開機過程當中一定需要的模組』包成一個檔案 (檔名就是 initrd), 然後在開機時透過主機的 INT 13 硬體功能將該檔案讀出來解壓縮,並且 initrd 在記憶體內會模擬成為根目錄, 由於此虛擬檔案系統 (Initial RAM Disk) 主要包含磁碟與檔案系統的模組,因此我們的核心最後就能夠認識實際的磁碟, 那就能夠進行實際根目錄的掛載啦!所以說:『initrd 內所包含的模組大多是與開機過程有關,而主要以檔案系統及硬碟模組 (如 usb, SCSI 等) 為主』的啦! 一般來說,需要 initrd 的時刻為:
一般來說,各 distribution 提供的核心都會附上 initrd 檔案,但如果妳有特殊需要所以想重製 initrd 檔案的話, 可以使用 mkinitrd 來處理的。這個檔案的處理方式很簡單, man mkinitrd 就知道了! ^_^。 我們還是簡單的介紹一下去!
initrd 建立完成之後,同時核心也處理完畢後,我們就可以使用 grub 來建立選單了!底下繼續瞧一瞧吧! 測試與安裝 grub 如果你的 Linux 主機本來就是使用 grub 作為 loader 的話,那麼你就不需要重新安裝 grub 了, 因為 grub 本來就會主動去讀取設定檔啊!您說是吧!但如果你的 Linux 原來使用的並非 grub , 那麼就需要來安裝啦!如何安裝呢?首先,你必須要使用 grub-install 將一些必要的檔案複製到 /boot/grub 裡面去,你應該這樣做的:
所以說, grub-install 是安裝 grub 相關的檔案 (例如檔案系統定義檔) 到你的裝置上面去等待在開機時被讀取,但還需要設定好設定檔 (menu.lst) 後,再以 grub shell 來安裝 grub 主程式到 MBR 或者是 boot sector 上面去喔!好了,那我們來思考一下想要安裝的資料。
我們已經將設定檔處理完畢,但是你要知道的是,我們並不知道 /dev/hda1 到底有沒有包含 grub 的主程式, 因此我們想要將 grub 主程式再次的安裝到 /dev/hda1 的 boot sector ,也想要重新安裝 grub 到 MBR 上面去。 此時我們就得要使用 grub shell 囉!整個安裝與 grub shell 的動作其實很簡單, 如果您有興趣研究的話,可以使用 info grub 去查閱∼鳥哥這裡僅介紹幾個有用的指令而已。
由於我們最需要安裝的就是那個 stage1 啦!那才是 grub 的主程式嘛!而且設定檔通常與主程式擺在同一個目錄下。 因此我們需要使用 root (hd0,0) 去找到 /boot/grub/stage1 喔!接下來,請用 grub 來進入 grub shell 吧!進入 grub 後,會出現一個『 grub> 』的提示字元啊!
如此一來,就已經將 grub 安裝到 MBR 及 /dev/hda1 的 boot sector 裡面去了! 而且讀取的是 (hd0,0) 裡面的 /grub/menu.lst 那個檔案喔!真是很重要啊!重要到不行! 最後總結一下:
開機前的額外功能修改 事實上,上一個小節設定好之後,你的 grub 就已經在你的 Linux 系統上面了,而且同時存在於 MBR 與 boot sector 當中呢!所以,我們已經可以重新開機來查閱看看啦! 另外,如果你正在進行開機,那麼請注意,我們可以在預設選單 (鳥哥的範例當中是 30 秒) 按下任意鍵, 還可以進行 grub 的『線上編修』功能喔!真是棒啊!先來看看開機畫面吧! 圖 3.5.1、grub 開機畫面示意圖 由於鳥哥將隱藏選單的功能取消了,因此你會直接看到這四個選單,同時會有讀秒的咚咚在倒數。 選單部分的畫面其實就是 title 後面的文字啦!你現在知道如何修改 title 後面的文字了吧! ^_^。 如果你使用上下鍵去選擇第二 (/dev/hda1 boot sector) 或第三 (MBR loader) 時,會發現同樣的畫面重複出現! 這是因為那兩個是 loader 移交而已嘛!而我們都使用相同的 grub 與相同的 menu.lst 設定檔! 因此這個畫面就會重複出現了!這樣瞭解乎? 另外,如果你再仔細看的話,會發現到上圖中底部還有一些細部的選項,似乎有個 'e' edit 的樣子! 沒錯∼ grub 支援線上編修指令喔!這是個很有用的功能!假如剛剛你將 menu.lst 的內容寫錯了,導致出現無法開機的問題時, 我們可以查閱該 title 選單的內容並加以修改喔!舉例來說,我想要知道第一個選單的實際內容時,將反白光棒移動到第一個選單, 再按下 'e' 會進入如下畫面: 圖 3.5.2、grub 單一選單內容 哈哈!這不就是我們在 menu.lst 裡面設定的東西嗎?沒錯!此時你還可以繼續進一步修改喔! 注意看到上圖最底下的說明,你還可以使用:
我們說過, grub 是可以直接使用核心檔案來開機的,所以,如果您很清楚的知道你的根目錄 (/) 在那個 partition ,而且知道你的核心檔案檔名 (通常都會有個 /boot/vmlinuz 連結到正確的檔名), 那麼直接在圖三的畫面當中,以上述的 o, d, e 三個按鍵來編修,成為類似底下這樣: 圖 3.5.3、grub edit 的線上編修功能 按下 [Enter] 按鍵後,然後輸入 b 來 boot ,就可以開機啦!所以說,萬一你的 /boot/grub/menu.lst 設定錯誤,或者是因為安裝的緣故,或者是因為核心檔案的緣故,導致無法順利開機時,記得啊,可以在 grub 的選單部分, 使用 grub shell 的方式去查詢 (find) 或者是直接指定核心檔案,就能夠開機啦! ^_^ 另外,很多時候我們的 grub 可能會發生錯誤,導致『連 grub 都無法啟動』,那麼根本就無法使用 grub 的線上編修功能嘛!怎麼辦?沒關係啊!我們可以利用具有 grub 開機的 CD 來開機, 然後再以 CD 的 grub 的線上編修,嘿嘿!同樣可以使用硬碟上面的核心檔案來開機啦!很好玩吧! ^_^ 關於核心功能當中的 vga 設定 事實上,你的 tty1~tty6 除了 80x24 的解析度外,還能夠有其他解析度的支援喔!但前提之下是你的核心必須支援 FRAMEBUFFER_CONSOLE 這個核心功能選項才行。如何確定有沒有支援呢?你可以查閱 /boot/config-2.6.18-92.el5 這個檔案,然後這樣搜尋:
那麼如何調整 tty1 ~ tty6 終端機的解析度呢?先參考底下的表格再說 (此為十進位數值):
假設你想要將你的終端機螢幕解析度調整到 1024x768 ,且色彩深度為 15bit 色的時候,就得要指定 vga=790 那個數字! 舉例來說,鳥哥的 tty1 就想要這樣的解析度時,你可以這樣做:
重新開機並選擇此選單進入 Linux,你跑到 tty1 去看看,嘿嘿!就已經是 1024x768 的解析度囉! 只是字會變的很小,但是畫面的範圍會加大就是了。不過,某些版本支援的是 16 進位制,所以還需要修改一下格式呢! 一般使用上表當中的值應該就可以了。不過,由於不同的作業系統與硬體可能會有不一樣的情況,因此, 上面的值不見得一定可以在您的機器上面測試成功,建議您可以分別設定看看哩∼以找出可以使用的值! ^_^ BIOS 無法讀取大硬碟的問題 現今的硬碟容量越來越大,如果你使用舊的主機板來安插大容量硬碟時,可能由於系統 BIOS 或者是其他問題, 導致 BIOS 無法判斷該硬碟的容量,此時你的系統讀取可能會有問題。為什麼呢? 我們在本章一開始的開機流程講過,當進入 Linux 核心功能後,他會主動的再去偵測一下整個系統, 因此 BIOS 捉不到的硬體在 Linux 核心反而可能會可以捉到而正常使用。舉例來說,過去很多朋友常常會發現, 『我的系統使用 DVD 開機安裝時,可以順利的安裝好 Linux ,但是第一次開機時, 螢幕只出現黑壓壓的一片,且出現 grub> 的字樣,而無法進入 Linux 系統中』,這又是怎麼一回事?
更多 grub 錯誤的代碼查詢可以到底下的連結查閱: 現在你知道問題所在啦!那就是 BIOS 無法讀取大容量磁碟內的 kernel 與 initrd 檔案。 那如何解決呢?很簡單啦!就讓 kernel 與 initrd 檔案放置在大硬碟的最前頭,由於 BIOS 至少可以讀到大磁碟的 1024 磁柱內的資料,因此就能夠讀取核心與虛擬檔案系統的檔案囉。那如何讓 kernel 與 initrd 放置到整顆硬碟的最前面呢?簡單的要命吧!就建立 /boot 獨立分割槽,並將 /boot 放置到最前面即可!更多其他的解決方案可參考文後的延伸閱讀(註4) 萬一你已經安裝了 Linux 且發生了上述的問題,那該怎辦?你可以這樣作的:
不過,鳥哥還是建議您可以重新安裝,並且製作出 /boot 這個 partition 啦! ^_^!這也是為啥這次更版中, 鳥哥特別強調要分割出 /boot 這個分割槽的原因啊! 為個別選單加上密碼 想像一個環境,如果你管理的是一間電腦教室,這間電腦教室因為可對外開放,但是你又擔心某些 partition 被學生不小心的弄亂,因此你可能會想要將某些開機選單作個保護。這個時候,為每個選單作個加密的密碼就是個可行的方案啦! 那如何在開機的過程裡面提供密碼保護呢?首先,你必須要建立密碼,而且還需要是加密過後的喔! 否則人家跑到 /boot/grub/menu.lst 不就可以探查到你的開機密碼了?那如何建立加密的密碼呢? 我們可以透過 grub 提供的 md5 編碼來處理的,如下所示:
上面產生的最後一行,由 $ 開始到 . 結束的那行,就是你的密碼經過 md5 編碼過後的咚咚! 將這個密碼複製下來吧!假設我們要將第一個選項加入這個密碼,而第四個選項加入另外的密碼, 那你應該要這樣做:
上表的案例中,我們兩個選單進入的密碼並不相同,可以進行同學的分類啦!不過這樣也造成一個問題, 那就是一定要輸入密碼才能夠進入開機流程,如果你在遠端使用 reboot 重新開機,並且主機前面並沒有任何人的話.... 你的主機並不會主動進入開機程序喔! ^_^ 你必須要注意的是:password 這個項目一定要在 title 底下的第一行。 不過,此項功能還是可能被破解的,因為使用者可以透過編輯模式 (e) 進入選單,並刪除密碼欄位並按下 b 就能夠進行開機流程了!真糟糕!那怎辦?只好透過整體的 password (放在所有的 title 之前) , 然後在 title 底下的第一行設定 lock ,那使用者想要編輯時,也得要輸入密碼才行啊!設定有點像這樣:
那麼重新開機後,畫面會像這樣: 圖 3.8.1、 grub 加密的示意圖 你可以看到最下方僅出現 p 的功能,由於 2, 3, 4 選單並沒有使用 lock ,因此這三個選單使用者還是可以執行開機程序, 但是第一個選單由於有 lock 項目,因此除非你輸入正確的密碼,否則第一個選單是無法被載入執行的。 另外,這個項目也能夠避免你的 menu.lst 在開機的過程中被亂改,是具有保密 menu.lst 的功能啦! 與剛剛的選單密碼功能不同。 開機過程的問題解決 很多時候,我們可能因為做了某些設定,或者是因為不正常關機 (例如未經通知的停電等等) 而導致系統的
filesystem 錯亂,此時,Linux 可能無法順利開機成功,那怎麼辦呢?難道要重灌?當然不需要啦!
進入 run level 1 (單人維護模式) 去處理處理,應該就 OK 的啦!底下我們就來談一談如何處理幾個常見的問題! 忘記 root 密碼的解決之道 大家都知道鳥哥的記憶力不佳,容易忘東忘西的,那如果連 root 的密碼都忘記了,怎麼辦? 其實在 Linux 環境中 root 密碼忘記時還是可以救回來的!只要能夠進入並且掛載 / , 然後重新設定一下 root 的密碼,就救回來啦!這是因為開機流程中,若強制核心進入 runlevel 1 時, 預設是不需要密碼即可取得一個 root 的 shell 來救援的。整個動作有點像這樣:
init 設定檔錯誤 前一個 root 密碼挽救的方法其實可以用在很多地方,唯一一個無法挽救的情況,那就是 /etc/inittab 這個檔案設定錯誤導致的無法開機!根據開機流程,我們知道 runlevel 0~6 都會讀取 /etc/inittab 設定檔, 因此你使用 single mode (runlevel 1) 當然也是要讀取 /etc/inittab 來進行開機的。那既然無法進入單人維護模式, 就表示這題無解囉?非也非也,既然預設的 init 無法執行,那我們就告訴核心不要執行 init ,改呼叫 bash 啊! 可以略過 init 嗎?可以的,同樣在開機進入 grub 後,同樣在 grub edit 的情況下這樣做:
因為我們指定了核心呼叫的第一支程式 (init) 變成 /bin/bash,因此 /sbin/init 就不會被執行。 又根據開機流程的說明,我們知道此時雖然可以利用 root 取得 bash 來工作,但此時 (1)除了根目錄外,其他的目錄都沒有被掛載; (2)根目錄被掛載成為唯讀狀態。因此我們還需要進行一些動作才行!如下所示: 圖 4.2.1、 略過 init 的程序,直接進入 bash shell 鳥哥僅下達兩個指令,『 mount -o remount,rw / 』用途是將根目錄重新掛載成為可讀寫,至於『 mount -a 』則是參考 /etc/fstab 的內容重新掛載檔案系統! 此時你又可以開機進行救援的工作了!只是救援完畢後,你得要使用『 reboot 』重新開機一次才行! BIOS 磁碟對應的問題 (device.map) 由於目前硬碟很便宜啊,所以很多朋友就想說:『那我能不能將 Windows 安裝在 /dev/hda 而 Linux 安裝在 /dev/hdb , 然後調整 BIOS 的開機裝置順序,如此則兩套系統各有各的 loader 安裝在個別硬碟的 MBR 當中了!』。 這個想法非常好,如此一來兩者就不會互相干擾,因為每顆磁碟的 MBR 個別有不同作業系統的 loader 嘛! 問題是,grub 對磁碟的裝置代號使用的是偵測到的順序啊! 也就是說,你調整了 BIOS 磁碟開機順序後,你的 menu.lst 內的裝置代號就可能會對應到錯誤的磁碟上了!啊!真想哭! 沒關係的,我們可以透過 /boot/grub/device.map 這個檔案來寫死每個裝置對 grub 磁碟代號的對應喔! 舉例來說,鳥哥的這個檔案內容如下:
如果你不清楚如何處理的話,也可以利用 grub-install 的功能喔!例如:
這樣 device.map 就會主動的被更新了!這樣瞭解乎? 因檔案系統錯誤而無法開機 如果因為設定錯誤導致無法開機時,要怎麼辦啊?這就更簡單了!最容易出錯的設定而導致無法順利開機的步驟,通常就是 /etc/fstab 這個檔案了,尤其是使用者在實作 Quota 時,最容易寫錯參數, 又沒有經過 mount -a 來測試掛載,就立刻直接重新開機,真要命!無法開機成功怎麼辦? 這種情況的問題大多如下面的畫面所示: 圖 4.4.1、 檔案系統錯誤的示意圖 看到最後兩行,他說可以輸入 root 的密碼繼續加以救援喔!那請輸入 root 的密碼來取得 bash 並以 mount -o remount,rw / 將根目錄掛載成可讀寫後,繼續處理吧!其實會造成上述畫面可能的原因除了 /etc/fstab 編輯錯誤之外,如果你曾經不正常關機後,也可能導致檔案系統不一致 (Inconsistent) 的情況, 也有可能會出現相同的問題啊!如果是磁區錯亂的情況,請看到上圖中的第二行處, fsck 告知其實是 /dev/md0 出錯, 此時你就應該要利用 fsck 去檢測 /dev/md0 才是!等到系統發現錯誤,並且出現『clear [Y/N]』時,輸入『 y 』吧! 這個 fsck 的過程可能會很長,而且如果你的 partition 上面的 filesystem 有過多的資料損毀時, 即使 fsck 完成後,可能因為傷到系統槽,導致某些關鍵系統檔案資料的損毀,那麼依舊是無法進入 Linux 的。此時,就好就是將系統當中的重要資料複製出來,然後重新安裝,並且檢驗一下, 是否實體硬碟有損傷的現象才好!不過一般來說,不太可能會這樣啦∼ 通常都是 fsck 處理完畢後,就能夠順利再次進入 Linux 了。 利用 chroot 切換到另一顆硬碟工作 仔細檢查一下,你的 Linux 裡面應該會有一個名為 chroot 的指令才對!這是啥? 這是『 change root directory 』的意思啦!意思就是說,可以暫時將根目錄移動到某個目錄下, 然後去處理某個問題,最後再離開該 root 而回到原本的系統當中。 舉例來說,補習班中心最容易有兩三個 Linux 系統在同一個主機上面,假設我的第一個 Linux 無法進入了,那麼我可以使用第二個 Linux 開機,然後在第二個 Linux 系統下將第一個 Linux 掛載起來, 最後用 chroot 變換到第一個 Linux ,就能夠進入到第一個 Linux 的環境當中去處理工作了。 你同樣也可以將你的 Linux 硬碟拔到另一個 Linux 主機上面去,然後用這個 chroot 來切換, 以處理你的硬碟問題啊!那怎麼做啊?粉簡單啦!
重點回顧
本章習題 ( 要看答案請將滑鼠移動到『答:』底下的空白處,按下左鍵圈選空白處即可察看 )
簡答題部分:
參考資料與延伸閱讀
2003/02/10:第一次完成 2005/09/19:將舊的文章移動到 此處 。 2005/09/26:將 核心編譯 一文訂為進階篇,不一定要學啦!但是核心模組不可不題,所以,新增一小節! 2005/09/28:終於給他完成去!好累∼ 2005/10/09:加上參考文獻資料,以及修改一些些 kernel 開機時, grub 的 vga 設定值的解說。 2005/11/09:加上了關於較大硬碟所產生的困擾! 2006/08/21:MBR 應該只有 512 bytes ,結果誤植為 512 Kbytes ,抱歉! 2007/06/27:新增 initrd 的說明,請參考這裡。 2009/04/09:將舊的基於 FC4 的文章移動到此處。 2009/04/10:取消了 LILO 的 boot loader 說明!畢竟這玩意兒已經退流行!所以不再強調!有需要請查詢此處。 2009/04/30:修訂完畢,加強 init=/bin/bash 的說明,以及 grub 的密碼管理! 2009/09/14:加入情境模擬,並根據討論區 linuxfans 兄的建議,修改了一些地方!詳情請參考討論區建議! |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||