[轉貼]DIY:自己動手做一個迷你 Linux 系統

常言道:『飲水思源』,在 Open Source 的世界裡,我們常常需要別人的幫助,但是在您有所心得的時候請記得分享給大家,『幫助人是快樂的喔』。歡迎您在使用 debian 的過程中的任何心得分享給大家。

[轉貼]DIY:自己動手做一個迷你 Linux 系統

文章moto » 週五 12月 13, 2002 12:59 pm

作者: jserv ( ) 站內: embedded
標題: [轉錄] DIY:自己動手做一個迷你 Linux 系統
時間: Wed Nov 27 00:36:02 2002

發信人: Quotation (不是主席的語錄), 信區: Linux
標 題: zz:DIY:自己動手做一個迷你 Linux 系統
發信站: BBS 水木清華站 (Sat Nov 16 21:30:39 2002), 轉信

http://www-900.ibm.com/developerWorks/c ... ndex.shtml
DIY:自己動手做一個迷你 Linux 系統
內容:
目標
系統啟動
編譯內核
busybox
從啟動到進入 shell
安排文件系統
X Window
其它技巧
參考資料
關於作者
在 Linux 專區還有:
教程
工具與產品
代碼與組件
文章

趙蔚 (zhaoway@public1.ptt.js.cn)
自由職業者
2002 年 9 月

本文將帶領大家構建一個迷你型的 Linux 系統。它佔用的硬盤空間遠小於 16M 字節
,但是卻包括了 XFree86 的 X Window 窗口系統。

目標

本文要構建的這個迷你型的 Linux 系統隻能在一台特定的單機上運行,如果讀者朋友們
有興趣的話,在這個系統的基礎上加以改進,是可以構建出通用的、可以在大多數常規
PC
機上即插即用的系統來的。但是這已經不在本文的話題之內了,讀者朋友們如果有興趣,
可以通過我的電子郵件和我討論其中的細節問題。

我們的目標 Linux 系統運行在一台普通的 Intel 386 PC 機上,可以有硬盤,也可以不
要硬盤,而用 Flash Disk 來代替。如果是用 Flash 盤的話,需要能夠支持從 Flash 盤
啟動,而且 Flash 盤的大小要在 16M 字節或者以上。我們希望用戶一開機啟動,就直接
進入 X Window
圖形界面,運行事先指定好的程序。不需要用戶輸入用戶名和密碼進行登錄。

我們設定的這個目標有點像一個 X Terminal 終端工作站。稍加改進,還可以做成幹脆無
盤的形式,也就是說,連 16M 的 Flash 盤也不要了。不過,這也超出了本文的話題了。
讀者朋友們如果有興趣,可以來信和我進行討論。

系統啟動

因為我們要考慮從 Flash 盤進行啟動,所以我們選擇用 LILO 作為我們的 Boot Loader
,而不選用 GRUB。這是考慮到 GRUB 有較強的對硬盤和文件系統的識別能力,而 Flash
盤到底不是標準的硬盤,並且我們選用的文件系統 GRUB 又不一定認識,搞不好的話
GRUB 反 會弄巧成拙。而
LILO 就簡單的多了,它在硬盤開始的 MBR 寫入一個小程序,這個小程序不經過文件系統
,直接從硬盤扇區號,讀出 Kernel Image 裝入內存。這樣,保險系數就大大增加。並且
也給了我們自由選用文件系統的余地。那麼,我們要如何安裝 LILO 呢?

首先,我們要找一塊普通的 800M 左右的 IDE 硬盤,連在目標機器的 IDE 線上。這樣在
我們的目標機器上,IDE1 上掛的是 Flash 盤,IDE2 上掛的是一塊工作硬盤。我們用標
準的步驟在 IDE2 的標準硬盤上裝上一個 Debian GNU/Linux 系統。當然,如果讀者朋友
們手頭沒有
Debian,也可以裝 Red Hat 系統。裝好工作系統之後,要首先做一些裁減工作,把不必
要的 Service 和 X Window 等等東西都刪掉。這樣做的目的是增進系統啟動速度,因為
我們在後面的工作中,肯定要不停的重新啟動機器,所以啟動速度對我們的工作效率是很
關鍵的。

