關於isolinux
以前我們很多啟動盤採用的是loadlin引導linux核心的模式進行的(比如早期的slackware)。也就是採用win98的dos啟動,然後通過loadlin工具引導我們的自己的linux核心,解開我們的安裝檔案系統。
但是,隨著我們接觸的硬體機型多樣化,目前部分新設備不能採用dos(或win98)引導。
這個時候很多人會採用syslinux來製作啟動盤,但是syslinux一般都需要能夠將核心和檔案系統放到一張軟碟上的,如果我們的檔案系統很大,又不能裁減,那可就慘了。或者說想在光碟啟動的時候選擇多個核心/檔案系統,syslinux就比較麻煩了。
引導程式
概述
任何一個作業系統在任何一個硬體平台上的運行都需要一個引導的過程,即,初始化軟體環境、把核心從存儲介質放到記憶體當中去,並開始運行。當然對於某些簡單軟硬體系統,這個過程可能及其簡單,而對於 PC 就要略微複雜一些了。
PC 的引導程式上承 BIOS,下接核心的初始化代碼,雖然開一次機只運行一次後就不留痕跡了,不過還是相當重要的。所有的引導程式都在做類似的事情:
駐留在存貯介質的特殊位置可以被 BIOS 啟動,或是自己是某一系統的執行檔,可以被用戶顯式或隱式在該系統(宿主系統)內啟動;
了解要被啟動的必要啟動檔案的位置,包括系統核心、ramdisk 等,並把它們讀取出來、裝載到記憶體之中;
構造環境、運行作業系統的核心,自己則就此退出歷史舞台。
歷史上,用於 Linux 的最著名的引導程式莫過於 LILO 和 Grub 了,作為通用的引導程式,二者用途廣泛,但對於一些特殊的場合,譬如引導程式可利用的空間比較有限的可移動存儲介質 (通俗地說,包括光碟、軟碟、u 盤等),它們有些過於厚重了,這就引出了我們今天的主角 --- SYSLINUX/ISOLINUX,現在,你只要知道他們是引導程式就足夠了,接下來,我們還要插入一些廢話。
initrd
initrd = init ramdisk, 顧名思義,就是在啟動時使用的一個記憶體虛擬磁碟,它是系統廣泛的硬體支持性的必需品。
我們知道,Linux 的驅動程式是核心的一部分,它們提供了硬體向上層的抽象接口,Linux 核心的核心子系統 --- 虛擬檔案系統部分的工作強烈依賴於底層硬體驅動程式的支持,在啟動過程當中,當某些必備的驅動程式無法使用的時候,比如 EXT2 檔案系統、IDE 硬碟適配器等無法工作的時候,系統啟動將就此中止,發生所謂的``Kernel Panic'',這也是初學者編譯核心最常遇到的困難。
然而,我們當然不能將所有的驅動都編譯到核心當中去,因為我們不能無限制地加大核心的尺寸,這對於系統資源,尤其是引導過程中非常有限的可用存儲資源是難以承受的 .
具體設定
我們可以把很多驅動程式編譯成模組,隨用隨載入 極少數情況,某些模組是相互衝突的,比如 2.4 核心的某些版本之中,reiserfs 和 ext3 兩種驅動不能同時被編譯到核心當中。 所以,我們只能在核心中放入必要的驅動程式,其餘的不那么需要的部分編譯成模組放到 /lib/modules/`uname -r`/ 之中,在需要的時候會被載入。
但是,對於具有通用性的核心,是很難論斷出哪幾種驅動程式才是真正必須的,究竟是 Intel 的 IDE 磁碟控制器還是 AMD/nVidia 的,抑或是 VIA 的,乃至光纖通道SCSI 磁碟……是阿,這真是個很困擾人的問題,沒有一個驅動可以在占用絕對少的空間的前提下應付所有的設備,於是,我們退而求其次,尋求一個中間介質 --- ramdisk
在核心啟動前,引導程式首先在記憶體之中構建一個 ramdisk,成為一個基本檔案系統,然後 Linux 核心以此為自己的根檔案系統啟動,這樣的好處是可以不必理會磁碟驅動的問題,只要能驅動 ramdisk 就可以了。
用 ramdisk 啟動之後,在 ramdisk 的啟動腳本 (一般叫 /linuxrc) 之中,針對硬體嘗試 ramdisk 裡面的 /lib/modules/`uname -r`/,載入恰當的驅動,這時系統已經具備了切換到硬碟或其他介質上的檔案系統的條件了。
機不可失,這時,我們首先載入硬碟或光碟、u 盤等啟動介質,然後設該介質為根分區,並運行其 init 進程為 1 進程,之後,在 init 腳本中,釋放掉 initrd 的空間,這就是藉助 initrd 的引導過程。在這個過程之中 引導程式幫我們多做了一件事 --- 構建 ramdisk, 把 initrd 放入記憶體。
用 SYSLINUX/ISOLINUX 引導軟碟和光碟
上文已經說過了,SYSLINUX/ISOLINUX 是專門用來引導可移動介質的輕量級引導程式,因為這樣的介質通常不會固定只針對一種硬體,initrd 當然是 SYSLINUX/ISOLINUX 必須支持的功能了。這兩種引導程式其實是一樣的,沒有多大區別,只是放在不同的設備的引導區罷了。
3.1 配置 SYSLINUX/ISOLINUX
對於這兩種引導程式,都會有一段引導代碼,寫入引導代碼的時候,還同時需要一個配置檔案: syslinux.cfg/isolinux.cfg,同樣,這兩個檔案也是一樣的,唯一的區別在於檔案名稱,其各個欄位的寫法如下:
DISPLAY xxx.txt
這指定了一個檔案名稱,會在啟動的時候顯示的內容,該檔案甚至可以包含一個 RLE 編碼的圖形檔案,也就是大家在安裝光碟啟動時看到的那個;不過這個欄位不甚重要,我們就略過了。
DEFAULT linux
指定 label 是 linux 的啟動選項為預設,當然也可以是別的。
LABEL linux
kernel vmlinuz
append initrd=initrd26.gz ramdisk_size=1000000 vga=791
這就是一個啟動描述,前面的 label 大家都認識了,之後分別是指定 kernel 和核心參數,其中重要的參數就是 initrd= 指定 initrd 的檔案和 ramdisk_size= 指定 initrd 的尺寸上限。其餘的核心參數還可能有很多,不過這裡的參數我們一般都可以抄過來。這樣的啟動選項描述是可以有若干個的。
PROMPT=1
這是說,向用戶提示輸入選擇,直接回車就是預設選項了
TIMEOUT=0
沒有時間限制,當然也可以指定一定時間之後自動進入預設選項。
好了,就這么多,如果你會用 LILO 的話,用這個一定得心應手,說實話 grub 也差不了太多。
3.2 安裝 SYSLINUX/ISOLINUX
配置檔案寫完了,現在進入實質階段,這裡,兩種引導程式還是略有差別的,首先介紹SYSLINUX:
首先格式化引導介質為 FAT16 格式 (軟碟似乎應該是 FAT12),我們的例子裡面是 U 盤,
mkdosfs -F16 -I /dev/sdX #原百科命令最後面的sda,你不怕硬碟沒法啟動就用sda!
我們是操作整個 U 盤,而不是裡面的唯一分區,這種情況不是很多見,只是手上的 U 盤比較特殊,大部分情況下,我們也可以
mkdosfs -F16 /dev/sdX1
然後掛在該 U 盤,放入我們的 syslinux.cfg 以及 kernel 和 initrd.gz,還有其他啟動所需要的東東,之後 umount 該 U 盤。
* 執行下面操作之前,必須 umount U 盤!*
然後寫引導區:
syslinux /dev/sdX (或 syslinux /dev/sdX1,如果是格式化的 /dev/sdX1 的話)
至此就完成了。
對於光碟,同樣不複雜,我們用 ISOLINUX:
在準備製作 ISO 的目錄里添加一個子目錄,比如 boot/isolinux/ ,然後放入 isolinux.cfg 和一個對所有光碟都一樣的 isolinux 提供的引導介質 isolinux.bin,當然還要放入相應的 kernel, initrd 等等,然後,製作 iso 的時候要使用 -b 參數:
mkisofs -o output.iso \
-b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat \
-no-emul-boot -boot-load-size 4 -boot-info-table \
for-iso-dir/
最後的參數就是指定的光碟的目錄了,-c 參數的那個檔案是自動生成的,不用太擔心,其餘參數都是固定的。事實上,也常常有人用 isolinux/ 而不是 boot/isolinux/ ,這都是約定俗成的,你完全可以用自己的。這裡的路徑都是相對於光碟的根的,而和製作光碟時的工作目錄沒有關係。
至此,你也會用 SYSLINUX/ISOLINUX 了。 :)
實戰
-四、實戰 -- damn small linux + debian installer, 2 in 1 usb disk
1 下載 di 的 hd-image 里的 kernel image 和 initrd,放入 U 盤,同時把 businesscard iso 也放進去,從 iso 里找到 isolinux.cfg,記下裡面的啟設定
2 下載 dsl,把 KNOPPIX 目錄搬到我們的 U 盤裡,把 boot/isolinux/ 裡面的 kernel image 和 initrd 也放入 U 盤的根目錄,這時,U 盤根目錄里同時有二者的啟動檔案了,也記住 dsl 裡面的 isolinux.cfg 的啟動選項。
3 以其中一個的 isolinux.cfg 為基礎,加入另一個的啟動參數,注意 label 命名不要衝突了就可以了。
4 umount 隨身碟,然後對 U 盤運行 syslinux,寫引導區,大功告成。
如前面帖子說過,dsl 的 initrd 之中,只搜尋 /dev/sda[1-9] 而不搜尋
/dev/sda,所以,如果如果像我們一樣被迫用 /dev/sda 的話,就不得不修改一下 dsl 的 initrd 裡面的 linuxrc 了,除此之外,沒有什麼其它值得大書特書的了。
Enjoy it!