LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2934|回复: 5

制作软盘上运行的FreeBSD系统

[复制链接]
发表于 2003-6-6 10:59:18 | 显示全部楼层 |阅读模式
拿linuxsir这到边贴一次哈

制作软盘上运行的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格式)。

  1. bsd# disklabel -r -w fd0a fd1440
复制代码

接下来是安装引导程序。

  1. bsd# disklabel -B fd0a
复制代码

现在软盘已经能够引导了,但因为我们要在它上面放置程序,所以要创建文件系统。

  1. bsd# newfs fd0a
复制代码

刚才已经做好了引导程序,因为引导程序会加载/boot/loader,所以我们还需要将系统中的/boot/loader复制到软盘中。

  1. bsd# mkdir /fd
  2. bsd# mount /dev/fd0a /fd
  3. bsd# mkdir /fd/boot
  4. 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设备支持

下面是我使用的一个内核配制文件:

  1. #
  2. # GENERIC -- Generic kernel configuration file for FreeBSD/i386
  3. #
  4. #
  5. # $FreeBSD: src/sys/i386/conf/GENERIC,v 1.246.2.38 2002/01/25 17:41:40 murray Exp $
  6. machine                i386
  7. cpu                I386_CPU
  8. cpu                I486_CPU
  9. cpu                I586_CPU
  10. cpu                I686_CPU
  11. ident                "MINI-KERNEL"
  12. maxusers        0                       #maxusers最好让系统自动分配,如果设得过大,会占用过多的内存。

  13. options         INET                        #InterNETworking
  14. options         FFS                        #Berkeley Fast Filesystem
  15. options         FFS_ROOT                #FFS usable as root device [keep this!]
  16. options         MFS                        #Memory Filesystem
  17. options         MD_ROOT                        #MD is a potential root device
  18. options         COMPAT_43                #Compatible with BSD 4.3 [KEEP THIS!]
  19. options                NO_SWAPPING             #Disable swap

  20. device                isa
  21. device                pci

  22. # Floppy drives
  23. device                fdc0        at isa? port IO_FD1 irq 6 drq 2
  24. device                fd0        at fdc0 drive 0

  25. # atkbdc0 controls both the keyboard and the PS/2 mouse
  26. device                atkbdc0        at isa? port IO_KBD
  27. device                atkbd0        at atkbdc? irq 1 flags 0x1

  28. device                vga0        at isa?

  29. # syscons is the default console driver, resembling an SCO console
  30. device                sc0        at isa? flags 0x100

  31. # Floating point support - do not disable.
  32. device                npx0        at nexus? port IO_NPX irq 13

  33. # PCI Ethernet NICs that use the common MII bus controller code.
  34. # NOTE: Be sure to keep the 'device miibus' line in order to use these NICs!
  35. device                miibus                # MII bus support
  36. device                fxp                # Intel EtherExpress PRO/100B (82557, 82558)
  37. device                rl                # RealTek 8129/8139
  38. device                xl              # 3Com 3c90x
  39. device                lnc0        at isa? port 0x280 irq 10 drq 0 # VMware Nic

  40. # Pseudo devices - the number indicates how many units to allocate.
  41. pseudo-device        loop                # Network loopback
  42. pseudo-device        ether                # Ethernet support
  43. pseudo-device        md                # Memory "disks"
复制代码

上面的内核基本上是一个系统要运行的最小配制了,当然如果你的机器不同具体也不同,大家按自己的情况来定,我的机器配制是:
CPU: Pentium III 733Mhz
MotherBoard: Via 693A Chipset
NIC: Realtek 8139c
当配制好之后就是编译内核了,建议大家使用config的方式来编译,注意,最后不要使用make install,否则你原来的内核会被替换。

  1. bsd# cd /sys/i386/conf
  2. bsd# config MINI
  3. bsd# cd ../../compile/MINI
  4. 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,编辑它以选择你需要哪些软件,下面以一个例子来说明它的用法:

  1. # $FreeBSD: src/release/picobsd/router/crunch.conf,v 1.1.2.2 2001/02/20 02:53:35 luigi Exp $
  2. #
  3. # NOTE: the string "/usr/src" will be automatically replaced with the
  4. # correct value set in 'build' script - you should change it there

  5. # Default build options
  6. buildopts -DNOPAM -DRELEASE_CRUNCH -DNOSECURE -DNOCRYPT -DNONETGRAPH -DNOIPSEC

  7. # other sources
  8. srcdirs /usr/src/bin
  9. srcdirs /usr/src/sbin/i386
  10. srcdirs /usr/src/sbin
  11. srcdirs /usr/src/usr.bin
  12. srcdirs /usr/src/usr.sbin
  13. srcdirs /usr/src/gnu/usr.bin
  14. srcdirs /usr/src/gnu/usr.sbin
  15. srcdirs /usr/src/libexec
  16. # sources for ns & vm
  17. srcdirs /usr/src/release/picobsd/tinyware

  18. # 以下为你所需要在crunch包含的程序列表,以空格分隔。
  19. progs dmesg ping ifconfig route hostname
  20. progs cp rm ls cat test mkdir less
  21. progs uname sysctl
  22. progs init sh reboot

  23. # ln是表示建立一个别名,如ln less more,表示当执行more的时候实际上是执行less
  24. ln less more

  25. # 以下是指定编译时需要的库
  26. libs -lncurses -lmytinfo -lipx
  27. libs -lz -lpcap -lalias
  28. libs -ledit -lutil -lmd -lcrypt -lmp -lgmp -lm -lkvm
  29. libs -lgnuregex -ltelnet