裝好工作系統之後,在 Falsh 盤上做一個 Ext2 文件系統,這個用 mke2fs 這個命令就
可以完成。由於 Flash 盤是接在 IDE1 上的,所以在 Linux 裡面,它的身份是
/dev/hda。本文作者在操作的時候,把整個 Flash 盤劃分了一個整個的分區,所以,調
用 mke2fs 的時候,處理的是
/dev/hda1。讀者朋友們應該可以直接在 /dev/hda 上做一個 Ext2 文件系統,而不用事
先分區。

在 Flash 盤上做好了文件系統之後,就可以把一個編譯好的內核映像文件 vmlinuz 拷貝
到 Flash 盤上了。注意,必須要先把這個 vmlinuz 映像文件拷貝到 Flash 盤上,然後
才能在 Flash 盤上安裝 LILO。不然的話,LILO 到時候可是會 LILILILI 打結巴的,因
為它會找不到 Kernel
Image 在 Flash 盤上的位置的,那樣的話 Flash 盤也就啟動不起來了。還有,如果讀者
朋友們在 Flash 盤上用的是一個壓縮的文件系統的話,到時候 LILO 也會出問題,它雖
然能正確的找到 Kernel Image 在硬盤上的起始位置,但是它卻沒有辦法處理被文件系統
重新壓縮過的這個
Kernel Image,不知道該如何把它展開到內存中去。

把 Kernel Image 拷貝過去以後,我們就可以動手編輯一份 lilo.conf 文件,這份文件
可以就放在工作系統上就行了。但是注意在 lilo.conf 中索引的文件名的路徑可要寫對
。這些路徑名都是在工作系統上看上去的路徑名。比如,如果 Flash 盤 Mount 在 /mnt
目錄下面,那麼,在
lilo.conf 中,vmlinuz 的路徑名就是 /mnt/vmlinuz。注意這一點千萬不要搞錯。不然
的話,如果一不小心把工作系統的 LILO 給破壞掉了,那就麻煩了。編輯好了 lilo.conf
,然後再運行 lilo 命令,注意,要告訴它用這個新的 lilo.conf 文件,而不要用
/etc/lilo.conf。

安裝好 LILO 之後,我們可以立即重新啟動,測試一下。首先在 BIOS 裡面,設置成從
IDE1 開始啟動,如果我們看到 LILO 的提示符,按回車後還能看到 Kernel 輸出的消息
,這就算是 LILO 的安裝成功了。記得這個操作的方法,以後每次我們更新 Flash 盤上
的 Kernel
Image,都記得要更新 LILO。也就是說,要重新運行一遍 lilo 命令。

編譯內核

試驗成功 LILO 的安裝以後,我們開始考慮編譯一個新的內核。當然,要編譯新的內核,
我們首先要進入我們的工作系統。這裡有兩個辦法進入工作系統,一是在 BIOS 裡面設置
從 IDE2 啟動,當然,這就要求當初安裝工作系統的時候,要把 LILO 安裝在 /dev/hdb
上;另一個辦法是還是從 IDE1 啟動,不改變 BIOS 的設置,但是在看到 LILO 的提示符
的時候,要鍵入 linux root=/dev/hdb1,最前面的 linux 是在 lilo.conf 裡面定義的
一個 entry,我們隻採用這個 entry 所指定的 Kernel Image,但是用 /dev/hdb1 作為
root
文件系統。兩個辦法可能有的時候一個比另一個好,更方便一些。這就要看具體的情況了
。不過,它們的設置並不是互相沖突的。

