歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> Linux業界

構造Linux的圖形化安裝程序(1)

安裝環境的定制
於辰濤 ([email protected])
2001 年 9 月

這是一個向用戶介紹如何構造Linux的圖形化安裝程序的專欄。介紹的內容包括:安裝環境的定制,圖形化啟動,本地化支持,分區功能,如何支持reiserfs、raid、lvm,rpm包的安裝,定制各種啟動配置腳本等等。本文是這個系列文章的第一篇,主要是向您介紹如何定制系統安裝環境,包括生成安裝內核,初始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.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 IPC SystemV的進程間通訊機制
(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系統,Gtk(Qt)庫環境,可能還需要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

作者介紹
於辰濤,聯想(北京)電腦公司軟件工程師。目前主要從事Linux系統安裝程序的開發工作,主要研究興趣是操作系統的工作機制和開發底層系統程序。您可以通過電子郵件 [email protected] 跟他聯系。




Copyright © Linux教程網 All Rights Reserved