作者: Tom Fawcett ( fawcett+BH@croftj.net)
譯者: 朱漢農
v4.0, APRil 2000, 翻譯日期: 27 July 2000
--------------------------------------------------------------------------------
本文描述如何設計與建造你自己的 linux boot/root 磁片。這些磁片能用來當做救援磁片 (rescue disks) ,或是能用來測試新系統元件 (components) 。在企圖建造你自己的 bootdisk 之前,你應該要相當熟悉系統管理工作。如果你只是想要一張緊急時使用的救援磁片,請參考 Pre-made bootdisks 。
--------------------------------------------------------------------------------
1. 前言 -- Preface
1.1 版本注意事項 -- Version notes
1.2 尚未完成的事
1.3 回應與感謝 -- Feedback and credits
1.4 散布政策 -- Distribution policy
2. 簡介 -- Introduction
3. Bootdisks與開機流程 -- Bootdisks and the boot process
3.1 開機流程 -- The boot process
3.2 磁碟類型 -- Disk types
4. 建立一個root filesystem -- Building a root filesystem
4.1 概觀 -- Overview
4.2 制作 filesystem -- Creating the filesystem
4.3 移植檔案系統 -- Populating the filesystem
4.4 對 PAM 與 NSS 的提供 -- Providing for PAM and NSS
4.5 模組 -- Modules
4.6 一些最後的細節 -- Some final details
4.7 Wrapping it up
5. 選擇一個 kernel -- Choosing a kernel
6. 把它們放在一起:制作磁片(組) -- Putting them together: Making the diskette(s)
6.1 用 LILO 傳送 kernel -- Transferring the kernel with LILO
6.2 不使用 LILO 來傳送 kernel -- Transferring the kernel without LILO
6.3 設定ramdisk -- Setting the ramdisk Word
6.4 傳送root filesystem -- Transferring the root filesystem
7. 問題解決 -- Troubleshooting, or The Agony of Defeat
8. 其它各種主題 -- Miscellaneous topics
8.1 減少 root filesystem 的 size -- Reducing root filesystem size
8.2 Non-ramdisk root filesystems
8.3 建造一張工具磁片 -- Building a utility disk
9. How the pros do it
10. 常見問題 (FAQ) 列表 -- Frequently Asked Question (FAQ) list
Appendix
11. 資源與指示 -- Resources and pointers
11.1 預先做好的 Bootdisks -- Pre-made Bootdisks
11.2 救援套件 -- Rescue packages
11.3 LILO -- the Linux loader
11.4 Linux FAQ 與 HOWTOs
11.5 Ramdisk使用方法 -- Ramdisk usage
11.6 Linux開機流程 -- The Linux boot process
12. LILO boot error codes
13. Root filesystem 列表樣本 -- Sample root filesystem listings
14. 工具程式磁片 (utility disk) 目錄列表樣本 -- Sample utility disk directory listing
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
1. 前言 -- Preface
這份文件可能已經過期了。 如果標題頁上的日期距今已超過 6 個月,那麼請查閱 Bootdisk-HOWTO homepage 看看是否已有較新的版本。
雖然本文以 text 格式也是可以閱讀,但是因為印刷符號的關系, 最好 還是以 Postscript (.ps) 、 PDF 或 HTML 的格式來閱讀。
1.1 版本注意事項 -- Version notes
Graham Chapman 是原本 Bootdisk-HOWTO 的作者,他一直提供支援到 version 3.1 。 Tom Fawcett 大約是在 kernel v2 問市時成為合作作者。他是本文目前的維護者。
文中資訊是給在 Intel 平臺上運作的 Linux 使用。其中許多資訊也許能應用在其它平臺的 Linux ,但是我們并沒有嘗試在其它平臺制作 bootdisk ,也沒有相關的資訊。如果你有在其它平臺上制作 bootdisk 的經驗,請與我們聯絡。
1.2 尚未完成的事
有任何自愿者嗎 ?
請描述 (或是鏈結到另一份有敘述的文件)如何制作其它可開機的類磁片物品,諸如 CDROMs, ZIP disks 與 LS110 disks 。
請描述如何處理巨大的 libc.so 共享函式庫。基本上可選擇獲取較舊、較小的函式庫,或是刪減現有的函式庫。
重新分析 distribution bootdisks 與更新 "How the Pros do it" 這一節。
刪減敘述關於如何升級現有 distribution bootdisks 的章節。 This is usually more trouble than it's worth.
重寫 / 潤飾 Troubleshooting 這一節。
1.3 回應與感謝 -- Feedback and credits
我接受任何關於本文內容之回應,無論是好是壞。我/我們 已力求這份文件內的指令與資訊是正確而可靠的。如果你發現任何錯誤或遺漏,請讓我知道。在撰寫時, 請指出你所參考的文件之版本號碼 。
我們感謝許多協助修正與給予建議之人。他們的貢獻使得本文比我們自己獨立完成它時還來得更好。
請各位利用上述的 email 地址,給予作者你的批評、指正與疑問。我不介意嘗試回答任何問題,但是如果你有特定問題是關於你的 bootdisk 不能運作,那麼請先閱讀 Troubleshooting 。
1.4 散布政策 -- Distribution policy
Copyright ? 1995,1996,1997,1998,1999,2000 by Tom Fawcett and Graham Chapman. 本文可以在 Linux Documentation Project License 的條件下流通。如果你未能拿到此 license ,請與作者聯絡。
本文是一份免費文件。我們發行它是希望它能有助於你,但是 不能給你任何保證 ;本文也沒有 具有商業能力 或 適合特定用途 的保證。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
2. 簡介 -- Introduction
Linux 開機磁片 (boot disks) 在很多情況下是很有用的,諸如
測試一個新的核心 (kernel)。
從磁碟錯誤中復原 (這類錯誤從遺失開機磁區到磁碟讀寫頭毀損都有可能) 。
修復一個癱瘓 (disabled) 的系統
安全地升級臨界共用 (critical) 的系統檔案 (諸如 libc.so) 。
有好幾種獲得 boot disks 的方法:
使用發行套件 (distribution) 像是 Slackware 所提供的。它至少能讓你開機。
使用救援套件 (package) 建造用來做為救援磁片的磁片。
學習每一種 disk 運作系統時所需的東西,然後自己制作。
有些人選擇最後一種方法,如此他們能靠自己動手做。這樣子,如果某處發生問題,就能找出辦法去解決問題。此外也可以學到很多有關 Linux 如何運作的知識。
本文假設讀者已熟悉基本的 Linux 系統管理觀念。舉例來說,你應該知道有關目錄、 filesystems 與軟碟片的議題。你也應該知道如何使用 mount 與 df 。你還應該知道 /etc/passwd 與 fstab 這兩個檔案的用途以及它們看起來像什麼。最後,你應該知道 HOWTO 文件內大部分的指令,都要以 root 的身份來執行。
剛開始制作你自己的 bootdisk 是很復雜的。如果你未曾讀過 Linux FAQ 與相關文件,諸如 Linux Installation HOWTO 與 Linux Installation Guide ,那麼你不應該嘗試建造開機磁片。如果你只需要緊急時用的 bootdisk ,下載一個別人事先完成的 bootdisk 拿來用會 更 為容易。請參考下面的 Pre-made bootdisks 以得知在哪里可以找到這些東西。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Bootdisks與開機流程 -- Bootdisks and the boot process
bootdisk 基本上是放在軟碟片內的一個小型而自足的 Linux 系統。它必須執行許多和完整又 full-size 的 Linux 系統相同的功能。在建造 bootdisk 之前,你應該了解基本的 Linux 開機流程。我們在此只做基本的介紹,但已足夠讓你了解本文之後的內容。很多細節與替代選項已被省略。
3.1 開機流程 -- The boot process
所有 PC 系統開始開機流程都是藉由執行 ROM (明確地說,就是 BIOS) 中的程式,從開機磁碟機的第 0 磁區、第 0 磁柱載入可供開機的磁區。開機磁碟機通常是第一臺軟碟機 (如 DOS 的 A槽 與 Linux 的 /dev/fd0)。接著 BIOS 會嘗試執行這個磁區。在大部分可開機的 disks 上,第 0 磁區、第 0 磁柱包含以下兩者之一:
開機載入程式 (boot loader ,如 LILO)的程式碼,它會找出 kernel 所在位置,接著載入并執行它以啟動開機程序。
一個作業系統 kernel 的開頭 (start) ,諸如 Linux 。
如果一個 Linux kernel 已利用 raw-copied 的方式置入一張磁片內,那麼這張磁片的第一個磁區就是 Linux kernel 本身的第一個磁區。這個磁區將從開機設備載入 kernel 的剩馀部分以繼續開機流程。
一旦 kernel 載入完畢,一些基本設備也完成初始化 (initialization) 。然後系統將嘗試從某個設備載入以及掛上 (mount) root filesystem 。所謂的 root filesystem 只是一個被掛上當作 ``/'' 目錄的 filesystem 。 kernel 必須被告知可從哪里找到此 root filesystem ;如果 kernel 在那里找不到一個可載入的影像檔 (image) ,系統就會停止運作 (halt) 。
在某些開機情況下 -- 常常是從軟碟片開機 -- root filesystem 會被載入到 ramdisk 中,也就是被系統所存取的 RAM ,如同系統存取磁碟一般。為何系統會載入到 ramdisk 的理由有二。第一, RAM 是幾個比軟碟片快的有序磁性體,所以系統在其上運作較快; 第二, kernel 可以從軟碟片載入一個 壓縮的filesystem 并且在解壓縮後放到 ramdisk 上,如此可讓更多的檔案儲存在軟碟片上。
一旦 root filesystem 被載入并掛上,你會看到一行訊息像:
VFS: Mounted root (ext2 filesystem) readonly.
此時系統會在 root filesystem 上找到 init 程式 ( 在 /bin or /sbin) 并執行它。 init 讀取它的組態設定檔 (configuration file) /etc/inittab ,找出檔中標明 sysinit 的一行,并執行被指名的script。這個 sysinit script 通常類似 /etc/rc 或 /etc/init.d/boot 這兩個檔。這個 script 是一組建立基本系統服務的 shell 指令,諸如:
對所有磁碟執行 fsck,
載入必備的核心模組 (modules),
啟動 swapping,
進行網路初始化,
將指定在 fstab 內的磁碟掛上。
這個 script 常會啟動其它各種不同的 scripts 執行模組的 (modular) 初始化。舉例來說,在一般的 SysVinit 架構下, /etc/rc.d/ 這個目錄包含一個復雜的子目錄架構,其中的檔案指出如何啟動與關閉大部分的系統服務。然而,在一張 bootdisk 上,這樣的 sysinit script 常常是非常簡單的。
當 sysinit script 結束後,控制權回到 init 上,接著進入 預設的runlevel ,此預設的 runlevel 以 initdefault 這個關鍵字被指定在 inittab 內。此 runlevel line 通常指定一個像 getty 的程式,這個程式負責處理 console 與 ttys 之間的通訊。事實上,就是 getty 程式在螢幕上印出熟悉的 ``login:'' 提示。 getty 程式并轉而呼叫 login 程式以處理 login 是否有效,并於之後建立 user sessions 。
3.2 磁碟類型 -- Disk types
如果你已了解基本的開機流程,那麼我們現在可以定義所涉及到之各種不同類型的磁碟。我們將磁碟分類成四種。本文與在此討論所稱之 ``磁碟 (disk)'' 除非有特別聲明,否則都是指軟碟片,雖然絕大部分的討論也同樣可應用在硬碟上。
boot
一張包含可被啟動之 kernel 的磁片。這張磁片被用來啟動 kernel ,接著這個 kernel 會載入在另一張磁片上的 root file system 。在 bootdisk 上的 kernel 通常必須被告知到哪去找它的 root filesystem 。
bootdisk 常會從另一張磁片載入一個 root filesystem ,但是相反地, bootdisk 也有可能被設定成載入硬碟的 root filesystem 。一般在測試新 kernel 時會這樣做 (事實上, ``make zdisk'' 會自動地從 kernel 的原始碼制造出這樣的一張 bootdisk 。
root
在其 filesystem 上包含運作 Linux 系統必備檔案的一張磁片。這張磁片不一定有 kernel 或 boot loader 。
一旦 kernel 被啟動後, root disk 就可以獨立於其它磁片來運作系統。通常 root disk 的內容會被自動地 copy 到 RAM 而成為 ramdisk 。這使得 root disk 的存取變得更為快速,而且可釋放一臺軟碟機給工具程式磁片 (utility disk)。
boot/root
一張同時包含 kernel 與 root filesystem 的磁片。換句話說,這張磁片包含不用硬碟而能啟動與運作 Linux 系統之所有必備項目。這種磁片的優點在於簡單輕便 -- 每一項必備的東西都放在同一張磁片上。然而,隨著檔案 size 的逐漸增加,讓所有東西都存在同一張磁片上就越顯困難,甚至利用壓縮也一樣。
utility
一張包含 filesystem 的磁片,但是并不是要掛上做為 root file system 來使用。這張磁片可視為額外的資料片 (data disk) 。你可以利用這種磁片把原本過多而不能放在 root disk 上的工具程式放在其上。
一般而言,當我們提及 ``建造一張 bootdisk'' 時,是指造出 boot ( kernel ) 與 root (files) 這兩個部分。這兩個部分不是放在一起 (一張單張的boot/root disk) ,就是兩張分開的磁片 (boot + root disks) 。對救援磁片而言最具彈性之做法,可能是使用兩張分開的 boot 與 root 磁片,再加上一張或多張的 utility diskettes 以處理多出來的東西。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
4. 建立一個root filesystem -- Building a root filesystem
造出 root filesystem 涉及選擇能讓系統正常運作所必備的檔案。在這一節中,我們將敘述如何建造一個 壓縮的 root filesystem 。在磁片上建造一個直接掛上做為根目錄 (root) 之未經壓縮的 filesystem 是較不普遍的觀念;這個替代方案敘述在 Non-ramdisk Root Filesystem 這一節中。
4.1 概觀 -- Overview
root filesystem 必須包含支援完整 Linux 系統運作所需的每一個項目。為了能夠達成這個目的,這張磁片必須包括能讓 Linux 系統運作最起碼 (minimum) 的需求:
基本的檔案系統架構,
最起碼的目錄: /dev, /proc, /bin, /etc, /lib, /usr, /tmp,
基本的工具程式: sh, ls, cp, mv, etc.,
最起碼的組態設定檔: rc, inittab, fstab, etc.,
設備檔: /dev/hd*, /dev/tty*, /dev/fd0, etc.,
Runtime 函式庫以提供工具程式所使用之基本功能 (functions) 。
當然,任何系統只有在你能於其上執行某些東西時才會顯得有用,而一張 root 磁片通常只有在你能做到以下事情時才會顯得有用:
檢查另一臺磁碟機的 file system ,舉例來說,檢查你硬碟上的 root file system ,你必須能夠從另一臺磁碟機啟動 Linux ,例如你可以用一張 root 磁片辦到這件事。然後你可以在你原本的 root 磁碟機未被掛上時,對其執行 fsck 。
使用檔案 (archive) 與壓縮工具程式,諸如 cpio, tar, gzip 與 ftape ,從備份 (backup) 恢復儲存所有或部分你原本 root 磁碟機的資料。
我們將敘述如何建造一個 壓縮的 filesystem ,就是平時被壓縮在磁片上,只有當開機時,才會解壓縮後存入ramdisk 。 用壓縮 filesystem 的方式,你可以在一張標準的 1440K 磁片上放入很多檔案 (大約 6 megabytes) 。因為 filesystem 比磁片大很多,我們不能直接把它建在磁片上。我們必須在其它地方建立它,壓縮它,然後再把它 copy 到磁片上。
4.2 制作 filesystem -- Creating the filesystem
為了建造如此的一個 filesystem ,你需要一個多出而夠大的設備,能夠讓你在壓縮之前存放所有的檔案。你將需要一個能夠存放大約 4 megabytes檔案的設備。有以下幾種選擇:
使用 ramdisk (DEVICE = /dev/ram0)。在這種情況下,記憶體被模擬成一臺磁碟機。 Ramdisk 必須大到能夠存放一個適當大小的 filesystem 。如果你使用 LILO ,請檢查你的組態設定檔 (/etc/lilo.conf) ,找到一行像
RAMDISK = nnn
這行決定可以分配給 ramdisk 的 RAM 之極大值。預設值是 4096K ,這應該是足夠了。你應該不可能嘗試在一臺少於 8MB RAM 的電腦上使用如此的 ramdisk 。 請檢查以確認你有一個設備檔像是 /dev/ram0, /dev/ram 或是 /dev/ramdisk 。如果沒有,請自己以 mknod (major number 1, minor 0)造出 /dev/ram0 。
如果你有一個未使用且夠大的硬碟 partition (差不多幾megabytes大就可以了),就使用它吧。
使用一個 loopback device ,這可以把一個磁碟檔案當做是一臺設備來使用。使用 loopback device 時,你可以在硬碟上造出一個 3 megabyte 的檔案,并於其上建造 filesystem 。 鍵入 man losetup 找尋指令以使用 loopback devices 。如果你沒有 losetup ,你可以從 ftp://ftp.win.tue.nl/pub/linux/utils/util-linux/ 目錄中, util-linux 套件 (package) 內相容版本之 mount 與 unmount 的隨附物中找到它。 如果在你的系統上沒有 loop device 檔 (/dev/loop0, /dev/loop1, etc.),那麼你必須用 ``mknod /dev/loop0 b 7 0'' 自己造出一個。一旦安裝好這些特別的 mount 與 umount 二進位檔,就請在一臺容量夠大的硬碟上造出一個暫存檔 (temporary file)(eg, /tmp/fsfile) 。你可以使用像這樣子的指令:
dd if=/dev/zero of=/tmp/fsfile bs=1k count=nnn
以造出一個 nnn-block 的檔案。 請使用自己的檔名取代以下的 DEVICE 。當你下了 mount 指令,你同時要加上 ``-o loop'' 選項以告知 mount 是使用 loopback device 。 舉例來說:
mount -o loop -t ext2 /tmp/fsfile /mnt
以掛上 loopback device 的方式,把 /tmp/fsfile 掛上 /mnt 這個 mount point 。用 df 指令可讓你看到以上的結果。
在你選擇其中一種方法後,請準備 DEVICE 以:
dd if=/dev/zero of=DEVICE bs=1k count=4096
這行指令送出一堆 0 把DEVICE填滿。用 0 填滿 device 是關鍵的一步,因為 filesystem之後將會被壓縮,所以所有未使用的部分應被用 0 填滿以達到最大的壓縮比。無論何時你從你的 root filesystem 刪除檔案,請記得這個事實。實際上 filesystem 只是釋出 (de-allocate) 這些 blocks , 但是并沒有再把它們填為 0 。如果你執行過很多次刪除與 copy 的動作,你的壓縮 filesystem 最後會比必要的大出很多。
下一步就是造出 filesystem 。 Linux kernel 承認兩種能讓 root disks 自動地被 copy 到 ramdisk 上的 file system 。它們是 minix 與 ext2 ,其中 ext2 是比較受歡迎的。如果使用 ext2 ,你會發現使用 -i 選項指定比預設值更多的 inodes 是有助益的;我們建議用 -i 2000 ,這樣你就不會用完 inodes 。如果不用上述選項,你可以移除許多不必要的 /dev 檔案以節省 inodes 。 mke2fs 預設會造出 360 個 inodes在一張 1.44Mb 的磁片上。我發現在我目前的救援 root 磁片上, 120 個 inodes 是相當足夠了,但是如果你把所有的設備檔都放入 /dev 目錄中,那麼你很容易會超過 360 個inodes 。使用壓縮的 root filesystem 可讓你擁有較大的 filesystem ,同時預設會有更多的 inodes ,但是你仍然必須要不就是減少檔案數量,要不就是增加 inodes 數目。
因此,你所使用的指令看起來會像這樣:
mke2fs -m 0 -i 2000 DEVICE
(如果你使用的是一個 loopback device ,那麼請用你目前所用的磁碟檔案替換掉上面的 DEVICE 。)
mke2fs 指令會自動地偵測可獲得的空間,然後依據偵測對自身進行組態設定。 ``-m 0'' 參數避免保留空間給 root ,因此可提供更多可用的磁碟空間。
下一步,掛上這個 device :
mount -t ext2 DEVICE /mnt
(如果 mount point 并不存在,你必須自行造出一個 mount point /mnt 。) 在剩下的章節中,所有的目的 (destination) 目錄都被假設是相對於 /mnt 。
4.3 移植檔案系統 -- Populating the filesystem
以下是你的 root filesystem 最起碼該有的目錄
此處所呈現之目錄架構僅供 root diskette 使用。真正的 Linux 系統有一套更為復雜且設計良好的架構方法,稱為 Filesystem Hierarchy Standard ,它決定檔案應該如何放置。 :
/dev -- 里面存放設備檔 (Devices) ,為達成 I/O 工作所需
/proc -- Directory stub required by the proc filesystem
/etc -- 里面存放系統組態設定檔
/sbin -- 重要的 (critical) 系統二進位執行檔 (binaries)
/bin -- 被認為是系統一部分的基本二進位執行檔
/lib -- 提供 run-time 支援的共享函式庫
/mnt -- 維護其它磁碟所用的磁碟掛入點 (mount point)
/usr -- 額外的工具程式與應用程式
上述目錄的其中三個在 root filesystem 上會是空的,所以它們只需要用 mkdir 造出來。 /proc 目錄基本上是一個把 proc filesystem 放置於其下的 stub 。 /mnt 與 /usr 這兩個目錄只是在 boot/root 系統運作時所使用的 mount points 。因此再重覆一次,這些目錄只需要被造出來就可以了。
剩下的四個目錄描述於以下各節。
/dev
/dev 目錄包含一群特別的檔案,這些檔案是給系統上所有設備使用的,這樣的 /dev 目錄每個 Linux 系統都一定會有。這個目錄本身是一個普通目錄,可以以一般的方法用 mkdir 造出來。然而,這些特別的檔案必須以特別的方法用 mknod 指令造出來。
但還是有一條捷徑 -- 直接 copy 你現有 /dev 目錄的內容,然後再清除你不想要的設備檔。唯一的要求是 copy 這些特別的設備檔時,要用 -R 選項。這個選項會 copy 整個目錄中的檔案,但是不會 copy 這些檔案的內容。請確定使用 大寫字母 R 。這個指令是:
cp -dpR /dev /mnt
在此我們假設磁片是被掛在 /mnt 底下。 dp 選項 (switches) 確保 symbolic links 是以 links 的方式來 copy ,而不是 copy 鏈結檔所指向的 target file ,同時原本的檔案屬性也被保留,因此保留了檔案的所有權資訊。
如果你想要用高難度技巧完成這個任務,就利用 ls -l 列出你想要的設備檔之 major 與 minor device numbers ,然後再用 mknod 在磁片上造出它們。
無論如何 copy 這些設備檔,還是要檢查任何你所需之設備檔 (device special file) 是否已放入這張救援磁片中。舉例來說, ftape 使用磁帶設備,如果你想要從 bootdisk 存取軟式磁帶機,你就需要 copy 所有有關的設備檔。
請注意,每一個設備檔需要一個 inode ,但 inodes 一直都是稀少的資源,特別是在磁片 filesystems 上。因此,從磁片上的 /dev 目錄移除任何你所不需要的設備檔是有意義的。舉例來說,如果你沒有 SCSI 磁碟,你可以放心地移除所有以 sd 開頭的設備檔。同樣地,如果你并不想使用你的序列埠 (serial port) ,那麼你也可以移除所有以 cua 開頭的設備檔。
請確定從這個目錄放入了以下檔案的: console, kmem, mem, null, ram0 and tty1.
/etc
這個目錄包含了重要的組態設定檔。在大部分的系統上,這些檔案被分為三個群組:
一直都是必備的, e.g. rc, fstab, passwd 。
可能是必備的,但是沒有人能十分確定。
偷跑進來的垃報。
通常可以用以下指令識出哪些是非基本的檔案:
ls -ltru
這個指令將檔案依據上次被存取的日期,以先早後晚 (reverse) 的順序列出,所以如果有任何檔案不會被存取,那麼它們就可以從 root 磁片中刪去。
在我的 root 磁片上,我的組態檔數目已減至 15 個。這可減少我處理以下三種檔案的工作:
我必須為 boot/root 系統進行組態設定的檔案:
rc.d/* -- 系統啟動與改變 run level 的 scripts
fstab -- 要被掛上的 file systems 清單
inittab -- 給 init process 的參數,於開機時啟動的第一個 process 。
我們應該為 boot/root 系統整理的檔案:
passwd -- 重要的使用者、 home 目錄等其它項目的清單。
group -- 使用者群組。
shadow -- 使用者的密碼。你可能沒有這個檔。
termcap -- the terminal capability database.
如果系統安全 (security) 對你很重要,那麼 passwd 與 shadow 應該被刪減,以避免將使用者密碼 copy 出系統,這樣當你從磁片開機時,不想要的 logins 會被拒絕。 請確定 passwd 至少包含了 root 。如果你要讓其他的使用者 login ,請確定他們的 home 目錄與 shells 都存在。 termcap ,終端機資料庫,一般而言有幾百個 kilobytes 。你 boot/root 磁片的版本應該被刪減到只包含你所使用的終端機,這通常就是 linux 或 linux-console 項目 (entry) 。
The rest. They work at the moment, so I leave them alone.
Out of this, 我實際上只必須設定兩個檔,而它們所應包含的項目驚人地少。
rc 應該包含:
#!/bin/sh
/bin/mount -av
/bin/hostname Kangaroo
請確定上述的目錄都是正確的。你并不需要真地去執行 hostname -- 如果你執行只是讓系統比較好看 (譯注:如此系統會有個名字) 。
fstab 應該至少要包含:
/dev/ram0 / ext2 defaults
/dev/fd0 / ext2 defaults
/proc /proc proc defaults
你可以從你現存的 fstab copy 你想要的項目,但是你并不應該自動地掛上你硬碟任何的 partitions ;請對這些項目使用 noauto 關鍵字 (譯注:用 noauto 代替 default ) 。當使用 bootdisk 時,你的硬碟可能是早已損壞或掛了。
你的 inittab 應該被改變,以使其中 sysinit 這行能執行 rc 或無論什麼將被執行的基本開機 script 。同時,如果你想要確保不可從序列埠 login ,請在所有行尾包括 ttys 或 ttyS 的 getty 項目前加上「#」符號 (comment out) 。請保留 tty 埠以讓你可以在 console 前 login 。
一個最起碼的 inittab 檔看起來樣這樣:
id:2:initdefault:
si::sysinit:/etc/rc
1:2345:respawn:/sbin/getty 9600 tty1
2:23:respawn:/sbin/getty 9600 tty2
inittab 檔定義了系統在各種不同的情況中將執行什麼項目,包括 startup 、切換至多使用者模式等等。請仔細地檢查在 inittab 中被提及的檔案名稱 (filenames) ;如果 init 不能找到所提及的程式,那麼 bootdisk 將會停止運作,而你甚至不會得到錯誤訊息。
請注意,某些程式不能被移到其它地方,因為其它程式已在撰寫時,就把它們的檔案位置寫死了 (hardcode) 。舉例來說在我的系統上, /etc/shutdown 已把 /etc/reboot 的位置寫死在其中。如果我移動了 reboot 到 /bin/reboot,然後下達一個 shutdown 指令,將會因為找不到 reboot 檔而發生錯誤。
剩下來的,就是 copy 在你 /etc 目錄中的所有文字檔 (text files) ,再加上在你 /etc 目錄中,你無法確定你需不需要的所有可執行檔。需要指示 (guide) 者,請參考在 Sample roodisk directory listings 的樣本清單。也許只要 copy 這些檔案就足夠了,但是系統差異會有很大的影響,所以你無法確定你系統上相同的檔案組合,就一定等於清單中的檔案。唯一確定的方法就是從 inittab 著手,并找出需要什麼。
現在大部分的系統使用 /etc/rc.d/ 目錄,其中包含給不同 run levels 的shell scripts 。最起碼會有一個單一的 rc script,但是僅從你現存的系統 copy inittab 與 /etc/rc.d 這兩個目錄,然後刪減 rc.d 目錄中的 shell scripts 以移除和磁片系統環境無關的 processing ,會是較為簡單的做法。
/bin 與 /sbin
/bin 目錄是一個放置為了執行基本作業 (Operations) 而所需之額外工具程式的方便好地方,這些工具程式諸如 ls, mv, cat 與 dd 。 bin/ 與 /sbin 這兩個目錄的檔案清單□例請見 Sample rootdisk directory listings 。但□例中并沒有包括任何從備份復原時所需之工具程式,諸如 cpio, tar 與 gzip 。這是因為我把這些東西放在另一張 (separate) 工具程式磁片上,以節省 boot/root 磁片的空間。一旦 boot/root 磁片被開機啟動,就會被 copy 到 ramdisk 并釋放軟碟機,讓軟碟機能掛上另一張磁片,就是工具程式片。我通常把它掛上當做 /usr 。
工具程式磁片 (utility diskette) 的制作被描述在下面 Building a utility disk 這節。保留一份相同版本之備份用工具程式的copy是比較好的,這個備份用工具程式被用來制作備份,如此你就不用浪費時間在嘗試安裝不能讀取你備份磁帶的版本。
請確定你包括了以下程式: init, getty 或相等的程式, login, mount, 某種可以執行你rc scripts 的 shell, 以及一個從 sh 指向這個 shell 的 link 。
/lib
在 /lib 中,你要放入必要的共享函式庫 (libraries) 與載入程式 (loaders) 。如果無法在你的 /lib 目錄中找到必要的函式庫,那麼系統將不能夠開機。如果你很幸運,你可能會看到告訴你為什麼會發生如此情況的錯誤訊息。
近來每一個程式至少都要求 libc 函式庫, libc.so.N ,其中 N 是目前版本的編號。請檢查你的 /lib 目錄。 Libc.so.N 通常是一個 symlink ,它指向一個具有完整版本編號的檔名:
% ls -l /lib/libc*
-rwxr-xr-x 1 root root 4016683 Apr 16 18:48 libc-2.1.1.so*
lrwxrwxrwx 1 root root 13 Apr 10 12:25 libc.so.6 -> libc-2.1.1.so*
在這個情況下,你會想要 libc-2.1.1.so 。為了找到其它函式庫,你應該要看過所有你打算包括的二進位檔,并且用 ldd 指令檢查它們的相依性。舉例來說:
% ldd /sbin/mke2fs
libext2fs.so.2 => /lib/libext2fs.so.2 (0x40014000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x40026000)
libuuid.so.1 => /lib/libuuid.so.1 (0x40028000)
libc.so.6 => /lib/libc.so.6 (0x4002c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
在右手邊的每一個檔案是一定要有的。有些檔案可能是一個 symbolic link 。
請注意某些函式庫 相當地大 ,而且并不能輕易地配合你的 root filesystem 。舉例來說,上述的 libc.so 大約有 4 megabytes 。因此,在你 copy 它們到你 root filesystem 的同時,你可能需要除去一些函式庫。請看 Reducing root filesystem size 這一節以了解 instructions 。
在 /lib 內,你也必須包括一個 loader 供這些函式庫使用。這個 loader 不是 ld.so (給 A.OUT 函式庫使用),就是 ld-linux.so (給 ELF 函式庫使用)。較新版的 ldd 會如同上述的例子,正確地告訴你需要哪一種 loader ,然而舊版的就不會。如果你并不確定你需要哪一種 loader ,就對函式庫執行 file 指令。舉例來說:
% file /lib/libc.so.4.7.2 /lib/libc.so.5.4.33 /lib/libc-2.1.1.so
/lib/libc.so.4.7.2: Linux/i386 demand-paged executable (QMAGIC), stripped
/lib/libc.so.5.4.33: ELF 32-bit LSB shared object, Intel 80386, version 1, stripped
/lib/libc-2.1.1.so: ELF 32-bit LSB shared object, Intel 80386, version 1, not stripped
QMAGIC 指出 4.7.2 版是給 A.OUT 函式庫使用,而 ELF 指出 5.4.33 以及 2.1.1 版是給 ELF 使用。
請 copy 你所需要的指定 loader(s) 到你所建立的 root filesystem 。針對所包括的二進位檔,函式庫與 loaders 應該被 仔細地檢查 。如果 kernel 不能載入所需的函式庫,那麼 kernel 就會在沒有錯誤訊息的情況下停止運作。
4.4 對 PAM 與 NSS 的提供 -- Providing for PAM and NSS
你的系統可能會需要動態地載入未被 ldd 所見的函式庫。如果你沒有提供函式庫給這些項目,那麼你會在登錄 (log in) 或使用你的 bootdisk 時遭遇到困難。
PAM (Pluggable Authentication Modules)
如果你的系統使用 PAM (Pluggable Authentication Modules) ,那麼你必須在你的 bootdisk上為 PAM 做一些預備。簡而言之, PAM 是一種復雜精密的模組化方法,針對使用者認證以及控制使用者對服務的存取。一個決定你的系統是否使用 PAM 的簡單方法,是對你的 login 可執行檔執行 ldd ;如果輸出包括 libpam.so ,你就需要 PAM 。
幸運地,安全性通常并非 bootdisk 所關心的議題,因為任何對機器有實際存取權的人,通常能做任何他們無論如何想做的事。因此,你可以有效地關閉 PAM ,只要在你的 root filesystem 造出一個簡單的 /etc/pam.conf 檔,這個檔看起來像這樣:
--------------------------------------------------------------------------------
OTHER auth optional /lib/security/pam_permit.so
OTHER account optional /lib/security/pam_permit.so
OTHER password optional /lib/security/pam_permit.so
OTHER session optional /lib/security/pam_permit.so
--------------------------------------------------------------------------------
請記得也 copy /lib/security/pam_permit.so 這個檔到你的 root filesystem 。這個函式庫只有大約 8K ,因此它只占用極小量的 overhead 。
請記得這個組態設定允許任何人對這臺機器上的檔案以及服務有完整的存取權。如果你因某種理由而在乎你 bootdisk 的安全性,那麼你就必須 copy 一些或是全部你硬碟的 PAM setup 到你的 root filesystem 。請確定曾仔細地讀過 PAM 文件,并且 copy 任何在 /lib/security 中所需要的函式庫到你的 root filesystem 上。
你同時必須包含 /lib/libpam.so 到你的 bootdisk 上。但是你已知這件事,因為你已對 /bin/login 執行過 ldd ,這動作顯示了其相依性。
NSS (Name Service Switch)
如果你正使用 glibc (aka libc6) ,你就必須為名稱服務 (name switch) 進行預備,否則你會無法 log in 。 /etc/nsswitch.conf 這個檔案控制資料庫對各式服務之搜尋 (lookups) 。如果你并不打算從網路上存取服務 (比如說: DNS或 NIS 搜尋),那麼你只需要準備一個簡單的 nsswitch.conf 檔,這個檔案看起來像這樣:
--------------------------------------------------------------------------------
passwd: files
shadow: files
group: files
hosts: files
services: files
networks: files
protocols: files
rpc: files
ethers: files
netmasks: files
bootparams: files
automount: files
aliases: files
netgroup: files
publickey: files
--------------------------------------------------------------------------------
這樣就指定每一項服務只被 local files 提供。你同時需要包括 /lib/libnss_files.so.X ,在此 X 是 1 的話是指 glibc 2.0 ,而 2 的話是指 glibc 2.1 。這個函式庫將被以動態方式載入以處理檔案搜尋。
如果你打算從你的 bootdisk 存取網路,那麼你會想要制作一個更精巧復雜的 nsswitch.conf 檔。細節請參考 nsswitch man page。最後,請記得你必須為你所指定的每一項 服務 (service) ,把 /lib/libnss_service.so.1 檔放入 bootdisk 中。
4.5 模組 -- Modules
如果你有一個模組化的 kernel ,你必須考量在開機後,你想要從你的 bootdisk 上載入哪一種模組。你可能會想要包括 ftape 與 zftape 模組 (如果你的備份磁帶是floppy tape),以及給 SCSI 設備用的模組 (如果你有 SCSI 設備),也可能是 PPP 或 SLIP 支援的模組 (如果你在緊急情況下想要存取網路)。
這些模組可能會被放在 /lib/modules 。你同時也應該包括 insmod, rmmod 與 lsmod 。根據你是否想要自動地載入模組,你可能也要包括 modprobe, depmod 與 swapout 。如果你使用 kerneld,請與 /etc/conf.modules 一起包括進來。
然而,使用模組的主要優點在於你可以把非關鍵 (non-critical)模組移到 utility disk 上,在需要用到時才載入,這樣在你的 root disk 上會使用比較少的空間。如果你要處理許多不同的設備,這個方法比建立一個內建支援許多設備的巨大 kernel 來得好。
請注意,為了啟動 (boot) 一個壓縮的 ext2 filesystem ,你必須有 ramdisk 與內建 ext2 支援。 它們不能夠以模組的方式被提供。
4.6 一些最後的細節 -- Some final details
某些系統程式,諸如 login ,當 /var/run/utmp 檔與 /var/log 目錄不存在時,會發出警告。所以:
mkdir -p /mnt/var/{log,run{
touch /mnt/var/run/utmp
最後,在你設定 (set up) 完所有你所需的函式庫後,執行 ldconfig 以在 root filesystem上重新制作 (remake) /etc/ld.so.cache 。這個 cache 會告訴 loader 到哪里找到函式庫。要重新制作 ld.so.cache,請下達以下指令:
chdir /mnt; chroot /mnt /sbin/ldconfig
chroot 是必要的,因為 ldconfig 總是會為 root filesystem 重新制作 cache 。
4.7 Wrapping it up
一旦你完成 root filesystem 的建構工作,就 unmount 它,將之 copy 成一個檔案并壓縮它:
umount /mnt
dd if=DEVICE bs=1k | gzip -v9 > rootfs.gz
結束後,你會有一個名為 rootfs.gz 的檔案,這就是你被壓縮過的 root filesystem。你應該檢查它的 size 以確保它能放在一張軟碟片上;如果不行,你就必須回溯并移除一些檔案。 Reducing root filesystem size 這節有一些提示,告訴你有關減少 root filesystem 的 size 。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
5. 選擇一個 kernel -- Choosing a kernel
現在,你已有一個完整的被壓縮過的root filesystem。下一步是要建立或是選擇一個 kernel 。在大部分的情況下, copy 你目前所使用的 kernel 并且從它啟動軟碟片是可能的。然而,會有一些情況,你會希望建立一個獨立的 (separate) kernel 。
理由之一是 size 的考量。如果你正建立一張單一的 boot/root 磁片, kernel 將會是磁片上最大的檔案之一,也因此你必須盡可能地減少 kernel 的 size 。為了減少 kernel size ,請用能支援所想要的系統之必要最起碼的設備來建立 kernel 。這是指丟去你所不想要的每一項。網路功能是可以丟去的好選擇,另外還有當運作你的 boot/root filesystem 時,任何你所不需要的磁碟機與其它設備的支援。如同前述,你的 kernel 必須有 ramdisk 與 ext2 支援內建於其中。
如果你已完成一套最起碼的 (minimum) 設備組合以便於將之放入 kernel 中,那麼接下來你需要開始進行要把什麼加入回來。或許一套 boot/root 磁片組之最常見用途,是為了要能檢查與回復 (restore) 一個已損毀的 root file system ,而為了達成這個目標,你需要 kernel 的支援。舉例來說,如果你的備份都放在磁帶上,并使用 Ftape 存取你的磁帶機,那麼,如果你失去了你目前的root drive與含有 Ftape 的 drive ,你將不能夠從你的備份磁帶進行回復儲存。你將必須重新安裝 Linux ,下載并重裝 ftape ,然後試著讀取你的備份。
此處的要點是,無論你已加入什麼 I/O 支援到你的 kernel 內以支援備份,你同時也應該把它們加入到你的 boot/root kernel 中。
實際建造 kernel 的程序詳述在隨附於 kernel 的文件中。你可以輕易地照著指示進行,所以可以 /usr/src/linux 為起點。如果你在建造 kernel 上有困難,你或許不應該企圖不擇手段地建造 boot/root systems 。請記得用 ``make zImage''壓縮 kernel 。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
6. 把它們放在一起:制作磁片(組) -- Putting them together: Making the diskette(s)
進行到這里,你已經有一個 kernel 與一個壓縮的 root filesystem 。如果你正在制作一張 boot/root 磁片,請檢查它們的 size ,以確定它們都能放在同一張磁片上。如果你正在制作一套兩張磁片的 boot + root 磁片組。請檢查 root filesystem 以確定它能放在一張磁片上。
你應該決定是否使用 LILO 以啟動 bootdisk的 kernel 。替代的方法是直接把 kernel copy 到磁片上,然後不使用 LILO 開機。使用 LILO 的好處在於讓你能夠提供一些參數給 kernel ,這些參數對初始化硬體來說可能是必要的(請檢查你系統上的 /etc/lilo.conf 檔。如果這個檔存在,而且有一行像``append=...'',你可能需要這個特點 (feature))。使用 LILO 的缺點在於建造 bootdisk 變得更為復雜,并且占用稍嫌較多的空間。你將必須設定一個小型而獨立的 filesystem ,我們稱之為 kernel filesystem,在其中你傳送 kernel 以及一些 LILO 所需的其它檔案。
如果你將要使用 LILO ,請繼續讀下去;如果你要直接傳送 kernel ,先跳過此,直接到 Without using LILO 這一節。
6.1 用 LILO 傳送 kernel -- Transferring the kernel with LILO
你所必須做的第一件事是為 LILO 編寫一個小型的組態檔。這個檔看起來像這樣:
--------------------------------------------------------------------------------
boot =/dev/fd0
install =/boot/boot.b
map =/boot/map
read-write
backup =/dev/null
compact
image =KERNEL
label =Bootdisk
root =/dev/fd0
--------------------------------------------------------------------------------
關於這些參數的說明請看 LILO's user documentation 。你或許也會想從你硬碟上的 /etc/lilo.conf 檔,加入一行 append=... 到這個組態檔中。
把這個組態檔存成 bdlilo.conf 。
現在你必須制作一個小型的檔案系統,我們稱之為 kernel filesystem ,有別於 root filesystem 。
首先,指出這個 filesystem 應該會有多大。用 blocks 計算你 kernel 的 size (這個 size 用 ``ls -l KERNEL'' 顯示出來,是被 1024 所除并強迫進位),然後加 50 。這個 50 blocks 是估計的空間,為 inodes 與其它檔案所需。如果你想要,你可以精確地計算這個數字,或是就用 50 就好了。如果你正在制作兩張磁片的磁片組,你會高估這個空間,因為無論如何第一張磁片只給 kernel 使用。我們稱這個數字會 KERNEL_BLOCKS 。
請把軟碟片放入軟碟機 (為求簡便,我們假設是 /dev/fd0),然後在其上制作 ext2 kernel filesystem 。
mke2fs -i 8192 -m 0 /dev/fd0 KERNEL_BLOCKS
``-i 8192'' 指定我們想要每 8192 bytes 一個 node 。接下來, mount 這個 filesystem ,移除 lost+found 目錄,然後為 LILO 造出 dev 與 boot 這兩個目錄:
mount /dev/fd0 /mnt
rm -rf /mnt/lost+found
mkdir /mnt/{boot,dev}
再來,造出設備檔 /dev/null 與 /dev/fd0 。不用尋找設備號碼,你只要從你的硬碟上用 -R copy它們:
cp -R /dev/{null,fd0} /mnt/dev
LILO 需要一份它的 boot loader 的 copy , boot.b ,你可以從你的硬碟得到它。它通常是放在 /boot 目錄內。
cp /boot/boot.b /mnt/boot
最後,隨附你的 kernel , copy 你在上一節所編寫的 LILO 組態檔。它們兩者可以被放在根目錄下。
cp bdlilo.conf KERNEL /mnt
LILO 所需的每一項現在都在 kernel filesystem上,所以你已準備好去執行它。 LILO 的 -r 旗號(flag)被用作安裝 boot loader 在某個其它的 root 上:
lilo -v -C bdlilo.conf -r /mnt
LILO 應該可以在無錯的情況下執行,在此之後,你可以看看你的 kernel filesystem ,應該長得像這樣:
--------------------------------------------------------------------------------
total 361
1 -rw-r--r-- 1 root root 176 Jan 10 07:22 bdlilo.conf
1 drwxr-xr-x 2 root root 1024 Jan 10 07:23 boot/
1 drwxr-xr-x 2 root root 1024 Jan 10 07:22 dev/
358 -rw-r--r-- 1 root root 362707 Jan 10 07:23 vmlinuz
boot:
total 8
4 -rw-r--r-- 1 root root 3708 Jan 10 07:22 boot.b
4 -rw------- 1 root root 3584 Jan 10 07:23 map
dev:
total 0
0 brw-r----- 1 root root 2, 0 Jan 10 07:22 fd0
0 crw-r--r-- 1 root root 1, 3 Jan 10 07:22 null
--------------------------------------------------------------------------------
如果檔案 size 和你自己的 filesystem 有稍微不同,請不用擔心。
現在請把磁片留在軟碟機內,然後前進到 Setting the ramdisk word 這一節。
6.2 不使用 LILO 來傳送 kernel -- Transferring the kernel without LILO
如果你 不 使用LILO,那麼就用 dd 指令來傳送 kernel 給 bootdisk :
% dd if=KERNEL of=/dev/fd0 bs=1k
353+1 records in
353+1 records out
在這個例子中, dd 寫入了 353 個完整記錄(records) + 1個partial record ,所以 kernel 占用了 354 個軟碟片的 blocks 。這個數字稱為 KERNEL_BLOCKS ,請記得它,這個數字要給下一節使用。
最後,請設定 root device 為軟碟片自己,然後再設定 root 要被載入成 read/write :
rdev /dev/fd0 /dev/fd0
rdev -R /dev/fd0 0
在第二個 rdev 指令中,請小心地使用 -R 。
6.3 設定ramdisk -- Setting the ramdisk word
在 kernel image內的是 ramdisk word ,它伴隨其它選項,指定了 root filesystem 應該在哪里被找到。這個 word 會被以 rdev 指令,來進行存取與設定,而它的內容被解釋如下:
bits 0-10: Offset to start of ramdisk, in 1024 byte blocks
bits 11-13: unused
bit 14: Flag indicating that ramdisk is to be loaded
bit 15: Flag indicating to prompt before loading rootfs
如果 bit 15 被設定,在開機時 (boot-up) ,會提示你把一張新的軟碟片放入軟碟機中。這對一套雙磁片的開機磁片組來說是必要的。
依據你是建造一張單一的 boot/root 磁片,還是兩張 "boot + root" 的磁片組,這里會產生兩種情況。
如果你是建造一張單一磁片,壓縮的 root filesystem 會被放置在 kernel 之後,所以 offset 會是第一塊 free block (這個值應該會與 KERNEL_BLOCKS 相等) 。 Bit 14 會被設定為 1 ,而 bit 15 會被設定為 0 。 舉例來說,假設你正建造一張單一磁片,而 root filesystem 將自 block 253 (10進位)開始。那麼, ramdisk word 值應該是 253 (10進位) , bit 14 設為 1 而 bit 15 設為 0 。要計算這個值,你可以簡單地加一加這個 10 進位數字。 253 + (2^14) = 253 + 16384 = 16637 。如果你并不十分了解這個數字從何而來,把這數字放到工程計算機上,然後把它轉換為 2 進位,
如果你建造的是一套雙磁片組,那麼 root filesystem 將自第二張磁片的 block 0 開始,所以 offset 為 0 。 Bit 14 設為 1 而 bit 15 設為 1 。在這個情況下, 10 進位值是 2^14 + 2^15 = 49152 。
在仔細地為 ramdisk word 計算後,請用 rdev -r 設定它。請注意要使用 10 進位 值。如果你使用 LILO ,傳給 rdev 的引數在此應該是 mounted kernel path ,比如說 /mnt/vmlinuz;如果你用 dd 來 copy kernel ,替換成使用軟碟機名稱( 比如說 /dev/fd0)。
rdev -r KERNEL_OR_FLOPPY_DRIVE VALUE
如果你使用 LILO ,現在請把磁片 unmount 。
6.4 傳送root filesystem -- Transferring the root filesystem
最後一步是要傳送 root filesystem 。
如果 root filesystem 將被放置在做為 kernel 之 相同 磁片上,請使用 dd 指令及其 seek 選項傳送它,這會指定要跳過多少個 blocks :
dd if=rootfs.gz of=/dev/fd0 bs=1k seek=KERNEL_BLOCKS
如果 root filesystem 會被放置在 第二張 磁片上,請自磁碟機中拿走第一張軟碟片然後放入第二張磁碟片,接著將 root filesystem 傳送到其上:
dd if=rootfs.gz of=/dev/fd0 bs=1k
恭喜你,已經完成了!
在把 bootdisk 挪為緊急使用之前,請記得先測試它 !如果你的成品不能執行,請繼續讀下去。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
7. 問題解決 -- Troubleshooting, or The Agony of Defeat
當建造 bootdisks 時,開始的幾次嘗試結果常常是無法開機。建造一張 root disk 的一般方法是組合來自你現有系統的元件 (compnents) ,接著嘗試與得到這個以磁片為基礎的系統 (diskette-based system) ,直到它在 console 上顯示訊息。一旦它開始與你交談,這場戰斗就結束一半了,因為你可以了解它在抱怨什麼,而且你可以解決個別的問題直至系統能平順地運作。如果系統停止運作而沒有任何說明,要找到這原因會是一件困難的事。為了讓系統能啟動到能與你交談的階段,這需要使用到好幾種元件,而且這些元件要經過正確地組態。以下是調查系統無法與你交談之問題的建議程序:
你會看到一行訊息像這樣:
kernel panic: VFS: Unable to mount root fs on XX:YY
這是常見的問題,而它只有一些原因。首先,請根據 device code 清單檢查 device XX:YY ;它是正確的 root device 嗎 ?如果不是,那你可能沒有做過 rdev -R ,或者是你是對錯誤的 image 執行rdev -R。如果 device code 是正確的,那麼請仔細地檢查被編譯到你 kernel 內的 device 驅動程式。請確定它有內建軟碟片、 ext2 filesystem 支援。
如果你看到許多錯誤訊息像是:
end_request: I/O error, dev 01:00 (ramdisk), sector NNN
這是 ramdisk driver 所報告的 I/O 錯誤訊息,可能是因為 kernel 正嘗試寫入超越了設備的結尾。你的 ramdisk 因為太小而不能持有你的 root filesystem 。請檢查你的 bootdisk kernel 的初始化訊息,找一行像是:
Ramdisk driver initialized : 16 ramdisks of 4096K size
請針對 root filesystem 未經壓縮的 size檢查上述的 size 。如果 ramdisks 不夠大,那就讓它更大吧。
請檢查 root disk 實際上有包含你所認為應該被包含的目錄。 Copy 到錯誤的 level 是容易犯的錯誤,以致於到最後在你的 root 磁碟片上,你會有像是 /rootdisk/bin 的目錄,而非 /bin。
請檢查是否有 /lib/libc.so ,而它是否有與你硬碟內 /lib 目錄中所顯示之相同 link 。
請檢查你既存系統 /dev 目錄內的 symbolic links 是否同時也存在於你的 root 磁碟片 filesystem 上,在此,那些 links 是連往你已包括在你 root 磁碟片上的 devices 。尤其是在很多情況下, /dev/console links是最基本的。
請檢查你是否已包括了 /dev/tty1, /dev/null, /dev/zero, /dev/mem, /dev/ram 與 /dev/kmem 這些檔案。
請檢查你的 kernel 組態設定 - 對於直到登錄點 (login point) 所需之所有資源的支援必須被內建,不能使用模組。所以 ramdisk 與 ext2 支援必須被內建 。
請檢查你的 kernel root device 與 ramdisk 設定是否正確。
以上已經涵蓋一般部分,以下是一些更特定的檔案與檢查項目:
請確定 init 是以 /sbin/init 或 /bin/init 的形式被包括進來。并且確認它是可執行的。
請執行 ldd init 以檢查 init 的函式庫。通常這個就是 libc.so ,但是請無論如何還是檢查一下。請確定你已放入了必備的函式庫與 loaders。
請確定你把正確的 loader 給你的函式庫 -- ld.so 是給 a.out 而 ld-linux.so 是給 ELF 。
請針對 getty (或某種類似 getty 的程式,諸如 agetty, mgetty 或 getty_ps)的呼叫,檢查你bootdisk filesystem上的 /etc/inittab。請針對你硬碟的 inittab 檢查兩次。再檢查你所使用的程式的 man pages 以確定這些是有意義的。 inittab 可能是最詭異的部分,因為它的語法與內容,依據所使用的 init 程式與系統本質而有所不同。解決的唯一之道就是去閱讀 init 與 inittab 的man pages,然後再正確地做出既存系統開機時所做的事。請檢查以確定 /etc/inittab 有一個系統初始化的記錄 (entry) 。它應該包括一個指令以執行必定存在的系統初始化 script 。