在編譯內核的時候,由於我們的內核是隻有一台機器使用的,所以我們應該對它的情況了
如指掌;另外一方面,為了減低不必要的復雜性,我們決定不用 kernel module 的支持
,而把所有需要的東西直接編譯到內核的裡面。這樣編譯出來的內核,在一台普通的
586
主板上,把所有必要的功能都加進去,一般也不到 800K 字節。所以,這個辦法是可行的
。而且減低了 init scripts 的復雜程度。從運行方面來考慮,由於需要的 kernel 代碼
反正是要裝載到內存中的,所以並不會引起內存的浪費。

在我們的目標平台上,我們希望使用 USB 存儲設備。還有一點要注意的,就是對 Frame
buffer 的支持。這主要是為了支持 XFree86。一般說來,如果我們的顯卡是 XFree86 直
接支持的,那當然最好,也就不需要 frame buffer 的內核支持。但是如果 XFree86
不支持我們的顯卡,我們可以考慮用 VESA 模式。但是 XFree86 的 VESA 卡支持運行起
來不太漂亮,還有安全方面的問題,有時在啟動和退出 X Window 的時候會出現花屏。所
以我們可以採用 kernel 的 vesa 模式的 frame buffer,然後用 xfree86 的 linux
frame buffer
的驅動程序。這樣一般就看不到花屏的現象了,而且安全方面也沒有任何問題。

devfs 也是我們感興趣的話題。如果 kernel 不使用 devfs,那麼系統上的 root 文件系
統就要有 /dev 目錄下面的所有內容。這些內容可以用 /dev/MAKEDEV 腳本來建立,也可
以用 mknod 手工一個一個來建。這個方法有其自身的好處。但是它的缺點是麻煩,而且
和 kernel
的狀態又並不一致。相反的,如果使用了 devfs,我們就再也不用擔心 /dev 目錄下面的
任何事情了。/dev 目錄下面的項目會有 kernel 的代碼自己負責。實際使用起來的效果
,對內存的消耗並不明顯。所以我們選擇 devfs。

busybox

有了 LILO 和 kernel image 之後,接下來,我們要安排 root 文件系統。由於 flash
盤的空間隻有 16M 字節,可以說,這是對我們最大的挑戰。這裡首先要向大家介紹小型
嵌入式 Linux 系統安排 root 文件系統時的一個常用的利器:BusyBox。

Busybox 是 Debian GNU/Linux 的大名鼎鼎的 Bruce Perens 首先開發,使用在 Debian
的安裝程序中。後來又有許多 Debian developers 貢獻力量,這其中尤推 busybox 目前
的維護者 Erik Andersen,他患有癌癥,可是卻是一名優秀的自由軟件開發者。

Busybox 編譯出一個單個的獨立執行程序,就叫做 busybox。但是它可以根據配置,執行
ash shell 的功能,以及幾十個各種小應用程序的功能。這其中包括有一個迷你的 vi
編輯器,系統不可或缺的 /sbin/init 程序,以及其他諸如 sed, ifconfig, halt,
reboot, mkdir, mount,
ln, ls, echo, cat ... 等等這些都是一個正常的系統上必不可少的,但是如果我們把這
些程序的原件拿過來的話,它們的體積加在一起,讓人吃不消。可是 busybox 有全部的
這麼多功能,大小也不過 100K 左右。而且,用戶還可以根據自己的需要,決定到底要在
busybox
中編譯進哪幾個應用程序的功能。這樣的話,busybox 的體積就可以進一步縮小了。

使用 busybox 也很簡單。隻要建一個符號鏈接,比方 ln -s /bin/busybox /bin/ls,那
麼,執行 /bin/ls 的時候,busybox 就會執行 ls 的功能,也會按照 ls 的方式處理命
令行參數。又比如 ln -s /bin/busybox /sbin/init,這樣我們就有了系統運行不可或缺
的 /sbin/init
程序了。當然,這裡的前提是,你在 busybox 中編譯進去了這兩個程序的功能。

