|
論壇說明 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2004-07-31, 12:08 AM | #1 |
榮譽會員
|
製作軟碟上執行的FreeBSD系統
http://www.chinaunix.net
作者:黑夜編碼人 製作軟碟上執行的FreeBSD系統 =========================== 作者:Matthew(黑夜編碼人) <matthew@cnfug.org> 網站:http://www.cnfug.org/ http://www.arbornet.org/~matthew/ 最後版本:http://www.cnfug.org/journal/2/05.html 測試平台:FreeBSD 4.5 Release (i386) 前言 大家可能見到過很多在軟碟上執行的Linux系統,可在軟碟上執行的FreeBSD反而比較少,雖然有PICOBSD,然而很多時候PICOBSD並不能滿足我們的需要,那麼可不可以自己製作一個在軟碟上執行的FreeBSD系統呢?答案是肯定的。我在維 護著一個Floppy Firewall的Project (http://www.cnfug.org/project/ffw/),它是一個關於FreeBSD和IPFilter的執行在軟碟上的防火牆系統,很多網友在使用了Floppy Firewall之後發郵件來詢問如何使FreeBSD執行在一張小小的軟碟上。但由於前段時間事情太多一直沒有時間,今天終於找到時間,所以把製作在軟碟上執行的FreeBSD的程序寫出來與大家分享,由於時間倉促,文中難免有錯誤之處,還請大家指教。 同時非常歡迎大家訪問CNFUG(China FreeBSD User Group, http://www.cnfug.org),它是一個由一些FreeBSD愛好者組織起來的自由組織,目的是為大家提供中文的FreeBSD方面的資源,目前CNFUG定期的向大家發行免費的FreeBSD中文技術期刊(http://www.cnfug.org/journal/)和維護一些Project(http://www.cnfug.org/project/)。 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複製到軟碟中。 程式碼: 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,這個函數在大部分程序中都會用到,如果每個程序都包含一段print f的程式碼,那麼如果有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 # 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 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 7、建立設備文件 現在需要建立一些基本的設備文件,我們使用/dev/MAKEDEV來完成這些操作: 程式碼: bsd# cd /mnt/dev bsd# cp /dev/MAKEDEV . bsd#./MAKEDEV std # 建立標準設備 bsd# rm MAKEDEV 8、最後工作 到目前為止,我們的啟動部分,Kernel和記憶體磁牒都已經準備好了,下面就開始整合它們了。 因為init啟動的時候會搜尋login class中的daemon這個類別,如果沒有則會出現錯誤提示,為了使init不報錯,我們還需要複製/etc/login.conf到/mnt/etc中: bsd# cp /etc/login.conf /mnt/etc/login.conf 因為loader支持直接載入gzip壓縮格式的文件,這為我們節約磁空提供了方便,同時也解決了我們空間不夠的問題,現在壓縮kernel和記憶體磁牒bsd: 程式碼: bsd# cd /root bsd# cp /sys/compile/MINI/kernel . bsd# gzip -9 kernel # 使用最大壓縮率,將產生文件kernel.gz bsd# umount /mnt bsd# gzip -9 bsd # 使用最大壓縮率,將產生文件bsd.gz 然後編輯loader的配製文件: 程式碼: bsd# cd /fd/boot bsd# vi loader.rc 輸入: 程式碼: load kernel load -t mfs_root bsd # 表示將bsd.gz以md的方式載入,並且成為root device 儲存碟退出,將kernel.gz和bsd.gz複製到軟碟中: 程式碼: bsd# cd /root bsd# cp kernel.gz /fd bsd# cp bsd.gz /fd bsd# umount /fd 現在用你的這張軟碟就可以啟動你的機器,如果一切正常的話,你將看到"Hello, it's my Floppy BSD"的提示,並且看到可愛的shell符"#"了,是不是很有滿足感呢? 到此為止一個基本的BSD系統已經完成了,如果你想繼續擴展Floppy BSD的功能,那就按照上面的方法自己做吧! 同時我在CNFUG(China FreeBSD User Group, http://www.cnfug.org)維護著一個Floppy Firewall(http://www.cnfug.org/project/ffw/)的Project,就是利用這種方法製作的一個在軟碟上執行的防火牆系統,你可以用來做參考。 按照本文的步驟,我製作了一個例子,大家可以到這裡下載:http://www.cnfug.org/tmp/flp-bsd.bin 使用方法請參照Floppy Firewall的使用方法(http://www.cnfug.org/project/ffw/)。 參考資料: PICOBSD Project |
送花文章: 3,
|