BabyLinux製作過程詳解(轉)
一,什麼是BabyLinux
BabyLinux不是一個完整的發行版,他是利用原有的一套完整的linux系統的核心原始碼和編譯工具,利用busybox內建的強大功能,在一張軟盤上做的一個很小的linux系統.他具備一個linux系統的基本特徵,支援linux系統最常用的一百多個命令,支援多種檔案系統,支援網路等等,你可以把他當做一張linux起動盤和修復盤來用,你也可以把他當做一個靜態路由的路由器軟體,當然,你也可以把他當做一個linux玩具,向你的朋友炫耀linux可以做的多麼小.我把他叫做BabyLinux因為他很小巧,小的很可愛,像一個剛剛出生的小baby.
二,為什麼要作這樣一個linux
先說說我一開始的想法,當我一開始接觸linux的時候,看到書上說,linux通常安裝只需要60M左右的空間,但是我發現裝在我硬碟上的Redhat 6.0確要佔據好幾百M的空間.為什麼我的linux這麼大呢? 後來我發現,裝在我機器上的那麼多東西只有不到30%是我平時常用的,還有30%是我極少用到的,另外的40%基本上是不用的.於是,我和大多數初學者一樣,開始抱怨,為什麼linux不能做的精簡一點呢?於是,我萌發了自己裁減系統的想法.可惜那個時候我還沒有聽說過有LFS和Debain.等到我積累了足夠的linux知識後,我開始製作這樣一個小系統.
製作這樣一個小系統最大的意義在於,你可以透過製作系統瞭解linux的啟動過程,學會ramdisk的使用,讓你在短時間內學到更多的linux知識.當然,你會得到很大的樂趣.這個專案只是做一個具有基本特徵的linux系統,如果你想自己做一個具有完整功能的linux,請閱讀Linux From Scratch (LFS)文件.
三,什麼人適合讀這篇文件
如果你是一個linux愛好者,並且很想了解linux的啟動過程和系統的基本結構,而且是一個喜歡動手研究小玩意的人,那麼這個文件可以滿足你的需求.如果你僅僅是用linux來做一些普通的日常工作,而不在乎你的linux到底怎麼工作,那麼這份文件也許不太適合你.另外,如果你是linux愛好者,但是目前還是一個剛剛入門的newbi,我建議你先把linux命令學好.不過我想我會盡可能的把這份文件寫詳細一些,如果你有足夠的毅力,或許一個newbi也能成功做一個babylinux.或者,你遇到一件很不巧的事情,比如你的老婆來例假了,你的這個週末就泡湯了,那麼閱讀這篇文件並做一個linux小玩具可以打發你的時間.
四,應該具備的知識
在做一個babylinux之前,你應當已經會應用linux最常用的命令.並且至少有一次成功編譯並安裝系統核心的經歷,會透過編譯原始碼來安裝軟體.如果你具備了這些條件,那麼做這樣一個小系統會很順利,如果你還沒有掌握這些知識,你可能會遇到一些困難.但是隻要有毅力,也可以成功.你不需要具備程式設計的知識,因為我的目標是:讓具有中等以上linux水平的愛好者可以透過閱讀文件輕鬆完成這個專案.關於一張軟盤上的linux還有一個很著名的linux叫LOAP (Linux On A
Floppy) 但是他是由比較專業的人員需要編寫很多程式完成的.而且沒有關於他製作過程的文件.
五,linux系統引導過程簡介
首先,主機板的BIOS會讀取硬碟的主開機記錄(MBR),MBR中存放的是一段很小的程式,他的功能是從硬碟讀取作業系統核心檔案並執行,因為這個小程式太小了,因此通常這個小程式不具備直接引導系統核心的能力,他先去引導另一個稍微大一點的小程式,再由這個大一點的小程式去引導系統核心.在linux系統中這樣的小程式有LILO和GRUB.在這個專案中,我決定用LILO來做系統載入程式.在軟盤上啟動linux系統的過程和在硬碟上啟動的過程相似.
Linux系統核心被載入程式裝入核心並執行後,linux核心會檢測系統中的各種硬體.並做好各種硬體的初始化工作,使他們在系統正式執行後能正常工作.之後核心做的最後一個工作是執行
/sbin下的init程式,init是英文單詞initialization(初始化)的簡稱,init程式的工作是讀取/etc/inittab檔案中描述的指令,對系統的各種軟硬體環境做最初化設定.最後執行mingetty等待使用者輸入使用者名稱登入系統.所有的工作就這麼簡單,雖然linux啟動的時候有很多內容,看上去十分高深,但是都不過是對這個過程的擴充.明白了這個道理,你可以寫一些指令碼程式讓他在系統啟動的特定時間執行完成任務.事實上系統核心並不關心/sbin下的init是不是真的init,只要是放在/sbin下名叫init的可執行程式他都可以執行.可以做以下實驗:
編寫一個非常簡單的C程式:
main(){printf(“hello,world! ”);}
儲存後以init.c儲存他,並用gcc編譯.
#gcc –-static -o init init.c
這裡的--static 引數告訴gcc把這個程式靜態聯接,這樣這個程式不倚賴任何庫就能執行.把編譯好的init程式複製到/sbin下,備份好原來的那個.重新啟動系統最後系統的輸出結果是: hello,world!
然後停在那裡.做這個實驗以前先確定你知道如何把系統恢復到原來的狀態,有一個簡單的方法,在核心啟動前給他加上init=引數,比如你原先的init被你改成了init.bak 只要在啟動的時候給核心加上init=/sbin/init.bak就可以用原來的init程式啟動系統.
做完以上實驗,就明白了核心和init程式之間的關係.此外,init程式不一定是一個二進位制可執行程式,他可以是一個bash指令碼,一個指向另一個程式的聯接,他的位置也並不一定要在/sbin下,只要在啟動核心時,給核心加上init引數就能被執行,比如,開始時給核心加上init=/bin/bash引數,核心在最後一步就直接執行bash給出提示符,不用登入系統就可以輸入命令了.其功能類似單使用者模式啟動系統. /sbin/init 程式只是核心預設執行的第一個程式.
六,編譯一個linux系統核心
1,編譯前的規劃和準備
在編譯核心前,請先確定你的需求,把你的需求羅列成一張詳細的表格.你需要讓核心支援什麼硬體,支援多少種分割槽型別和檔案系統,支援哪些網路卡,支援哪些網路協議.等等.請儘可能詳細的羅列這些內容,但是你也不要太貪心,因為你所有能利用的空間只有1440K,如果你編譯出一個大於1440K或很接近這個數字的核心,你的這個專案就不能完成了,你已經沒有空間再放ramdisk映象檔案,除非你原意再多出一張軟盤,做一個兩張軟盤的小linux系統.對於音效卡驅動之類,我勸你還是放棄吧,因為一個音效卡驅動也許只讓你的核心增大了十多K,但是你有了一個音效卡驅動就務必要有一個播放器吧,否則音效卡驅動就沒有意義,可一個播放器的大小可不是一張軟盤可以裝得下的.在我先前製作的babylinux核心有900多K,其中,檔案系統部分站了大部分,因為我的目標是把他做成一個系統修復盤.因此我在核心中編譯7種檔案系統的支援,每減少一個檔案系統就可以減小几十甚至200多K的核心大小.越是複雜,越是安全的檔案系統,其支援模組也越大,比如在linux下FAT模組只有32K,VFAT只有17K,但是ext3的模組就有86K,JFS達到216K,reiserfs模組是224K,可以想像,編譯一個支援7個檔案系統的900多K的核心,檔案系統部分就佔了600K以上的空間,所以如果某一個檔案系統是你根本不用的,那麼還是不要編譯進核心把,這樣至少可以省下100多K的空間.對於其他的驅動,比如網路卡,通常大小隻有8,9K,最大的也不過10多K,因此可以把常用的網路卡晶片的驅動都編譯進去.另外如果你想讓你的babylinux支援隨身碟,那麼scsi的驅動模組也是不可小看的,他通常要接近150K,因為隨身碟是被當做scsi裝置來驅動的.另外你還需要讓你的核心支援即插即用,這些都是不小的空間開銷,我的建議是你放棄一兩個你不用的檔案系統.總之,你最後編譯出來的核心大小最好不要超過900K,否則你在busybox裡只能編譯進去很少的命令.
在我編譯的busybox中,我編譯進去120多個命令,基本上把busybox支援的命令都包括進去了.加上小系統所必需的檔案系統目錄,/dev下的裝置檔案,以及/etc下幾個必需的配置檔案,做成ramdisk壓縮後的大小是440多K, 加上900K左右的核心剛好可以放入一張1440K軟盤,請注意,你應該留下至少50K的空間,因為我們要在軟盤上建立一個ext2檔案系統,而檔案系統本生需要佔據大概25K的磁碟空間.另外lilo的引導檔案boot.b的大小是5.7K,還有裝上lilo後自動產生的map檔案也要10多K的空間,map檔案的具體大小由核心安裝的實際大小決定,通常不會超過30K.
綜上所述,請遵循下面的公式:
核心大小+檔案系統壓縮印象檔案+50K <= 1440K
另外一點需要說明的是:以上所羅列的檔案系統模組大小是察看我現在使用的Redhat 9 的
/lib/modules下的模組檔案得到的,實際編譯進核心大小會小一點,因為我們用make bzImage
在核心原始碼目錄樹下生成的核心是經過壓縮過的.
如果你對以上說的內容不太明白也沒有關係,我會在下面的內容中做詳細的說明.
2,必需編譯進核心的內容
首先,我們製作的這個小系統是基於一張軟盤的,因此,你的核心必需支援軟盤.另外對IDE硬碟和cdrom的支援也是不可少的,否則做出來的babylinux就沒有實用價值,因為他不能訪問硬碟和光碟上的內容這樣的linux雖然可以做的更小,但是製造一個完全沒有用的東西是浪費時間.其他的包括framebuffer等,如果你需要支援在字元介面下以高解析度顯示,以看到更多的螢幕內容,那麼就必需把framebuffer支援編譯進核心,此外在高解析度下使用的8x8字型也必需編譯進去.否則即使你給核心傳遞了vga= 引數,核心會因為沒有可用的小字型而自動轉跳到低解析度模式下,這是以前困擾我好幾天想不明白的事情,後來透過反覆試驗才明白原來是缺少字型的文體.這裡我先大致提一下需要注意的事情.在下一小節具體編譯時,我會繼續就某些細節問題說明.
3,關於核心的版本
我是在Redhat 9 linux系統下打造的babylinux小系統.使用的是Redhat 9 自帶的2.4.20版的核心.
為什麼我不用最新的2.6的核心?
一開始我也企圖用最新的核心,但是透過試驗我發現,在用最新的2.6.9核心的情況下,我編譯一個all-no的(即所有內容都選N,不支援任何硬體,只有一個最基本的核心)最小化核心就要460K左右,如果我在這個基礎上再加入幾種檔案系統和必要的驅動,那麼核心的大小就不能裝下一張1440K
的軟盤,而我用2.4.20的核心編譯一個最小化的核心只需要217K,的大小.如果最佳化了gcc引數他還能再小些.這樣我就立即省下了200多K的空間,在平時,200多K的內容微不足道,但是在babylinux裡,這個數目是整個空間的 1/7,相當於一個reiserfs檔案系統模組的大小.當然,我也嘗試了2.2以及更老的核心,但是他們缺少我需要的東西,因此最後權衡下來用2.4的核心是比較合理的.如果你用的是2.6核心的FC系統,那麼最好還是去下載一個2.4版的核心, 有各個時期的核心可以下載.
4, 核心的配置
如果你對linux核心的配置和編譯已經很熟悉了,請跳過這一段,直接看busybox的編譯.
以root身份登入系統
進入/usr/src/linux目錄
[root@gucuiwen root]# cd /usr/src/linux
如果你下載了一個2.4版本的核心,為了避免麻煩,請將他複製到/usr/src下,然後接壓縮,再做一個指向他的名為linux的連結.雖然這並不是必需的,但是根據我以往的經驗,如果我把linux原始碼放在其他目錄下解開並編譯,偶然會有一些莫名其妙的小問題發生.
#cp linux-2.4.20.bz2 /usr/src/
#cd /usr/src
#tar xfvj linux-2.4.20.bz2
如果是tar.gz格式,可以這樣解開
#tar xfvz linux-2.4.20.tar.gz
為了方便,做一個到目錄linux-2.4.20的連線:
#ln -s linux-2.4.20 linux
進入linux原始碼目錄:
#cd linux
清理原始碼樹:
#make mrproper
執行配置程式:
#make xconfig
code maturity level options
先選擇N,當我們配置好常規的東西,要加入framebuffer支援時再將這一項選擇Y,因為在2.4.20中,framebuffer支援尚屬於實驗性程式碼.
如果不在code maturity level options選擇為Y,將不能配置framebuffer.
Loadable module support
選擇N,為了簡化系統的製作,我在這個專案中不選擇可載入核心模組的支援.
processor type and features
processor family 中選擇你需要的CPU型別,如果你想讓老至386,新到P4的CPU都能執行babaylinux那麼請選擇386CPU,否則請按自己的實際情況選擇.
其他選項都選擇N.這些在babylinux中都是不需要的.
General setup
networking support 選擇Y
PCI support 選擇Y 除非你不用PCI裝置,不過一般人都是需要的,因為現在網路卡大部分是PCI的.
System V ipc 選擇Y
systrl support選擇Y
kernel support for ELF 選擇Y
其餘內容都可以選擇N,如果有特殊需求,比如的網路卡是ISA的,那麼請將相應的內容選上.但是不能貪心,時刻牢記,我們能利用的空間只有 1440K ,核心的大小絕不能超過 900K,任何不必要的東西都應該從核心中去除.
memory technology devices (MTD)
Parallel port support
Plug and Play configuration
以上三個大項中的所有內容選擇N
block devicesNormal floppy disk supportLoopback device supportRAM disk supportinitial RAM disk (initrd) supportPer partition statics in /proc/partitions
以上幾項選擇Y,其餘全部選擇N.
這裡的選項比較重要,我想重點說明一下.對於軟盤的支援,那是不必說的,那是必備的.
loopback device 即迴環裝置,我們平時用命令
#mount -o loop somecd.ISO /mnt/cdrom
掛裝光碟映象檔案,或者其他檔案系統映象檔案時就用到了核心中的loopback 模組,如果沒有編譯進這個模組,你將不能用上面的命令掛裝光碟映象和檔案系統映象.
個人認為這個功能是非常重要的,所以編譯了進去.
RAM disk support 即記憶體磁碟(比較貼切的說法是虛擬磁碟,即撥出一部分記憶體當做磁碟用).這是製作babylinux專案中的核心內容,由於一張軟盤的空間有限,babylinux的根檔案系統是用gzip壓縮法高度壓縮的,在執行時,將解壓縮後的檔案複製到一個RAM disk執行,所以在執行時,你在根檔案系統上的所有操作實際上是在記憶體上進行的.但是在形式上和在真正的磁碟上執行一樣.只不過放在RAM disk上的所有內容會在系統關機後全部消失.
不僅在執行babylinux時用到ramdisk,我們在製作壓縮的根檔案系統時也要用到ramdisk,學習ramdisk的使用是做一個babylinux的重要目的之一. 在linux中,還支援另外一種虛擬磁碟,叫做shm,
(shared memory),這種虛擬磁碟機制比ramdisk更加先進,ramdisk的大小是固定的,由編譯核心時候的default ram disk size 決定.預設為4096K(4M),也可以在核心裝載前加上ramdisk_size=引數來決定他的大小,但是系統一旦啟動,ramdisk的大小是不能改變的,而shm的大小卻動態的改變.預設情況下為實體記憶體的一半,當系統需要更多記憶體的時,他就自動縮小.系統記憶體富餘時,他自動增大,這樣可以充分靈活的利用記憶體空間,shm通常用來作為系統的磁碟快取記憶體,存放系統執行中的臨時檔案等.redaht 的linux在預設情況下都有shm的支援,可以用mount和df察看他的掛裝點和大小,如下命令:
[root@gucuiwen linux]# mount/dev/hda1 on / type ext3 (rw)none on /proc type proc (rw)usbdevfs on /proc/bus/usb type usbdevfs (rw)none on /dev/pts type devpts (rw,gid=5,mode=620)/dev/hda6 on /home type ext3 (rw)/dev/hda5 on /oracle type ext3 (rw)none on /dev/shm type tmpfs (rw)/dev/hda7 on /var type ext3 (rw)[root@gucuiwen linux]# df -h
檔案系統 容量 已用 可用 已用% 掛載點
/dev/hda1 2.9G 2.7G 26M 100% //dev/hda6 3.8G 1.8G 1.8G 50% /home/dev/hda5 5.7G 677M 4.8G 13% /oraclenone 125M 0 125M 0% /dev/shm/dev/hda7 711M 91M 584M 14% /var
雖然shm有這麼多的優點,我還是選擇了ramdisk,因為ramdisk可以很方便地在系統啟動的時候載入,而shm卻沒那麼容易,下面就來講一下關於核心啟動時載入ramdisk映象的相關內容.
initial RAM disk (initrd) support
即初始化ramdisk支援,這個選項讓核心有能力在核心載入階段就能裝入RAMDISK,並執行其中的內容,否則只能在系統執行階段用ramdisk ,我們平時在編譯了一個新核心後,如果你的根檔案系統用的是ext3,而你沒有把ext3編譯進核心,而只作為一個模組編譯了,那麼就需要用mkinitrd命令做一個initrd (initializtion ramdisk),這個ramdisk裡放了ext3的模組,這樣核心在載入根檔案系統前就能正確識別ext3檔案系統.否則,核心載入的最後一步就會出現kernel panic cant not find init .... 的錯誤.
在babylinux專案中,這個選項是必需的,這裡的作用是把解壓的根檔案系統映象裝入ramdisk.
Per partition statics in /proc/partitions
這個選項不是必需的,但是我發現如果我不把這個功能編譯進核心,那麼當我在掛裝檔案系統的時候會有些小問題,比如我不能以簡寫的掛裝命令來掛裝檔案系統.我不確定到底是不是這個選項的關係,但是把這個選項編譯進核心只增大一點點核心空間,所以為了避免麻煩,我把他編譯了進去.
Multi-device support (RAID and LVM)
Cryptography support (CryptoAPI)
這兩個大項全部選擇N,因為在個人用PC上,及少牽涉到這兩項,如果你真的有RAID裝置或者LVM,那麼就自己摸索著配置一下吧.
Networking options
這一大項中,只需要把下列專案編譯進核心:
Packet socket :mmapped IO
TCP/IP networking
對於IP:advanced router這項,如果你想重點把babylinux用做靜態路由軟體,那麼把這項編譯進去,而對於network packet filtering (replaces ipchains)這一項,沒有必要編譯進去了,因為busybox沒有提供iptables工具來設定包過濾防火牆.同樣,unix domain sockets這項也不必選擇,只有執行X的情況下才需要選這項.
Telephony Support 選擇N
ATA/IDE/MFM/RLL support
選擇Y,然後下面的'IDE,ATA and ATAPI Block Devices'按鈕就被啟用
下面幾項請選擇Y,其餘都可以是N.
Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support
Include IDE/ATA-2 DISK support
Auto-Geometry Resizing support
Include IDE/ATA CDROM support
如果你的核心要執行在一臺很老的pentium或486上,請把CMD640 chipset bugfix/support編譯進去,因為那時候主機板的CMD640 IDE控制晶片大多有莫名其妙的BUG,把這項編譯進去會修復這個bug.
下面幾個大項:
SCSI support
Fusion MPT device support
IEEE 1394(FireWire) support
I2O device support
全部選擇N,這裡可能有你想要的好東西,比如1394介面驅動,但是在babylinux上意義不大,而且我們的空間只有1440K.
下面一個大項:
Network device support
選擇Y,這樣就可以支援網路卡了,其餘都選擇N.然後點Ethernet(10 or 100 Mbit)按鈕選擇你需要的網路卡驅動,你可以把最常見的幾種Reltek8139,NE2000,3COM等網路卡編譯進核心.雖然網路卡的驅動通常都很小,但是不要太貪心,選2~3個就足夠了,否則你的核心就會一下子多出幾十K.在我先前編譯的babylinux核心中,我把via-rhine網路卡編譯了進去,是因為我打造babylinux的機器上只有一塊那個晶片的網路卡.
如果你發現你需要的網路卡是灰色的,不能點,那麼先確定他上一級的選項已經點了,比如你想選NE2000的網路卡,就必需先選擇ELSA,VLB,PCI and on board controllers.如果還不能點,那麼請確定是否已經把PCI的支援選項選上了,(在Geneal setup)裡.沒有PCI的支援,PCI的網路卡將不能選.
可能你是個有錢人,在自己的PC上用千兆網路卡,那麼請在千兆網路卡那一欄選擇.
接下來幾個大項:
Amateur Radio support
IrDA (infrared) support
ISDN subsystem
Old CD-ROM drivers (not SCSI,not IDE)
Input core support
全部選擇N.
接下來的Charcter devices是很重要的一項,他和Bloack devices一樣重要,我將重點講述.
除了Virtual terminal和Support for console on terminal兩項,其他全選N.
Virtual terminal 即虛擬終端,這是一般linux必備選項.否則你的linux啟動後,在螢幕看不到任何東西.另外還負責鍵盤輸入資訊等等.只有在某些嵌入式linux應用場合才會不要這個選項,因為這些linux通常都不用操作.
Support for console on terminal
在虛擬終端上的控制檯.他支援在終端上各種資訊的輸出,這也是必備的.
接下來的幾個大項:
Multimedia devices
Crypto Hardware support
全部選擇N.
再接下來的那部分File sytems可是重頭戲喔.
這部分不用我太羅嗦了吧,自己需要支援什麼就選什麼.
但是其中有三個是你必需選的:
/proc file system support 缺了他,很多命令和軟體就不能執行.
Second extended fs support BabyLinux的基本檔案系統.
ISO 9660 CDROM filesytem support 除非你不想用光碟.
另外,諸如磁碟限額(Quota support),Reiserfs的DEBUG模式(Enable reiserfs debug mode)
等就不用編譯進去了.這些東西意義不大,確要無端的增大核心大小.請牢記一點:編譯出來的核心大小不要超過900K.
Tip:是不是看的很累啊,我寫得更累,別急,核心配置部分馬上要好了.
最後一個Console drivers
這是支援linux在字元模式下高解析度顯示的核心模組.前面三個全部選擇Y,
Frame-buffer support按鈕是灰色的不能選,別急,回到第一個大選項:
Code maturity level options 選擇Y,就可以啟用這個按鈕了.
下面幾個選項需要選擇Y:
Support for framebuffer devices
VESA VGA graphics console
你也可以選擇其他的顯示卡驅動,比如nVidia的,但是VESA和VGA是通用性最好的,只要不是幾十年前的黑白顯示卡(我只聽說過,沒見過),都相容VESA和VGA,因此,為了製作好的BabyLinux的通用性,請選擇這個驅動.
Support only 8 pixels wide fonts
這個一定要選,否當你給核心傳遞vga=788引數,讓linux在字元介面下高解析度顯示的時候,系統會因為找不到合適的小字型而返回到低解析度模式.
好了!所有核心的配置工作到這裡就全部完成了,剩下的幾個大項全部選N就行了.
儲存後退出,配置程式會自動生成一個隱藏的配置檔案.config
下面是我配置好的.config檔案內容.如果你懶的自己去配置,那麼直接把這個.config複製到你的原始碼目錄下就能直接用了.(已經去掉了#開頭的註釋行)
CONFIG_X86=yCONFIG_UID16=yCONFIG_EXPERIMENTAL=yCONFIG_M586=yCONFIG_X86_WP_WORKS_OK=yCONFIG_X86_INVLPG=yCONFIG_X86_CMPXCHG=yCONFIG_X86_XADD=yCONFIG_X86_BSWAP=yCONFIG_X86_POPAD_OK=yCONFIG_RWSEM_XCHGADD_ALGORITHM=yCONFIG_X86_L1_CACHE_SHIFT=5CONFIG_X86_USE_STRING_486=yCONFIG_X86_ALIGNMENT_16=yCONFIG_X86_PPRO_FENCE=yCONFIG_NOHIGHMEM=yCONFIG_NET=yCONFIG_PCI=yCONFIG_PCI_GODIRECT=yCONFIG_PCI_DIRECT=yCONFIG_SYSVIPC=yCONFIG_SYSCTL=yCONFIG_KCORE_ELF=yCONFIG_BINFMT_ELF=yCONFIG_BLK_DEV_FD=yCONFIG_BLK_DEV_LOOP=yCONFIG_BLK_DEV_RAM=yCONFIG_BLK_DEV_RAM_SIZE=4096CONFIG_BLK_DEV_INITRD=yCONFIG_PACKET=yCONFIG_INET=yCONFIG_IP_MULTICAST=yCONFIG_IDE=yCONFIG_BLK_DEV_IDE=yCONFIG_BLK_DEV_IDEDISK=yCONFIG_IDEDISK_MULTI_MODE=yCONFIG_BLK_DEV_IDECD=yCONFIG_BLK_DEV_IDE_MODES=yCONFIG_NETDEVICES=yCONFIG_NET_ETHERNET=yCONFIG_INPUT_MOUSEDEV_SCREEN_X=1024CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768CONFIG_VT=yCONFIG_VT_CONSOLE=yCONFIG_REISERFS_FS=yCONFIG_EXT3_FS=yCONFIG_JBD=yCONFIG_FAT_FS=yCONFIG_VFAT_FS=yCONFIG_RAMFS=yCONFIG_ISO9660_FS=yCONFIG_JFS_FS=yCONFIG_NTFS_FS=yCONFIG_PROC_FS=yCONFIG_EXT2_FS=yCONFIG_MSDOS_PARTITION=yCONFIG_NLS=yCONFIG_NLS_DEFAULT="iso8859-1"CONFIG_VGA_CONSOLE=yCONFIG_VIDEO_SELECT=yCONFIG_VIDEO_IGNORE_BAD_MODE=yCONFIG_FB=yCONFIG_DUMMY_CONSOLE=yCONFIG_FB_VESA=yCONFIG_VIDEO_SELECT=yCONFIG_FBCON_CFB8=yCONFIG_FBCON_CFB16=yCONFIG_FBCON_CFB24=yCONFIG_FBCON_CFB32=yCONFIG_FBCON_FONTWIDTH8_ONLY=yCONFIG_FONT_8x8=yCONFIG_FONT_8x16=y
5,編譯核心
#make dep
#make bzImage
下面是最後編譯結果:
Boot sector 512 bytes.
Setup is 4733 bytes.
System is 845 kB
make[1]: Leaving directory `/usr/src/linux-2.4.20-8/arch/i386/boot'
我用上面的配置得到了一個845k的核心.
編譯好的核心放在/usr/src/linux-2.4.20-8/arch/i386/boot下.將他複製在一個安全的地方備用.
建立一個專放babylinux材料的目錄
#mkdir /babylinux
建立一個做babylinux根檔案系統的目錄
#mkdir /babylinux/rootfs
備份核心
#cp /usr/src/linux-2.4.20-8/arch/i386/boot/bzImage /babylinux/
七,編譯busybox
1,busybox簡介
busybox是一個整合了一百多個最常用linux命令和工具的軟體,他甚至還整合了一個http伺服器和一個telnet伺服器,而所有這一切功能卻只有區區1M左右的大小.我們平時用的那些linux命令就好比是分力式的電子元件,而busybox就好比是一個積體電路,把常用的工具和命令整合壓縮在一個可執行檔案裡,功能基本不變,而大小卻小很多倍,在嵌入式linux應用中,busybox有非常廣的應用,另外,大多數linux發行版的安裝程式中都有busybox的身影,安裝linux的時候案ctrl+alt+F2就能得到一個控制檯,而這個控制檯中的所有命令都是指向busybox的連結.
Busybox的小身材大作用的特性,給製作一張軟盤的linux帶來了及大方便.
2,busybox的用法
可以這樣用busybox
#busybox ls
他的功能就相當執行ls命令
最常用的用法是建立指向busybox的連結,不同的連結名完成不同的功能.
#ln -s busybox ls
#ln -s busybox rm
#ln -s busybox mkdir
然後分別執行這三個連結:
#./ls
#./rm
#./mkdir
就可以分別完成了ls rm 和mkdir命令的功能.雖然他們都指向同一個可執行程式busybox
但是隻要連結名不同,完成的功能就不同,busybox就是這麼的神奇.
很多linux網站都提供busybox的原始碼下載.目前版本是busybox1.0正式版.
3,配置busybox
busybox的配置程式和linux核心選單配置方式簡直一模一樣.熟悉用make menuconfig方式配置linux核心的朋友很容易上手.
#cp busybox-1.00.tar.gz /babylinux
#cd /babylinux
#tar xvfz busybox-1.00.tar.gz
#cd busybox-1.00
#make menuconfig
下面是需要編譯進busybox的功能選項,其他的可以根據需要自選,但是同樣不要太貪心.
General Configuration應該選的選項
Show verbose applet usage messages
Runtime SUID/SGID configuration via /etc/busybox.conf
Build Options
Build BusyBox as a static binary (no shared libs)
這個選項是一定要選擇的,這樣才能把busybox編譯成靜態連結的可執行檔案,執行時才獨立於其他函式庫.否則必需要其他庫檔案才能執行,在單一個linux核心不能使他正常工作.
Installation Options
Don't use /usr
這個選項也一定要選,否則make install 後busybox將安裝在原系統的/usr下,這將覆蓋掉系統原有的命令.選擇這個選項後,make install後會在busybox目錄下生成一個叫_install的目錄,裡面有busybox和指向他的連結.
其他選項都是一些linux基本命令選項,自己需要哪些命令就編譯進去,一般用預設的就可以了.
配置好後退出並儲存.
4,編譯並安裝busybox
#make
#make install
編譯好後在busybox目錄下生成子目錄_install,裡面的內容:
drwxr-xr-x 2 root root 4096 11月 24 15:28 bin
lrwxrwxrwx 1 root root 11 11月 24 15:28 linuxrc -> bin/busybox
drwxr-xr-x 2 root root 4096 11月 24 15:28 sbin
其中可執行檔案busybox在bin目錄下,其他的都是指向他的符號連結.
我編譯出來的busybox可執行檔案是935K,加上符號連結,整個_install目錄是952K.加上845K的核心不是已經超過1440K了嗎?別擔心,我們將對整個根檔案系統做大幅度的壓縮.
八,製作根檔案系統
1,基本目錄結構
#cd /babylinux/rootfs
#mkdir etc usr var tmp proc home root dev
其中etc,proc和dev是一定要建的,bin和sbin不用建,因為busybox中已經有了.
其他的可以象徵性的建幾個就可以了.
複製busybox
#cp -R /babylinux/busybox-1.00/_install/* /babylinux/rootfs/
2,建立裝置檔名
#cd /babylinux/rootfs/dev
你可以用mknod手工建立,也可以直接從原系統的/dev目錄下複製過來.
手工建立的方法:
#ls -l /dev/console
crw------- 1 root root 5, 1 11月 30 09:02 /dev/console
這樣就檢視到了console裝置的主裝置號是5,輔裝置號是1,是一個標記為C的字元裝置.
於是,我們可以用mknod建立一個同樣的裝置檔案:
#mknod console c 5 1
但是手工方法建立太麻煩了,通常直接從/dev下把需要的裝置檔案複製過來.
這些裝置檔案是特殊檔案,在複製時一定要加上-R引數才能複製.
#cp -R /dev/console ./
#cp -R /dev/null ./
#cp -R /dev/zero ./
...
以下是我認為需要的裝置名:
cdrom fd0 hda14 hda4 hdb11 hdb19 hdc hdc16 hdc6 hdd13 hdd3 loop2 ram2console fd0H1440 hda15 hda5 hdb12 hdb2 hdc1 hdc17 hdc7 hdd14 hdd4 loop3 tty0fb hda hda16 hda6 hdb13 hdb3 hdc10 hdc18 hdc8 hdd15 hdd5 loop4 tty1fb0 hda1 hda17 hda7 hdb14 hdb4 hdc11 hdc19 hdd hdd16 hdd6 loop5 tty2fb1 hda10 hda18 hda8 hdb15 hdb5 hdc12 hdc2 hdd1 hdd17 hdd7 null tty3fb2 hda11 hda19 hdb hdb16 hdb6 hdc13 hdc3 hdd10 hdd18 hdd8 ram tty4fb3 hda12 hda2 hdb1 hdb17 hdb7 hdc14 hdc4 hdd11 hdd19 initctl ram0 tty5fb4 hda13 hda3 hdb10 hdb18 hdb8 hdc15 hdc5 hdd12 hdd2 loop1 ram1 zero
其中,fd0,hda,ram,ram1,tty1,null,zero,loop1,fb0,fb等是必備的.
其它的hda,hda1,hdb等可以根據實際需要決定.但是上表中的選擇是比較合理的,即能滿足大部分的需要,有沒有不用的裝置浪費空間.注意,千萬不要把/dev下的裝置全複製過來,那將產生大約420K的/dev目錄,這對babylinux來說太大了.
3,建立etc目錄下的配置檔案
busybox.conf group inittab motd passwd resolv.conf shadow-
fstab init.d issue mtab profile shadow
其中init.d是一個目錄,從busybox-1.00原始碼目錄下複製過來.
#cp -R /babylinux/busybox-1.00/examples/bootflopyp/etc/init.d /babylinux/rootfs/etc/
busybox.conf是一個空檔案.
其他檔案的內容如下:
fstab/dev/fd0 / ext2 defaults 0 0none /proc proc defaults 0 0/dev/cdrom /mnt/cdrom udf,iso9660 noauto,owner,kudzu,ro 0 0/dev/fd0 /mnt/floppy auto noauto,owner,kudzu 0 0grouproot:x:0:rootinittab::sysinit:/etc/init.d/rcS::askfirst:/bin/shtty2::respawn:/bin/getty 38400 tty2tty3::respawn:/bin/getty 38400 tty3tty4::respawn:/bin/getty 38400 tty4# Stuff to do when restarting the init process::restart:/bin/init# Stuff to do before rebooting::ctrlaltdel:/bin/reboot::shutdown:/bin/umount -a -r::shutdown:/bin/swapoff -aissueBaby Linux release 0.1motdmtabpasswdroot::0:0:root:/root:/bin/ashprofile# /etc/profile: system-wide .profile file for the Bourne shellsechoechoexport PS1="[u@h w]$"echo "Done"alias ll='ls -l'alias du='du -h'alias df='df -h'alias rm='rm -i'echoresolv.confnameserver 202.96.209.5nameserver 202.96.209.6shadowroot:$1$$adltAB9Sr/MSKqylIvSJT/:12705:0:99999:7:::shadow-root:$1$DWU.tenP$B7ANiXoGoiZMwJR6Ih8810:12705:0:99999:7:::
其中有很多是從原系統的/etc下複製過來修改的,如果你是一個具有中等以上水平的linux愛好者,那麼應該一看就明白了,當然,你也可以根據自己的需要修改這些檔案.其中最重要的是fstab和inittab,busybox內建的init程式用到的inittab檔案的語法和一般的不一樣,不能直接把原系統/etc下inittab檔案複製過來.可以把busybox-1.00目錄下的示例檔案複製過來修改用.具體請看busybox的文件.busybox的init也可以不用inittab.但是在我製作babylinux過程中有一個非常奇怪的bug.所有/sbin下的busybox連結在做成壓縮的根檔案系統,解壓後都不能正常執行,顯示找不到該命令.只有當我在/bin下做這些連結時才能執行.具體原因還不太清除,所以你需要做下面的工作:
#cd /babylinux/rootfs/sbin
#ls
chroot getty ifconfig losetup pivot_root reboot swapoff sysctl
fdisk halt init mkswap poweroff route swapon telnetd
檢視到sbin下有上述連結
轉到bin下
#cd /babylinux/rootfs/bin
重新做這些連結:
#ln -s busybox chroot
#ln -s busybox getty
#ln -s busybox ifconfig
...
然後把sbin下的連結刪除,以節省空間
#rm -rf /babylinux/rootfs/sbin/*
再把原先inittab中所有的sbin改成bin
init.d下的檔案:
rcS
請確保這個檔案是可執行的,否則請改成可執行的:
#chmod u+x rcS
rcS的內容:
#! /bin/shmount -o remount,rw //bin/mount -a>/etc/mtabechoechoechoechoecho -en " Welcom to 33[0;32mBabyLinux33[0;39m "echo -en "33[0;36m "echoecho -en "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ "echo -en "+ This is a tiny linux system based on a floppy.It contains "echo -en "+ more than 100 basic Linux commands and tools.The kernel of "echo -en "+ this tiny system support all kinds of normal filesystems. "echo -en "+ linux ext2,ext3,jfs,reiserfs and windows fat,vfat,ntfs[readonly] "echo -en "+ is supported! So it is a powerful small system you can use it "echo -en "+ as a linux and windows rescue disk.Beside this,the kernel also "echo -en "+ contains the drivers of Reltek8139,NE2000,via-rhine ethernet "echo -en "+ adpater. you can configure the IPaddress and netmask with tools "echo -en "+ 'ifconfig' and config the default gateway with command 'route'. "echo -en "+ Is there anything else? Haha,this is a telnet server build-in "echo -en "+ you can type 'telnetd' to startd it and thus your friends can "echo -en "+ logon to your system to help you solve the problem. "echo -en "+ 33[0;32mAll these great features are powered by BusyBox 1.033[0;36m "echo -en "+ This is a free system tool developed by GuCuiwen. "echo -en "+ RUN YOUR OWN RISK of using it ! if you have any problem please "echo -en "+ mailto : win2linux@163.com Enjoy!! "echo -en "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ "echo -en "33[0;39m "hostname BabyLinux
可以自己作相應的修改.
以上是babylinux根檔案系統的所有內容,他的總大小應該在1M左右.
[root@gucuiwen baby]# du -hs
1.1M .
九,製作ramdisk映象檔案
babylinux根檔案系統所有東西都放在/babylinux/rootfs下,我們將利用ramdisk把這些內容做成ramdisk映象檔案並壓縮他.
以下主要是ramdisk的用法,看完以下內容,你應當學會ramdisk的使用.
[root@gucuiwen babylinux]# dd if=/dev/zero of=/dev/ram1
dd: 正在寫入 ‘/dev/ram1’: 裝置上沒有空間
讀入了 8193+0 個塊
輸出了 8192+0 個塊
zero是一個特殊的裝置,表示全部為0的字元塊.上面這條命令的意思是把系統的第一個ramdisk用全部為0的資料填充,因為ramdisk預設大小為4M,因此當讀滿8192個塊(每塊512位元組)後,顯示'裝置上沒空間'.這很正常,/dev/ram1已經被填充滿了.
如果指定塊的大小:
[root@gucuiwen babylinux]# dd if=/dev/zero of=/dev/ram1 bs=1M count=4
讀入了 4+0 個塊
輸出了 4+0 個塊
不會有錯誤提示,這裡演示了dd的一般用法,接下來還要頻繁用到dd命令.
在/dev下有很多ramdisk裝置,ram1,ram2,ram3....
一般用第一個就可以了.
填充後,ram1就有可空間,可以在這個空間上創見一個檔案系統:
[root@gucuiwen babylinux]# mkfs.ext2 -m0 /dev/ram1
mke2fs 1.32 (09-Nov-2002)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
1024 inodes, 4096 blocks
0 blocks (0.00%) reserved for the super user
First data block=1
1 block group
8192 blocks per group, 8192 fragments per group
1024 inodes per group
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 37 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
將ram1掛裝到檔案系統中:
先建立一個掛裝點:
#mkdir /mnt/ram
掛上ram1:
#mount /dev/ram1 /mnt/ram
將先前做好的babylinux根檔案系統複製到ram1上.
#cp -R /babylinux/rootfs/* /mnt/ram
做完以上幾步,你應就白了ramdisk裝置的含義,他是和hda1,hdb1,一樣的塊裝置,用mount掛到檔案系統下後就可以訪問,往裡放東西,但是所有的東西在記憶體上.關機將丟失所有東西.
複製好babylinux根檔案系統後解除安裝ram1:
#umount /dev/ram1
這時,雖然不能透過/mnt/ram這個掛裝點訪問ram1中的內容了,但是他卻切切實實得在記憶體中存在.
再用dd把這個ram1以映象方式取出來:
[root@gucuiwen babylinux]# dd if=/dev/ram1 of=/babylinux/ramdisk.img
讀入了 8192+0 個塊
輸出了 8192+0 個塊
驗證一下取出來的內容:
[root@gucuiwen babylinux]# file ramdisk.img
ramdisk.img: Linux rev 1.0 ext2 filesystem data
他是一個ext2 檔案系統,類似一個ISO光碟映象檔案.
因次,我們可以用loop裝置來把他重新掛裝到檔案系統裡:
[root@gucuiwen babylinux]# mount -o loop ramdisk.img /mnt/ram/
為了方便,我仍舊把他掛在/mnt/ram下,因此,在先前一定要把/dev/ram1 umount掉
檢視/mnt/ram下的內容,他應該和/babylinux/rootfs下的一模一樣,否則就是出錯了:
[root@gucuiwen babylinux]# ls /mnt/ram
bin dev etc home lost+found mnt proc root sbin tmp usr var
這樣,我們就得到了一個ramdisk根檔案系統映象:ramdisk.img
把他umount掉:
#umount /mnt/ram
如果是第一次接觸ramdisk,你可能對上述的內容很迷惑,如果這樣,請反覆閱讀和理解上面的內容,自己多動手做幾次試驗,就可以理解.
壓縮ramdisk.img印象檔案:
[root@gucuiwen babylinux]# gzip -v9 ramdisk.img
ramdisk.img: 87.9% -- replaced with ramdisk.img.gz
檢視壓縮後的大小:
[root@gucuiwen babylinux]# ls -lh ramdisk.img.gz
-rw-r--r-- 1 root root 495K 11月 30 11:32 ramdisk.img.gz
我得到的壓縮ramdisk映象檔案安是495K. 加上核心的845K,是1340K
符合公式:
核心大小+檔案系統壓縮印象檔案+50K <= 1440K
如果你做出來的kernel和ramdisk.img.gz太大了,請重新制作kernel或ramdisk.img.gz,在其中做一些取捨,如果你的kernel和ramdisk.img.gz太小了,那麼可以再往裡面新增一些內容,使你的babylinux功能更強.
十,核心與busybox的整合
準備一張完好的空白軟盤
建立一個比核心大小略大的檔案系統:
比如核心大小是845K,那麼我我創見一個920K的檔案系統:
#mkfs.ext2 -m0 /dev/fd0 920
如果空間允許,還可以再大一些,但是必需保證
1440K-檔案系統大小>=ramdisk.img.gz的大小.
掛上軟盤
#mount /dev/fd0
將核心複製到軟盤:
#cp /babylinux/bzImage /mnt/floppy/
將lilo引導檔案安boot.b 複製到軟盤
#cp /boot/boot.b /mnt/floppy
新建一個lilo.conf 配置檔案:
prompttimeout=60default=linuxboot=/dev/fd0map=/mnt/floppy/mapinstall=/mnt/floppy/boot.blinearimage=/mnt/floppy/bzImagelabel=linuxread-onlyvga=788root=/dev/fd0append="load_ramdisk=1 ramdisk_start=940"
vga=788表示讓核心支援字元介面的高解析度顯示,你可以改成vga=ask,這樣可以在啟動的時候選擇解析度.
紅色一行是關鍵,load_ramdisk=1告訴核心在啟動的時候轉載壓縮的ramdisk印象檔案,
ramdisk_start=940 告訴核心從軟盤的第940K的地方去尋找並裝載壓縮的ramdisk印象檔案.
關於ramdisk的用法和更多引數請檢視linux0核心文件/usr/src/linux/Documents/ramdisk.txt
接下來再用dd命令把ramdisk.img.gz裝到軟盤上.
#dd if=/babylinux/ramdisk.img.gz of=/dev/fd0 bs=1k seek=940
這裡的seek=940 表示把ramdisk.img.gz裝到軟盤的第940K開始的地方.
詳細內容請看dd的聯機文件 man dd
為什麼要從940k開始呢?
因為剛才作了一個920K的檔案系統.我把他裝在檔案系統20K以後的地方.
當然,如果你的空間十分緊張,連這20K都不捨得浪費,那麼可以這樣:
#dd if=/babylinux/ramdisk.img.gz of=/dev/fd0 bs=1k seek=921
當然,別忘記修改lilo.conf檔案. ramdisk_start=921
接下來裝lilo載入程式就大功告成了.
#lilo -C lilo.conf
如果你的磁碟上還有一點點空餘空間,那麼可以把lilo.conf也複製上去,以備將來使用.
#cp lilo.conf /mnt/floppy
#umount /dev/fd0
整個工程已經完成了,你可以重新啟動機器,設定電腦從軟盤啟動.看看有沒有成功.
十一,安裝測試和內容調整
如果在整合核心和ramdisk映象過程中,出現磁碟空間不夠的情況,請重新編譯核心和busybox
可以根據實際需要,調整核心和busybox,比如你要核心支援很多東西,但是隻需要一個支援50個命令的busybox,那麼可以自己做相應調整.
十二,babylinux中的BUG
有些命令的輸出結果會有偏差,比如用 busybox的df 看磁碟使用情況,和實際的不一樣.
十三,接下來要做的事情
做一個基於64M 隨身碟的linux小系統.
計劃支援如下特徵:
a.軟盤babylinux的所有功能
b.圖形介面的支援.
c.一個輕量級的視窗管理器(window maker)
d.網路的支援,
e.至少一個圖形web瀏覽器,可以上網.
f.一個音樂播放器和一個影片播放器.
g.支援中文的顯示和輸入.
h.可以修改配置並儲存資料
我還計劃做一個live CD,但是目前已經有很多live CD了,而且都做的非常好.
但是我會自己做一個作為學習linux的一種手段.如果有時間,可能寫一個做隨身碟linux和live CD
的教程.但是,我想不會寫的和這個文件一樣詳細了,我的時間有限.可能大概講一下原理和步驟.有經驗的linux愛好者應該可以透過閱讀文件完成製作.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-939906/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Toolbar製作選單條過程詳解 (轉)
- Redis複製過程詳解Redis
- 轉:DNS解析過程詳解DNS
- LumaQQ安裝過程詳解(轉)
- MapReduce 過程詳解 (用WordCount作為例子)
- [轉]:xmake編譯配置過程詳解編譯
- Nginx支援Socket轉發過程詳解Nginx
- [譯] 製作 Vue 3 的過程Vue
- 轉[Android]APK打包過程詳解(一)AndroidAPK
- 轉[Android]APK打包過程詳解(二)AndroidAPK
- MapReduce過程詳解
- 遊戲製作詳解自----OpenGL入門教程(九)(轉)遊戲
- 遊戲製作詳解自----OpenGL入門教程(五)(轉)遊戲
- 遊戲製作詳解自----OpenGL入門教程(四)(轉)遊戲
- [轉]反向代理過程與Nginx特點詳解Nginx
- Laravel + Vue 製作一款標籤選擇器(詳細過程)LaravelVue
- 奧巴馬籌款網站的製作過程網站
- QQ黑市揭密:被盜到出售過程詳解(轉)
- PHP 協程實現過程詳解PHP
- MySQL儲存過程詳解 mysql 儲存過程MySql儲存過程
- SSL/TLS 握手過程詳解TLS
- RabbitMQ安裝過程詳解MQ
- mongo 儲存過程詳解Go儲存過程
- 【elasticsearch】搜尋過程詳解Elasticsearch
- nagios配置過程詳解iOS
- mysql儲存過程詳解MySql儲存過程
- 儲存過程的詳解儲存過程
- oracle建庫過程詳解Oracle
- 網站製作過程中把握的幾點網站
- 例項詳解不同VLAN間通訊(轉發過程)
- 如何在Oracle中使用Java儲存過程(詳解)(轉)OracleJava儲存過程
- 網路組網七類水晶頭製作方法,七類網線製作過程
- Windows下Jekyll配置過程詳解Windows
- Hive SQL 編譯過程詳解HiveSQL編譯
- Linux啟動過程詳解Linux
- 【玩壞 MV】製作音遊的思路過程(2)
- 【玩壞 MV】製作音遊的思路過程(1)
- 企業展廳設計製作的過程分析