這裡面要提出注意的一點是,busybox 的 init 程序所認識的 /etc/inittab 的格式非常
簡單,而且和常規的 inittab 文件的格式不一樣。所以讀者朋友們在為這個 busybox 的
init 寫 inittab 的時候,要注意一下不同的語法。至於細節,就不在我們這裡多說了
,請大家參考
Busybox 的用戶手冊。

從啟動到進入 shell

busybox 安裝好以後,我們就可以考慮重新啟動,一直到進入 shell 提示符了。這之前
,我們要準備一下 /etc 目錄下的幾個重要的文件,而且要把 busybox 用到的 library
也拷貝過來。

用 ldd 命令,後面跟要分析的二進制程序的路徑名,就可以知道一個二進制程序,或者
是一個 library 文件之間的互相依賴關系,比如 busybox 就依賴於 libc.so 和
ld-linux.so ,我們有了這些知識,就可把動手把所有需要的 library 拷貝到 flash 盤
上。由於我們的 flash
盤說大不大,說小倒也不小,有 16M 字節之多。我們直接就用 Glibc 的文件也沒有太多
問題。如果讀者朋友們有特殊的需要,覺得 Glibc 太龐大了的話,可以考慮用 uClibc,
這是一個非常小巧的 libc 庫,功能當然沒有 Glibc 全,但是足夠一個嵌入式系統使用
了。本文就不再介紹
uClibc 了。

庫程序拷貝過來以後,我們就可以考慮系統啟動的步驟了。啟動的時候,先是 lilo,接
下來就是 kernel,kernel 初始化之後,就調用 /sbin/init,然後由 init 解釋
/etc/inittab 運行各種各樣的東西。inittab 會指導 init 去調用一個最重要的系統初
始化程序
/etc/init.d/rcS,我們將要在 rcS 中完成各個文件系統的 mount,此外,還有在 rcS
中調用 dhcp 程序,把網絡架起來。rcS 執行完了以後,init 就會在一個 console 上,
按照 inittab 的指示開一個 shell,或者是開 getty +
login,這樣用戶就會看到提示輸入用戶名的提示符。我們這裡為了簡單起見,先直接進
入 shell,然後等到調試成功以後,再改成直接進入 X Window。

關於 inittab 的語法,我們上面已經提到過了,希望讀者朋友們去查權威的 busybox 的
用戶手冊。這裡,我們先要講一下文件系統的構成情況。

安排文件系統

大家已經看到,我們的 root 文件系統為了避免麻煩,用的是標準的 ext2 文件系統。由
於我們的硬盤空間很小,隻有不到 16M,而且我們還要在上面放上 X Window,所以,如
果我們全部用 ext2 的話,Flash
盤的有限空間會很快耗盡。我們唯一的選擇是採用一個適當的壓縮文件系統。考慮到
/usr 目錄下面的內容在系統運行的時候,是不需要被改寫的。我們決定選擇隻讀的壓縮
文件系統 cramfs 來容納 /usr 目錄下面的全部內容。

cramfs 是 Linus Torvalds 本人開發的一個適用於嵌入式系統的小文件系統。由於它是
隻讀的,所以,雖然它採取了 zlib 做壓縮,但是它還是可以做到高效的隨機讀取。既然
cramfs
不會影響系統讀取文件的速度,又是一個高度壓縮的文件系統,對於我們,它就是一個相
當不錯的選擇了。

我們首先把 /usr 目錄下的全部內容制成一個 cramfs 的 image 文件。這可以用
mkcramfs 命令完成。得到了這個 usr.img 文件之後,我們還要考慮怎樣才能在系統運行
的時候,把這個 image 文件 mount 上來,成為一個可用的文件系統。由於這個 image
文件不是一個通常意義上的
block 設備,我們必須採用 loopback 設備來完成這一任務。具體說來,就是在前面提到
的 /etc/init.d/rcS 腳本的前面部分,加上一行 mount 命令:


