前言
大家可能見到過很多在軟盤上運行的Linux系統,可在軟盤上運行的FreeBSD反而比較少,雖然有PICOBSD,然而很多時候PICOBSD並不能滿足我們的需要,那麼可不可以自己制作一個在軟盤上運行的FreeBSD系統呢?答案是肯定的。我在維護著一個Floppy Firewall的Project,它是一個基於FreeBSD和IPFilter的運行在軟盤上的防火牆系統,很多網友在使用了Floppy Firewall之後發郵件來詢問如何使FreeBSD運行在一張小小的軟盤上。但由於前段時間事情太多一直沒有時間,今天終於找到時間,所以把制作在軟盤上運行的FreeBSD的過程寫出來與大家分享,由於時間倉促,文中難免有錯誤之處,還請大家指教。
1、FreeBSD的啟動過程簡介
當BIOS讀入MBR之後,MBR中的程序讀入硬盤FreeBSD Slice(FreeBSD分區)中的引導程序,引導程序默認情況下會加載/boot/loader,然後loader將加載/kernel,此時 kernel開始檢測一些硬件和做一些初始化。初始化完成後kernel將mount root device,然後啟動系統初始化進程/sbin/init,init將根據/etc/rc中的設置來進行初始化等。
可以看出我們需要解決的部分就是:引導程序 -> /boot/loader -> /kernel -> /sbin/init -> /etc/rc在了解了啟動過程之後和問題所在之後,我們便可以開始制作軟盤上的FreeBSD了。
2、初始化軟盤
首先要做的就是要將軟盤初始化,包括設置disklabel和創建文件系統(格式化成ufs格式)。
bsd# disklabel -r -w fd0a fd1440
接下來是安裝引導程序。
bsd# disklabel -B fd0a
現在軟盤已經能夠引導了,但因為我們要在它上面放置程序,所以要創建文件系統。
bsd# newfs fd0a
剛才已經做好了引導程序,因為引導程序會加載/boot/loader,所以我們還需要將系統中的/boot/loader復制到軟盤中。
QQRead.com 推出數據恢復指南教程 數據恢復指南教程
數據恢復故障解析
常用數據恢復方案
硬盤數據恢復教程
數據保護方法
數據恢復軟件
專業數據恢復服務指南
bsd# mkdir /fd
bsd# mount /dev/fd0a /fd
bsd# mkdir /fd/boot
bsd# cp /boot/loader /fd/boot/loader
根據FreeBSD的啟動過程,現在我們已經准備好了引導程序和loader,接下來就要准備內核了。
3、定制內核
軟盤的空間有限,所以我們需要定制一個小內核,而不能直接使用系統原來的內核。由於我們只使用軟盤,所以內核中的關於scsi、ata、atapi和raid等這些東西都應該刪除,因為我們不需要IPv6所以INET6也應該刪除,具體留下些什麼要看自己的用途了,這沒有什麼標准。不過有幾樣是必須的:
options MFS # 內存文件系統支持
options MD_ROOT # 使用MD(內存磁盤)設備做root
options UFS # UFS文件系統支持
options UFS_ROOT # UFS ROOT
pseudo-device md # MD設備支持
下面是我使用的一個內核配制文件:
#
# GENERIC -- Generic kernel configuration file for FreeBSD/i386
#
#
# $FreeBSD: src/sys/i386/conf/GENERIC,v 1.246.2.38 2002/01/25 17:41:40 murray EXP $
machine i386
cpu I386_CPU
cpu I486_CPU
cpu I586_CPU
cpu I686_CPU
ident "MINI-KERNEL"
maxusers 0
#maxusers最好讓系統自動分配,如果設得過大,會占用過多的內存。
options INET #InterNETworking
options FFS #Berkeley Fast Filesystem
options FFS_ROOT #FFS usable as root device [keep this!]
options MFS #Memory Filesystem
options MD_ROOT #MD is a potential root device
options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!]
options NO_SWAPPING #Disable swap
device isa
device pci
# Floppy drives
device fdc0 at isa? port IO_FD1 irq 6 drq 2
device fd0 at fdc0 drive 0
# atkbdc0 controls both the keyboard and the PS/2 mouse
device atkbdc0 at isa? port IO_KBD
device atkbd0 at atkbdc? irq 1 flags 0x1
device vga0 at isa?
# syscons is the default console driver, resembling an SCO console
device sc0 at isa? flags 0x100
# Floating point support - do not disable.
device npx0 at nexus? port IO_NPX irq 13
# PCI Ethernet NICs that use the common MII bus controller code.
# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs!
device miibus # MII bus support
device fxp # Intel EtherExpress PRO/100B (82557, 82558)
device rl # RealTek 8129/8139
device xl # 3Com 3c90x
device lnc0
at isa? port 0x280 irq 10 drq 0 # VMware Nic
# Pseudo devices - the number indicates how many units to allocate.
pseudo-device loop # Network loopback
pseudo-device ether # Ethernet support
pseudo-device md # Memory "disks"
上面的內核基本上是一個系統要運行的最小配制了,當然如果你的機器不同具體也不同,大家按自己的情況來定,我的機器配制是:
CPU: Pentium III 733Mhz
MotherBoard: Via 693A Chipset
NIC: Realtek 8139c
當配制好之後就是編譯內核了,建議大家使用config的方式來編譯,注意,最後不要使用make install,否則你原來的內核會被替換。
bsd# cd /sys/i386/conf
bsd# config MINI
bsd# cd ../../compile/MINI
bsd# make depend && make kernel
編譯完成後就會成生kernel這個文件,這時它的體積還是比較大,不過現在不用管它,後面將會介紹如何處理它。
4、編譯系統程序
現在就要准備系統所需要的基本程序了,首先最基本的是init和sh,init是所有進程的父進程,它負責進行一些初始化工作,它將是kernel引導完成後要運行的第一個用戶進程,而sh用於解釋/etc/rc中的命令。在UNIX中大部程序都使用了共享庫,這有利減少磁盤空間的占用,這對於使用硬盤是非常有用的,然而對於軟盤就不太適用了,因為單一個大部分程序都要使用的庫libc.so就有500多K,加上其它的庫軟盤根本就裝不下。
我們可以發現,大部分時候一個程序只是用到了庫中的某個函數,但同樣也要加載整個庫,所以我們可以使用靜態編譯來使程序只包含它使用的那部分函數,這樣可以減少程序的大小。
不過這樣問題同樣存在,如果只有少數程序這到沒有什麼,一旦程序很多時,那麼空間問題同樣存在。如果會C語言的朋友都知道,其實每一個程序中有很大一部分函數是相同的,比如printf,這個函數在大部分程序中都會用到,如果每個程序都包含一段printf的代碼,那麼如果有100個程序的話,就會包含 100個這樣的代碼,然而這些代碼都是相同的,實際上有99個都是浪費了空間,那麼可不可以讓一些程序在靜態編譯的情況下也能夠共享一些函數呢?要知道答案,往下接著看。
幸好,PICOBSD為我們提供了這樣的一個機制,使得程序即不用加載標准庫也可以利用其它程序中的相同函數,這就是crunch(crunch好像是世界頂級黑客高手John Draper的網名,不知道這與他有沒有關系。crunch是將所有需要的軟件編譯在一個文件中即crunch,然後當中的程序通過symbol link的方式link到它上面,這樣便可以使用相應的程序(類似於linux中的busybox),同時又節約了空間。PICOBSD為我們提供了一個自己定制crunch的機會,在FreeBSD4.5 Release(注:4.8 Release中的crunch無法定制,至少我沒有找到,所以建議大家使用4.5)中,crunch的配制文件是 /usr/src/release/picobsd/custom/crunch1/crunch.conf,編輯它以選擇你需要哪些軟件,下面以一個例子來說明它的用法。
# $FreeBSD: src/release/picobsd/router/crunch.conf,
v 1.1.2.2 2001/02/20 02:53:35 luigi Exp $
#
# NOTE: the string "/usr/src" will be automatically replaced with the
# correct value set in 'build' script - you should change it there
# Default build options
buildopts -DNOPAM -DRELEASE_CRUNCH -DNOSECURE -DNOCRYPT -DNONETGRAPH -DNOIPSEC
# other sources
srcdirs /usr/src/bin
srcdirs /usr/src/sbin/i386
srcdirs /usr/src/sbin
srcdirs /usr/src/usr.bin
srcdirs /usr/src/usr.sbin
srcdirs /usr/src/gnu/usr.bin
srcdirs /usr/src/gnu/usr.sbin
srcdirs /usr/src/libexec
# sources for ns & vm
srcdirs /usr/src/release/picobsd/tinyware
以下為你所需要在crunch包含的程序列表,以空格分隔。
progs dmesg ping ifconfig route hostname
progs cp rm ls cat test mkdir less
progs uname sysctl
progs init sh reboot
QQread.com
推出各大專業服務器評測 Linux服務器的安全性能
SUN服務器
HP服務器
DELL服務器
IBM服務器
聯想服務器
浪潮服務器
曙光服務器
同方服務器
華碩服務器
寶德服務器
ln是表示建立一個別名,如ln less more,表示當執行more的時候實際上是執行less,ln less more。以下是指定編譯時需要的庫:
libs -lncurses -lmytinfo -lipx
libs -lz -lpcap -lalias
libs -ledit -lutil -lmd -lcrypt -lmp -lgmp -lm -lkvm
libs -lgnuregex -ltelnet
當編輯好crunch.conf之後,你就可以開始編譯crunch了:
bsd# make
這時會生成一個名為crunch1的程序,我們要的就是它了。
5、建立內存磁盤
大家可以看到crunch1加上我們剛才編譯的內核和loader程序,已經超出了軟盤的容量,同時為了加速程序的運行我們需要使用MD(內存磁盤)來解決這個問題,MD將作為系統的根文件系統和用來存放系統程序。對於內存磁盤的大小一般不易太大,因為這樣會占用過多的內存,下面我們就以建立一個3M的內存磁盤為例說明如何建立內存磁盤:
bsd# cd /root
bsd# dd if=/dev/zero of=bsd bs=1k count=3072 # 生成一個3M的文件,用來做MD
bsd# vnconfig -c -s labels vn0c bsd
# 使用bsd來創建一個vn設置,以便在其中存放程序
bsd# disklabel -w -r vn0c auto # 建立disklabel
bsd# disklabel -B vn0c # 安裝啟動代碼
bsd# newfs vn0c # 創建UFS文件系統
bsd# mount /dev/vn0c /mnt # 將vn0c即bsd mount到/mnt
接下來要做的就是建立目錄結構,具體建立哪些目錄這要視需要決定,本例中需要建立如下目錄:
bsd# mkdir /mnt/etc
bsd# mkdir /mnt/sbin
bsd# mkdir /mnt/bin
bsd# mkdir /mnt/dev
然後將crunch1復制到/mnt/sbin中,再將剛才編譯進crunch1中的那些命令分別做上symbol link:
bsd# cp /usr/src/release/picobsd/custom/crunch1/crunch1 /mnt/sbin
bsd# cd /mnt/sbin
bsd# ln -s ./crunch1 init # init必須在/mnt/sbin目錄中
bsd# ln -s ./crunch1 reboot
bsd# ln -s ./crunch1 sysctl
bsd# ln -s ./crunch1 ifconfig
bsd# ln -s ./crunch1 route
bsd# ln -s ./crunch1 ping
bsd# ln -s ./crunch1 dmesg
bsd# cd /mnt/bin
bsd# ln -s ../sbin/crunch1 sh # sh必須在/mnt/bin目錄中
bsd# ln -s ../sbin/crunch1 hostname
bsd# ln -s ../sbin/crunch1 cp
bsd# ln -s ../sbin/crunch1 rm
bsd# ln -s ../sbin/crunch1 ls
QQread.com
推出各大專業服務器評測 Linux服務器的安全性能
SUN服務器
HP服務器
DELL服務器
IBM服務器
聯想服務器
浪潮服務器
曙光服務器
同方服務器
華碩服務器
寶德服務器
bsd# ln -s ../sbin/crunch1 cat
bsd# ln -s ../sbin/crunch1 test
bsd# ln -s ../sbin/crunch1 mkdir
bsd# ln -s ../sbin/crunch1 less
bsd# ln -s ../sbin/crunch1 uname
bsd# ln -s ../sbin/crunch1 more
6、編寫啟動腳本
因為我們的系統只是為了測試在軟盤上運行FreeBSD,因而這裡的啟動腳本非常簡單只是讓系統可以工作,沒有做其它的工作,其內容如下:
#!/bin/sh
# Floppy BSD init script
PATH=/sbin:/bin
HOME=/
export PATH HOME
echo
echo "Hello, it's my Floppy BSD"
echo
因為沒有使用登錄驗證,所以這裡只是簡單的一直運行shell
while : ; do
/bin/sh
done