复制代码

当编辑好crunch.conf之后,你就可以开始编译crunch了:

  1. bsd# make
复制代码

这时会生成一个名为crunch1的程序,我们要的就是它了。

5、建立内存磁盘
大家可以看到crunch1加上我们刚才编译的内核和loader程序,已经超出了软盘的容量,同时为了加速程序的运行我们需要使用MD(内存磁盘)来解决这个问题,MD将作为系统的根文件系统和用来存放系统程序。对于内存磁盘的大小一般不易太大,因为这样会占用过多的内存,下面我们就以建立一个3M的内存磁盘为例说明如何建立内存磁盘:

  1. bsd# cd /root
  2. bsd# dd if=/dev/zero of=bsd bs=1k count=3072       # 生成一个3M的文件,用来做MD
  3. bsd# vnconfig -c -s labels vn0c bsd                # 使用bsd来创建一个vn设置,以便在其中存放程序
  4. bsd# disklabel -w -r vn0c auto                     # 建立disklabel
  5. bsd# disklabel -B vn0c                             # 安装启动代码
  6. bsd# newfs vn0c                                    # 创建UFS文件系统
  7. bsd# mount /dev/vn0c /mnt                          # 将vn0c即bsd mount到/mnt
复制代码

接下来要做的就是建立目录结构,具体建立哪些目录这要视需要决定,本例中需要建立如下目录:

  1. bsd# mkdir /mnt/etc
  2. bsd# mkdir /mnt/sbin
  3. bsd# mkdir /mnt/bin
  4. bsd# mkdir /mnt/dev
复制代码

然后将crunch1复制到/mnt/sbin中,再将刚才编译进crunch1中的那些命令分别做上symbol link:

  1. bsd# cp /usr/src/release/picobsd/custom/crunch1/crunch1 /mnt/sbin
  2. bsd# cd /mnt/sbin
  3. bsd# ln -s ./crunch1 init          # init必须在/mnt/sbin目录中
  4. bsd# ln -s ./crunch1 reboot
  5. bsd# ln -s ./crunch1 sysctl
  6. bsd# ln -s ./crunch1 ifconfig
  7. bsd# ln -s ./crunch1 route
  8. bsd# ln -s ./crunch1 ping
  9. bsd# ln -s ./crunch1 dmesg
  10. bsd# cd /mnt/bin
  11. bsd# ln -s ../sbin/crunch1 sh      # sh必须在/mnt/bin目录中
  12. bsd# ln -s ../sbin/crunch1 hostname
  13. bsd# ln -s ../sbin/crunch1 cp
  14. bsd# ln -s ../sbin/crunch1 rm
  15. bsd# ln -s ../sbin/crunch1 ls
  16. bsd# ln -s ../sbin/crunch1 cat
  17. bsd# ln -s ../sbin/crunch1 test
  18. bsd# ln -s ../sbin/crunch1 mkdir
  19. bsd# ln -s ../sbin/crunch1 less
  20. bsd# ln -s ../sbin/crunch1 uname
  21. bsd# ln -s ../sbin/crunch1 more
复制代码

6、编写启动脚本
因为我们的系统只是为了测试在软盘上运行FreeBSD,因而这里的启动脚本非常简单只是让系统可以工作,没有做其它的工作,其内容如下:

  1. #!/bin/sh
  2. # Floppy BSD init script

  3. PATH=/sbin:/bin
  4. HOME=/
  5. export PATH HOME

  6. echo
  7. echo "Hello, it's my Floppy BSD"
  8. echo

  9. # 因为没有使用登录验证,所以这里只是简单的一直运行shell
  10. while : ; do
  11.    /bin/sh
  12. done
复制代码


7、建立设备文件
现在需要建立一些基本的设备文件,我们使用/dev/MAKEDEV来完成这些操作:

  1. bsd# cd /mnt/dev
  2. bsd# cp /dev/MAKEDEV .
  3. bsd#./MAKEDEV std                # 建立标准设备
  4. 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:

  1. bsd# cd /root
  2. bsd# cp /sys/compile/MINI/kernel .
  3. bsd# gzip -9 kernel              # 使用最大压缩率,将生成文件kernel.gz
  4. bsd# umount /mnt
  5. bsd# gzip -9 bsd                 # 使用最大压缩率,将生成文件bsd.gz
复制代码

然后编辑loader的配制文件:

  1. bsd# cd /fd/boot
  2. bsd# vi loader.rc
复制代码

输入:

  1. load kernel
  2. load -t mfs_root bsd             # 表示将bsd.gz以md的方式加载,并且成为root device
复制代码

存盘退出,将kernel.gz和bsd.gz复制到软盘中:

  1. bsd# cd /root
  2. bsd# cp kernel.gz /fd
  3. bsd# cp bsd.gz /fd
  4. 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
发表于 2003-6-6 12:42:39 | 显示全部楼层
呵呵,原来我注册了“黑夜编码人”的呀,以后就不用Plan9这个ID了。 :p
发表于 2003-6-6 19:17:32 | 显示全部楼层
放在网上

让大家下载.....
发表于 2003-6-8 16:59:26 | 显示全部楼层
发表于 2003-6-8 17:27:09 | 显示全部楼层
好,不错!
发表于 2003-6-15 15:24:04 | 显示全部楼层
能不能弄个usb盘上的bsd。
现在usb盘也很便宜了,容量也比软盘大得多,使用也方便,如果可以,估计很多人会用。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表