mount -o loop -t cramfs /usr.img /usr

這樣,就可以經由 loopback 設備,把 usr.img 這個 cramfs 的 image 文件 mount 到
/usr 目錄上去了。哦,對了,由於要用到 loopback 設備,讀者朋友們在編譯內核的時
候,別忘了加入內核對這個設備的支持。對於系統今後的運行來說,這個 mount 的效果
是透明的。cramfs
的壓縮效率一般都能達到將近 50%,而我們的系統上絕大部分的內容是位於 /usr 目錄下
面,這樣一來,原本可能要用到 18M 的 Flash 盤,現在可能隻需要 11M 就可以了。一
個 14M 的 /usr 目錄,給壓縮成了僅僅 7M。

上面考慮了壓縮問題,下面還要考慮到,Flash 盤畢竟不像普通硬盤,多次的擦寫畢竟不
太好,所以我們考慮,在需要多次擦寫的地方,使用內存來做。這個任務,我們考慮用
tmpfs 來完成。至於 tmpfs 和經典的 ramdisk 的比較,我們這裡就不多說了。一般說來
,tmpfs
更加靈活一些,tmpfs 的大小不像 ramdisk,可以順著用戶的需要增長或者縮小。我們選
擇把 /tmp、/var 等幾個目錄做成 tmpfs。這隻需要我們在 /etc/fstab 裡面加上兩行類
似下面的文字就可以了:


none /var tmpfs default 0 0

然後別忘了在 /etc/init.d/rcS 裡面靠近開頭的地方,加上 mount -a。這樣,就可以把
/etc/fstab 裡面指定的所有的文件系統都 mount 上來了。

X Window

進行到這裡,讀者朋友們可能會以為,X Window 的安裝可能會很復雜。其實不然,由於
我們上面的架子搭好了,X Window 的安裝非常簡單,隻需要把幾個關鍵的程序拷貝過來
就可以了。一般說來,隻需要 /usr/X11R6 目錄下面的 bin 和 lib
兩個目錄。然後,根據用戶各自的需要,還可以做大幅的裁減。比如,如果你的局域網上
有一個開放的 xfs 字體服務器的話,你可以把所有本地的字體都刪掉,而使用遠端的字
體服務器。如果隻需要運行有限的程序,別忘了把沒有用的 library 都刪掉。此外,還
可以把多余的 X
Window 的 driver 都刪掉,隻保留本機的顯示卡所需要的 driver 就可以了。

當然,這一關免不了要做多次測試。

其它技巧

如果你的工作系統式在另外一台機器上,通過局域網和本機互聯的話,ssh 是一個不錯的
工具。此外,ssh 中帶的 scp 用起來和普通的 cp 拷貝程序差不多,非常方便。用 ssh
和 scp 來共享文件,遠程試驗,你就可以不需要在辦公室裡跑來跑去的了。

如果你需要一個 MS Windows 上運行的 X Server 和 xfs 字體服務器,可以考慮包括在
Red Hat 的 Cygwin 工具箱中的 XFree86 系統。

參考資料

1. BusyBox 的站點:http://www.busybox.net
2. Linux From Scratch,自己動手,從頭開始做一個 Linux 系統:
http://www.linuxfromscratch.org
3. uClibc 的站點:http://www.uclibc.org
4. Cygwin 的站點:http://www.cygwin.com

關於作者

趙蔚,自由職業者。我的網絡日記位於 http://www.advogato.org/person/zhaoway/
上面列有我在網絡上發表的其它的文章。歡迎讀者朋友們來信和我討論問題。
頭像
moto
摩托學園站長
摩托學園站長
 
文章: 2808
註冊時間: 週二 9月 03, 2002 3:37 am
來自: 台北

回到 share

誰在線上

正在瀏覽這個版面的使用者:沒有註冊會員 和 1 位訪客