主要是向您介紹如何定製系統安裝環境,包括產生安裝核心,初始Ram盤的產生,迷你安裝環境的定製。
自從Caldera推出了第一個Linux系統下的圖形化安裝程式以來,現在的主流Linux發布大多都使用圖形化的安裝程式進行系統內容的安裝,比如RedHat的安裝程式anaconda,Suse的安裝程式yast2, Caldera的安裝程式lizard,以及Mandrake的安裝程式gi。
這些主流廠商的安裝程式都有一個共同的特點,就是它們都是先構造一個完備的最小化的Linux運行環境,定製Linux的啟動過程,使得系統核心啟動後,載入一個系統裝載程式,這個程式將定製好的 Linux運行環境部分或者全部載入進入記憶體,然後將控制轉移到圖形化安裝程式。最後再由此程式啟動的圖形環境XFree86),設定對應的語言環境,啟動對應的系統安裝過程。
1 主流安裝程式簡介
Caldera的安裝程式lizard是Linux世界的第一個圖形化安裝程式,它的全部程式使用c++語言編製,圖形化的風格是基於kde和qt的。值得一提的是,caldera在定製圖形化安裝時,修改了核心,實現了核心的圖形化啟動,同時其安裝程式的硬體檢測功能很強大,可以檢測到部分非隨插即用的isa裝置,而且還提供了類似html風格的協助系統。因為安裝程式要求精鍊的環境,而此時通用的XWindows視窗管理器是無法滿足需求的太大而且佔用資源太多),所以caldera中還提供了一個最小化的視窗管理器lwm。在caldera安裝系統包的過程中,您還可以玩吃豆子遊戲,這也是lizard的一大創意。
Redhat的安裝程式 anaconda可能是大家最熟悉的安裝程式之一。它的全部程式都是由Python完成。Python是一種物件導向的指令碼語言,您可以在http: //www.python.org獲得它的相關資料。Redhat使用Python Gtk作為圖形介面的開發工具。在您解開anaconda的源碼包之後,您會發現一個anaconda的檔案,這是程式執行的主檔案。它提供了一個最小化的slang庫以支援文本方式的安裝。Redhat的安裝程式最大的特點就是很穩健,支援的驅動程式較多,對硬體的支援很強這說明Redhat安裝核心定製得非常好,而且得到了相當多的廠商支援)。但是Redhat安裝程式的功能不是特彆強,比如對於reiserfs、lvm不提供支援,不支援中文安裝7.2可能會推出中文版)。也有很多廠商的安裝程式是稍微修改了RedHat源碼構成的,比如VALinux、中科紅旗等。
對於Mandrake的安裝程式gi,它的全部程式都是使用Perl編製,您可以從Mandrake的CVS伺服器上下載最新的安裝程式。Perl是一種功能強大的指令碼語言,可以非常方便的處理Linux上的各種配置指令碼,它的圖形介面使用Perl-GTK編製。Mandrake的安裝程式是第一種提供中文安裝的主流發布。它的安裝程式的特點是新,支援的功能相當多,包括配置複雜的檔案系統,支援無線通訊裝置,多種印表機支援等等。
Redhat和Mandrake的安裝程式都是由指令碼構成的,它們雖然速度稍慢,但是其構成的安裝程式一般都比較穩定,而且便於移植到其他平台上。Redhat的整個安裝環境是儲存在一個stage2.img的檔案裡。您可用命令:
mount -o loop stage2.img /mnt/tmp
將其掛接到指定的目錄下,察看Redhat安裝程式的結構。Mandrake的安裝環境儲存在mdkinst的目錄下。
2 安裝環境的構成
一個圖形化的安裝環境實際上就是一個最小化的Linux運行環境。一般由如下幾部分構成:Linux系統安裝核心,Linux系統的初始Ram磁碟,系統運行所需的一些shell命令和程式所必需的系統庫,初始化程式,系統運行時必須的外部命令,XFree86子系統,字型集和本地化的環境設定,系統的案頭風格和貼圖,鍵盤對應,裝置設定資料庫,系統安裝程式等部分。
系統核心vmlinuz存在系統的開機映像之中,在系統啟動時調入,然後Linux調入初始Ram磁碟,由此Ram磁碟上的程式載入運行安裝程式的第一階段載入程式。這是個可執行程式,它一般執行載入硬碟驅動模組,將磁碟上的整個安裝環境調入記憶體,並作為根分區掛接。
這時就有一個在記憶體中的最小化的Linux系統了,一段映像程式結束運行,釋放自己所佔的記憶體,並將控制轉移到真正的系統安裝程式。這時系統安裝程式開始啟動XFree86子系統,設定正確的本地化環境,包括本地化環境變數,字型集,正確的鍵盤對應等,這時就允許使用者進行互動,從而在使用者的幹預下,完成整個系統的安裝過程。
整個安裝過程的一般流程:
2.1 定製安裝核心
一個好的安裝程式核心是和安裝程式緊密相關的,它必須是完備的和精簡的。完備的核心是指:如果安裝程式要對某方面的功能進行支援的話,必須在核心中也提供相應的支援。精簡的核心是指:對於安裝程式不需要的功能,核心一定不要支援,而且能作為模組存在的,就一定要把它設定為模組。這樣定製出來的核心很小,保證了定製的核心以及必須的硬碟驅動模組能放入開機映像中。
例如,對於2.4.3核心一組選項是:在下面的一組選項中沒有註明的選項,可以在定製安裝程式的核心時省略)
Loadable module support 可載入模組支援
[*] Enable loadable module support 將可載入模組支援打入核心
[*] Kernel module loader 將核心模組載入器打入核心
Processor type and features 核心支援的處理器類型
(386) Processor family 選擇386相容方式編譯核心
Toshiba Laptop support 東芝筆記本支援作為模組
(off) High Memory Support 對大於2GB的記憶體不提供支援
選擇386相容方式是為了保證安裝程式具有良好的相容性,在某種程度上來說,速度的快慢並不是衡量安裝程式的指標。一個好的安裝程式,應該具有高穩定性和高相容性。
General setup 一般選項
[*] Networking support 核心級網路支援
[*] PCI support 核心級PCI匯流排支援
(Any) PCI access mode PCI硬體的存取方式
[*] EISA support核心級EISA匯流排支援
[*] Support for hot-pluggable devices 支援熱插拔裝置
[*] System V IPCSystemV的進程間通訊機制
(ELF) Kernel core (/proc/kcore) format 核心檔案格式為ELF
Kernel support for a.out binaries核心模組支援a.out檔案
<*> Kernel support for ELF binaries 核心支援ELF格式
Kernel support for MISC binaries 核心模組支援其他的格式
對於網路支援和IPC機制的核心支援是必須的,因為Linux上的很多程式,即便它沒有進行網路通訊,它也用這些方式進行進程間通訊。對於ELF的核心支援也是必須的,因為安裝程式需要使用初始記憶體映像initrd),這種方式需要調用程式完成一些初始化的工作,這就要求核心必須能夠支援ELF可執行檔格式。其他對於PCI、EISA裝置的支援,是提高安裝核心硬體相容性的必要選項。
Parallel port support並行連接埠支援,要引入並口裝置支援時
Parallel port support 模組化的並行連接埠支援
PC-style hardware PC類型的硬體
[*] IEEE 1284 transfer modes IEEE 1284傳送模式支援支援裝置自檢)
對於並口而言,為了自動檢測串連到並口的裝置,必須將IEEE 1284傳送模式支援打入核心。對於不支援IEEE 1284傳送模式的並口裝置,系統是無法進行自動檢測的。
Plug and Play configuration
Plug and Play support模組化的隨插即用裝置支援
ISA Plug and Play support 模組化的ISA隨插即用裝置支援
在2.4.x核心中,對ISA Plug and Play裝置的支援存在一些錯誤,對於部分裝置,將此選項置入核心,裝置是無法正常工作的。因此,建議在定製核心時,對此類裝置的支援採用核心模組方式。
Block devices 引入對塊裝置的支援
<*> RAM disk support 核心支援RAM磁碟
(4096) Default RAM disk size
[*] Initial RAM disk (initrd) support
初始RAM磁碟的核心支援。因為安裝程式需要設定初始記憶體鏡像以載入裝置模組,所以這一選項對於安裝程式是必須的。
其他的選項都作為裝置模組存在,在需要時可以放入初始記憶體鏡像中。
Multi-device support (RAID and LVM)
[*] Multiple devices driver support (RAID and LVM)
<*>RAID support 將裝置模組md.o打入核心
如果將md.o不置入核心,僅為模組方式,raid分區將無法作為根分區啟動系統。這主要是因為raid裝置需要在啟動之初對硬碟進行讀寫,以決定raid分區的位置,類型等參數。
Linear (append) mode
RAID-0 (striping) mode
RAID-1 (mirroring) mode
RAID-4/RAID-5 mode
Multipath I/O support
Logical volume manager (LVM) support
為了支援軟體RAID裝置和邏輯卷管理的分區,將上述裝置定製為核心模組。為了對上述特殊類型的存放裝置進行支援,就需要mkinitrd支援產生正確的初始記憶體映像,同時為了在正確掛接裝置模組之後,系統能正確的安裝檔案系統並進行檢查,也必須提供初始啟動指令碼的支援initscript)。
Networking options
Packet socket設定包協議
<*> Unix domain sockets 支援unix域通訊端
[*] TCP/IP networking 核心支援TCP/IP網路
ATA/IDE/MFM/RLL support 對ATA/(E)IDE和ATAPI的低端存放裝置提供支援。
<*> ATA/IDE/MFM/RLL support
IDE, ATA and ATAPI Block devices
<*> Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support
<*> Include IDE/ATA-2 DISK support
<*> Inculde IDE/ATAPI CDROM support
Inculde IDE/ATAPI TAPE support
<*> Inculde IDE/ATAPI FLOPPY support
SCSI emulation support
IDE chipset support/bugfixes作為核心支援存在
對常見的IDE裝置支援,最好打入核心,這樣保證了安裝程式可以直接從硬碟、磁碟片、光碟機啟動,而無須額外的設定。
SCSI support
支援的SCSI裝置全部作為核心模組。這些模組將壓縮以後存入初始記憶體映像,以便在使用SCSI控制器時,系統能夠插入正確的裝置驅動模組。
Network device support
[*] Network device support
對網路裝置包括ARCnet、Appletalk devices、Ethernet、PPP、SLIP、Token Ring等類型的裝置提供支援,這些裝置的驅動程式都可作為裝置模組。
ISDN subsystem
ISDN support
對ISDN裝置提供支援,為了減小核心底層的ISDN卡的硬體驅動程式全部作為模組。
Old CD-ROM drivers (not SCSI, not IDE)
[*] Support non-SCSI/IDE/ATAPI CDROM drivers
對於具體的老CDROM裝置,它們的驅動程式也以模組的形式存在。
Input core support
Input core support
Keyboard support
Mouse support
Joystick support
Event interface support
開啟USB裝置的HID支援
Character devices
[*] Virtual terminal
允許您在一個虛擬終端上運行幾個虛擬中斷,可以使用Alt-<功能鍵>進行切換
[*]Support for console on virtual terminal
設定一個虛擬終端作為系統控制台
Standard/generic (8250/16550 and compatible UARTs) serial support
產生serial.o,允許串口滑鼠、串口modem以及其他相似的裝置串連到標準的序列埠上。
File systems
Kernel automounter support
Reiserfs support
DOS FAT fs support
MSDOS fs support
VFAT (Windows-95) fs support
Simple RAM-based file system support
ISO 9660 CDROM file system support
[*] Microsoft Joliet CDROM extensions
NTFS file system support
[*] /proc file system support
[*] /dev/pts file system for Unix98 PTYs
ROM file system support
<*> Second extended fs support
Network File Systems作為模組
Partition Types
[*] PC BIOS (MSDOS partition tables) support
Native Language Support作為模組
這樣的選項使得定製的核心支援/proc,ext2和/dev/pts檔案系統,可以使用插入模組的方式支援fat、vfat、ntfs、cdrom、 reiserfs、rom檔案系統。支援NFS檔案系統,並能支援核心級的自動掛接。同時,在掛接檔案系統時提供本地語言支援,預設值為iso8859- 1。
Console drivers
[*] VGA text console
[*] Video mode selection support
MDA text console (dual-headed)
Frame-buffer support
允許Linux的文字模式使用VGA模式或者是幀緩衝方式,支援Frame-buffer對於安裝程式是必須的,它使得安裝程式能夠以fbdev的方式啟動XFree86。
Sound
Sound card support
對於音效卡的支援,核心可以把各個音效卡的裝置驅動定製成模組。
USB support
Support for USB
[*] Preliminary USB device filesystem
usb檔案系統,必須定製到核心中,這樣以後才可以通過/proc檔案系統檢測安裝的usb裝置。usb的橋接器(uhci、ohci)和其他不同的裝置驅動程式都可以作為核心模組。
2.2 定製記憶體初始鏡像
由於在定製安裝程式的核心時,要求核心很小,而另一方面安裝程式又要支援儘可能多的硬體裝置。為了支援儘可能多的硬體,尤其是特殊的存放裝置,我們需要在定製初始的啟動鏡像時將需要支援的部分,如常見的SCSI控制器和非標準的IDE控制器的驅動程式模組放入其中。這樣才能夠使核心在嘗試使用硬碟或其他存放裝置時,其裝置驅動程式已經提前載入了。
在核心調入記憶體之後,如果存在記憶體初始鏡像initrd),那麼控制會轉到其上並執行配置指令碼linuxrc。記憶體的初始鏡像使引導載入器載入一個RAM盤,此RAM盤可以作為根檔案系統掛接並且能在其上運行應用程式。此後,新的根檔案系統能從不同的裝置上掛接比如光碟機或者硬碟)。在掛接了新的檔案系統之後,作為根分區的記憶體初始鏡像將成為目錄/initrd或者被卸裝。
記憶體初始鏡像initrd)的使用將使得系統的引導過程分成兩個階段,初始啟動的核心只需保留最精簡的驅動程式最小集,當啟動必須載入附加的驅動模組時再由記憶體初始鏡像載入。比如,您在使用了軟體RAID方式管理硬碟並使用RAID 1類型的分區作為系統的根分區之後,就必須建立記憶體初始鏡像。這時的記憶體初始鏡像中包含了裝置模組raid1.o以及系統命令insmod,和一個 shell指令碼linuxrc,其內容一定包含:
insmod raid1.o
在使用記憶體初始鏡像時,系統引導過程如下:
引導載入程式載入核心和初始化RAM盤。
核心轉變記憶體初始鏡像為正常的RAM盤並釋放記憶體初始鏡像所用的記憶體。
記憶體初始鏡像掛接為根分區,此分區允許讀/寫操作。
執行linuxrc它可以是任何合法的執行程式,包括shell指令碼;該程式以uid為0方式運行,可以完成init所做的每件基本工作)。
在linuxrc終止時,真正的根檔案系統被掛接。
若/initrd目錄存在,則initrd被移動到此處,否則,initrd被卸載。
在根檔案系統上完成正常的引導過程。例如,對於正常的系統而言,執行/sbin/init,這時控制就會轉到正常的大家所熟知的啟動過程了。而對於安裝程式,它只需將控制轉到安裝過程的第一階段,由它完成後續的安裝環境的載入,裝置的進一步初始化等操作。
建立一個初始記憶體鏡像實際上就是建立一個檔案,這個檔案上包含了一個ext2檔案系統,它可以使用迴環方式loop)掛接到本地檔案系統上。下面的shell程式段可以建立初始記憶體鏡像:
dd if=/dev/zero of=/tmp/initrd bs=1k count=2000
建立一個2000k的整塊檔案,一定不能有片段
mke2fs /tmp/initrd
建立一個ext2檔案系統
mount -t ext2 /tmp/initrd /mnt -o loop
將此檔案作為迴環檔案系統掛接到/mnt目錄下
建立所需的路徑和檔案:
mkdir /mnt/dev
mknod /mnt/dev/tty1 c 4 1
mkdir /mnt/lib
cp raid1.o /mnt/lib/
mkdir /mnt/sbin
cp /sbin/insmod /mnt/sbin/
cp /sbin/ash /mnt/sbin/
... ...
umount /mnt
卸載此檔案系統
gzip -9 /tmp/initrd
cp -f /tmp/initrd.gz /boot/initrd.img
rm -f /tmp/initrd.gz
這樣一個記憶體映像檔案就產生了。
為了產生記憶體映像檔案,核心在編譯時間必須開啟ramdisk支援並且支援初始RAM盤,initrd中執行程式的所有對象例如,可執行檔格式ELF和檔案系統EXT2)必須編入核心,這樣您產生的記憶體映像檔案才是正常可用的。
預設條件下,核心的標準設定指定了根裝置,另外還可以由rdev設定,或者由命令列傳遞參數root=xxx指定。在initrd環境下也可以改變根裝置。首先,系統要掛接/proc,然後使下列檔案可用:
/proc/sys/kernel/real-root-dev
/proc/sys/kernel/nfs-root-name
/proc/sys/kernel/nfs-root-addrs
real-root-dev能通過向其寫入新的根檔案系統裝置號來改變,例如
# echo 0x301 >/proc/sys/kernel/real-root-dev
總而言之,建立初始記憶體映像檔案的主要目的是為了在系統安裝啟動)時配置核心模組。這時整個安裝過程的最初階段會按如下方式工作:
系統由磁碟片或其它介質以最小核心啟動必須支援RAM盤,初始記憶體鏡像,ELF類型的可執行檔,ext2類型的檔案系統)並載入初始記憶體鏡像。
/linuxrc決定下一步的工作:
掛接真正的根檔案系統,包括對裝置類型,裝置驅動程式,檔案系統等資訊的處理。
安裝程式的發布介質例如,CDROM,網路,磁帶…)。這可以通過詢問使用者,自動探測,或混合的方法完成。
/linuxrc載入必須的裝置驅動程式模組。
/linuxrc建立和管理根檔案系統。
/linuxrc寫在根檔案系統和任何已經掛接的其它檔案系統,設定/proc/sys/kernel/...,終止。
掛接根檔案系統。
引導載入程式被讀入記憶體。
引導載入程式配置帶有模組集的初始記憶體鏡像/initrd能被修改,卸載)。
完成系統引導時附加的安裝任務。
2.3 定製最小化的運行環境
安裝程式的運行環境是整個安裝過程第二階段,它是在核心以及初始記憶體映像運行之後,由第一階段的安裝程式裝入記憶體的。在此之後,安裝程式才正式從其上開始運行。定製最小化的安裝程式運行環境也就是定製最小化的Linux系統運行環境。
定製怎樣的安裝程式運行環境和安裝程式所提供的功能密切相關。一般而言,安裝程式都要開啟多個控制終端,所以為了便於調試,安裝環境中應該具備完整的 shell命令環境。同時,為了支援圖形化顯示,那麼安裝環境還需要XFree86系統,GtkQt)庫環境,可能還需要gtk-engine以支援貼圖的顯示方式。而對於要提供多語言支援的安裝程式,這就需要提供glibc的本地化環境,多種字型集,不同的鍵盤對應方式。另外對於安裝程式提供支援的硬體裝置,也應該將其驅動程式模組放入安裝程式的運行環境中。
安裝程式運行環境一般應包括如下內容:
運行時刻庫,包括運行程式必須的動態庫
驅動程式模組檔案,包括安裝程式需要支援的裝置和服務模組
系統命令,包括各種系統命令
多語言環境,包括鍵盤對應、本地化環境、字型
XFree86系統,包括XFree86伺服器
指令碼解釋程式運行環境,例如Perl或Python等
安裝程式
為了使運行環境最小,構建安裝程式運行時刻庫時,必須也是最精簡的,也就是說,每個庫檔案必須被至少一個命令或者安裝程式的某個部分所使用。同時在拷貝的過程中,使用strip命令撥去所有的調試資訊。要檢查一個命令使用了哪些動態庫可以使用命令ldd。
例如,當安裝程式中包含fdisk命令時,要檢查它所需要的運行庫,只需要運行下面的命令:
ldd `which fdisk`
這樣我們就可以知道,fdisk需要的動態庫為libc.so.6和ld-linux.so.2。接下來的工作就是將這兩個庫拷貝到安裝程式的運行環境,同時運行
strip libc.so.6
strip ld-linux.so.2
以撥去所有的調試資訊。
下面我們以Mandrake 8.0為例,讓我們看看它的安裝程式運行環境包含了些什麼東西。Mandrake 8.0的安裝程式存放在光碟片目錄mdkinst下,其安裝程式的目錄結構是:
/etc
包含pcmcia裝置的配置選項,sysconfig目錄,調色盤,Imlib缺生設定。
/lib
包含系統的運行庫lib*和支援的驅動程式模組集。
/usr/X11R6/bin
包含XFree86伺服器,包括XF86_FBDev、XF86_VGA16。
/usr/X11R6/X11
包含XFree86伺服器的字型和本地化環境。
/usr/bin/
這是整個安裝程式最關鍵的目錄,它包含安裝程式執行時需要的系統命令,安裝程式源碼,install2檔案為安裝程式的主控檔案,所有安裝程式的來源程式儲存在perl-install目錄下。
/usr/lib/
包含多語言支援的運行庫儲存在gconv目錄下,perl5運行所需的模組儲存在perl5目錄下,其他與本地化和gtk相關的設定。
/usr/share
包含控制台字型儲存在consolefonts下,程式貼圖和桌面主題貼圖一部分儲存在gtk目錄下同時也包括此目錄下的所有*.xpm,*.png檔案,glibc的本地化環境儲存在locale目錄下,鍵盤對應分別儲存在keymaps和xmodmap目錄下,檢測裝置的資訊檔包含裝置標識與裝置驅動程式的對應關係)儲存在ldetect-lst目錄下。
儲存在/lib/目錄下的系統運行時刻庫:
系統RPM包 動態庫
Glibc Ld-linux.so.2,libc.so.6,libcrypt.so.1,libdl.so.2,libm.so.6,libnsl.so.1, libnss_dns.so.2,libnss_files.so.2,libnss_nis.so.2,libresolv.so.2
libext2fs2 libcom_err.so.2,libe2p,libuuid.so.1
db3 libdb-3.1.so
db3-devel libdb.so.2
zlib1 Libz.so.1
libpng2 libpng.so.2
libgtk+1.2-devel libgtk-1.2.so.0,libgdk-1.2.so.0
libimlib1 libgdk_imlib.so.1
libglib1.2 libglib-1.2.so.0
libglib1.2-devel libgmodule-1.2.so.0
libbzip2_1 libbz2.so.1
Lvm liblvm.so
Rpm librpm.so.0,librpmio.so.0
XFree86-devel LibX11.so.6,libXext.so.6
XFree86-libs libXi.so.6
XFree86-server-common libfont.so.1
Freetype libttf.so.2
表 2-1
儲存在/usr/bin/目錄下系統支援的命令:
系統rpm包 系統命令
Ash Ash
console-tools Consolechars
Cpio Cpio
Gzip Gzip
e2fsprogs badblocks,mke2fs,resize2fs,dumpe2fs
util-linux fdisk,rescuept
Modutils insmod_,rmmod
Raidtools mkraid,raidstart,
bzip2 bzip2
Rpmtools packdrake,parsehdlist
perl-base Perl
Lvm pvcreate,pvdisplay,vgchange,vgcreate,vgdisplay,vgextend,vgremove,vgscan,lvcreate,lvdisplay,lvremove
kernel-pcmcia-cs Ifport
Dosfstools Mkdosfs
reiserfs-utils mkreiserfs,resize_reiserfs
表 2-2
另外,因為perl語言具有一部分系統功能,所以為了減小運行環境,部分命令還可以採用perl語言編製。這些命令包括:
basename,bug,cat,chmod,chown,cp,dd,df,dirname,displaySize,dmesg,du, e2fsck,fsck.ext2,getopts,grep,gunzip,head,head_tail,header,hexdump, insmod,kill,ln,loadkeys,ls,lsmod,lspci,mkdir,mknod,mkswap,modprobe,more, mount,pack,ps,raidstop,report_bug,rights,rm,rmdir,route,sh,sort,strings, swapoff,swapon,sync,tail,tr,true,umount,uncpio,unpack,which