详解基于busybox的minilinux制作
这里制作的小linux中的initrd及filesystem是基于busybox制作的

制作环境:
[root@localhost kernels]# uname -a
Linux localhost.localdomain 2.6.18-308.el5 #1 SMP Fri Jan 27 17:21:15 EST 2012 i686 i686 i386 GNU/Linux
#安装开发环境所需的软件组
yum groupinstall -y "Development Libraries" "Development Tools"


一、制作minilinux所需的硬盘
 1.新装一块10G的IDE硬盘,作为制作minilinux的硬盘
 [root@localhost ~]# fdisk -l /dev/hdb

 Disk /dev/hdb: 10.7 GB, 10737418240 bytes
 15 heads, 63 sectors/track, 22192 cylinders
 Units = cylinders of 945 * 512 = 483840 bytes

 Disk /dev/hdb doesn't contain a valid partition table
 #这里我的硬盘是/dev/hdb

 2.创建三个分区并格式化
 #linux对中文的支持不好,并且本人的英文也不好,所以脚本中的备注都是中式英语,莫见笑!
 [root@localhost ~]# cat scripts/partdisk.sh
 #!/bin/bash
 #
 #show warnning information
 echo "initial a disk..."
 echo -e "\033[31mWarnning:\033[0m"
 #show harddisk list
 fdisk -l 2>/dev/null | grep -o "Disk /dev/[sh]d[a-z]"
 #Choose to hard disk
 read -p "Your choose:" partdisk
 #when the user select q,then quit this script
 if [ $partdisk = q ];then
  echo "quit"
  exit 7
 fi

 until fdisk -l 2>/dev/null | grep -o "Disk /dev/[sh]d[a-z]" | grep "^Disk $partdisk$" &>/dev/null;do 
  read -p "wrong option,choose again:" partdisk
 done
 #show confirm information
 read -p "Are you sure?" choose

 until [ $choose = y -o $choose = n -o $choose = q ];do
  read -p "Wrong choose,choose again?" choose
 done

 if [ $choose = n -o $choose = q ];then
  echo "quit"
  exit 9
 else
  echo "partition..."
 #umount the disk
  for i in `mount | grep "$choose" | awk "{print $1}"`;do
   fuser -km $1
   umount $1
   echo "$1 unmonut ok"
  done
 #Delete the partition table
 dd if=/dev/zero of=$partdisk bs=512 count=1
 sync
 sleep 3
 sync
 sleep 3
 #partition
 echo "n
 p
 1

 +20M
 n
 p
 2

 +512M
 n
 p
 3

 +128M
 t
 3
 82
 w
 " | fdisk $partdisk >/dev/null
 wait
 sleep 2
 sync
 partprobe $partdisk
 sleep 2
 sync
 #Notice the kernel re-reads the partition table
 cat /proc/partitions
 #Format the partition
 mke2fs -j ${partdisk}1 &>/dev/null
 wait
 mke2fs -j ${partdisk}2 &>/dev/null
 wait
 mkswap ${partdisk}3 &>/dev/null

 fi
 #验证分区是否成功
 [root@localhost scripts]# cat /proc/partitions
 major minor  #blocks  name

    3     0   10485760 hda
    3     1     104391 hda1
    3    64   10485760 hdb
    3    65      19813 hdb1
    3    66     500377 hdb2
    3    67     125685 hdb3
    8     0  125829120 sda
    8     1   41945683 sda1
    8     2    1052257 sda2
  253     0   30703616 dm-0
 #验证格式化是否成功
 [root@localhost scripts]# blkid
 /dev/mapper/vol0-home: UUID="be16484a-5354-404d-8052-8a74509f63e8" TYPE="ext3"
 /dev/mapper/vol0-root: UUID="f5849c49-0eb0-4f77-a0fd-31a36c5ba822" TYPE="ext3"
 /dev/sda2: LABEL="SWAP-sda2" TYPE="swap"
 /dev/hdc: LABEL="RHEL/5.8 i386 DVD" TYPE="iso9660"
 /dev/hda1: LABEL="/boot1" UUID="15c3a850-6521-459a-9a9a-ff548e4e0000" TYPE="ext3"
 /dev/vol0/root: UUID="f5849c49-0eb0-4f77-a0fd-31a36c5ba822" TYPE="ext3"
 /dev/hdb1: UUID="9cd3b7bb-3906-489e-adb2-f209d35e2b57" SEC_TYPE="ext2" TYPE="ext3"
 /dev/hdb2: UUID="1f26afe4-0969-4735-8b44-b52d40eb1498" SEC_TYPE="ext2" TYPE="ext3"
 /dev/hdb3: TYPE="swap"

 #创建目录并挂载分区
 #这里创建两个目录/mnt/boot,/mnt/sysroot其中boot作为minilinux的boot分区,sysroot作为minilinux的根分区
 #boot和sysroot对应的设备文件分别是/dev/hdb1,/dev/hdb2
 mkdir /mnt/{boot,sysroot};mount /dev/hdb1 /mnt/boot;mount /dev/hdb2 /mnt/sysroot
 #验证挂载是够成功
 [root@localhost scripts]# mount
 /dev/mapper/vol0-root on / type ext3 (rw)
 proc on /proc type proc (rw)
 sysfs on /sys type sysfs (rw)
 devpts on /dev/pts type devpts (rw,gid=5,mode=620)
 /dev/mapper/vol0-home on /home type ext3 (rw)
 /dev/hda1 on /boot type ext3 (rw)
 tmpfs on /dev/shm type tmpfs (rw)
 none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
 sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
 /dev/hdb1 on /mnt/boot type ext3 (rw)
 /dev/hdb2 on /mnt/sysroot type ext3 (rw)

二、制作minilinux的boot分区
 1.为minilinux安装grub,此处的/dev/hdb为目标系统所在的那块新磁盘
 grub-install --root-directory=/mnt  /dev/hdb
 #检查grub是否安装成功
 [root@localhost ~]# tree /mnt/boot/
 /mnt/boot/
 |-- grub
 |   |-- device.map
 |   |-- e2fs_stage1_5
 |   |-- fat_stage1_5
 |   |-- ffs_stage1_5
 |   |-- iso9660_stage1_5
 |   |-- jfs_stage1_5
 |   |-- minix_stage1_5
 |   |-- reiserfs_stage1_5
 |   |-- stage1
 |   |-- stage2
 |   |-- ufs2_stage1_5
 |   |-- vstafs_stage1_5
 |   `-- xfs_stage1_5
 `-- lost+found

 2 directories, 13 files

 #接下来为grub建立配置文件
 [root@localhost ~]# vim  /mnt/boot/grub/grub.conf
 [root@localhost ~]# cat /mnt/boot/grub/grub.conf
 default        0
 timeout        3
 color    light-green/black light-magenta/black
 title    MageEdu-lixiaobo Mini Linux (2.6.38.5)
  root (hd0,0)
  kernel /linuz ro root=/dev/hda2
  initrd /initrd.gz

2.制作minilinux所需的内核
#下载并解压内核源文件及cp当前系统的.config文件
cd /usr/src/kernels
#进入kernels目录下载并解压内核源文件,这里使用的是2.6.38版本的内核
wget ftp://192.168.0.254/pub/Sources/kernel/linux-2.6.38.5.tar.bz2
tar xf linux-2.6.38.5.tar.bz2
cd /usr/src/kernels/linux-2.6.38.5
cp /usr/src/kernel/$release/.config ./
#根据您的实际和规划选择所需要的功能;本实例计划制作一个具有网络的功能的微型linux且不打算使用内核模块,因此,这里选择把本机对应的网卡驱动直接编译进了内核。作者使用的是vmware Workstation虚拟机,所以,所需的网上驱动是pcnet32的,其它的均可按需要进行选择。选择完成后需要保存至当前目录下.config文件中。
提示:为了实现后面的功能,请务必将文件系统中的ext3和网卡的驱动程序直接编译进内核;否则,就需要手动装载这些相关文件系统的模块;
make menuconfig
#制作
make SUBDIR=arch/


#copy内核到/mnt/boot/linuz
cp arch/x86/boot/bzImage /mnt/boot/linuz

3.制作initrd
#下载并解压busybox以及编译安装
cd /usr/src
tar xf busybox-1.20.2.tar.bz2
cd  busybox-1.20.2
mkdir include/mtd
cp  /usr/src/linux/include/mtd/ubi-user.h  include/mtd/
make menuconfig
#说明:
1、此处需要选择 Busybox Settings --> Build Options -->  Build BusyBox as a static binary (no shared libs),这样可以把Busybox编译成一个不使用共享库的静态二进制文件,从而避免了对宿主机的共享库产生依赖;但你也可以不选择此项,而完成编译后把其依赖的共享库复制至目标系统上的/lib目录中即可;这里采用后一种办法。
2、修改安装位置为/mnt/sysroot;方法为:Busybox Settings --> Installation Options --> (./_install) BusyBox installation prefix,修改其值为/mnt/sysroot,作者选择的是默认安装路径。

#拷贝busybox中所有文件到/tmp/initrd,因这里需要制作initrd,安装后的文件均位于./_install目录中;但为了创建initrd,并实现让其启动以后将真正的文件系统切换至目标系统分区上的rootfs,需要复制一份刚编译安装busybox至另一个目录,以实现与真正的根文件系统分开制作。我们这里选择使用/tmp/initrd目录;
mkdir /tmp/initrd
cp -a busybox-1.20.2/_install/* /tmp/initrd
#建立initrd所需的目录
cd /tmp/initrd
mkdir -pv  proc  sys  etc tmp  dev  mnt/sysroot

#创建两个必要的设备文件:
mknod  dev/console  c  5  1
mknod  dev/null  c  1  3

#为initrd制作init程序,此程序的主要任务是实现rootfs的切换,因此,可以以脚本的方式来实现它:

rm -f linuxrc
[root@localhost initrd]# vim  init
[root@localhost initrd]# cat init
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mdev -s
mount -t ext3 /dev/hda2  /mnt/sysroot
exec  switch_root  /mnt/sysroot  /sbin/init

#给此脚本执行权限:
chmod  +x  init

#制作initrd
find  .  | cpio  --quiet  -H newc  -o  | gzip  -9 > /mnt/boot/initrd.gz

4.制作minilinux真正的根分区/mnt/sysroot
#拷贝busybox中所有文件到/mnt/sysroot
cp -a busybox-1.20.2/_install/* /mnt/sysroot
#创建minilinux所需的目录
mkdir -pv /mnt/{boot/grub,sysroot/{boot,proc,sys,bin,sbin,lib/modules,usr/{bin,sbin,lib},var/{run,log,lock},etc/{init.d,rc.d},dev/pts,home,root,tmp}}
#创建两个必要的设备文件:
mknod  dev/console  c  5  1
mknod  dev/null  c  1  3
#配置init所需的inittab配置文件
cd  /mnt/sysroot
rm  -f  linuxrc

[root@localhost sysroot]# vim etc/inittab
[root@localhost sysroot]# cat etc/inittab
::sysinit:/etc/rc.d/rc.sysinit
::respawn:/sbin/getty 9600 tty1
::respawn:/sbin/getty 9600 tty2
::respawn:/sbin/getty 9600 tty3
::shutdown:/bin/umount -a -r
::ctrlaltdel:/sbin/reboot
#配置系统初始化脚本etc/rc.d/rc.sysinit
[root@localhost sysroot]# vim  etc/rc.d/rc.sysinit
[root@localhost sysroot]# cat etc/rc.d/rc.sysinit
#!/bin/sh
echo -e "\tWelcome to  \033[31mMageEdu\033[0m Linux"

echo -e "Remounting the root filesystem ..."
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -o  remount,rw  /

echo -e "Creating the files of device ..."
mdev -s

echo -e "Mounting the filesystem ..."
mount -a
swapon -a

echo -e "Starting the log daemon ..."
syslogd
klogd

echo -e "Configuring loopback interface ..."
ifconfig  lo  127.0.0.1/24
ifconfig eth0 172.16.100.100/16
#而后让此脚本具有执行权限:
chmod +x  etc/rc.d/rc.sysinit

#为系统准备一个“文件系统表”配置文件etc/fstab
[root@localhost sysroot]# vim  etc/fstab
[root@localhost sysroot]# cat etc/fstab
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
/dev/hda1               /boot                   ext3    defaults        0 0
/dev/hda2               /                       ext3    defaults        1 1


#手动为minilinux添加一个root用户
[root@localhost sysroot]# grep  "^root"  /etc/shadow  > etc/shadow
[root@localhost sysroot]# grep  "^root"  /etc/passwd  > etc/passwd
[root@localhost sysroot]# grep  "^root"  /etc/group  > etc/group
#注:等目标主机启动时,root用户的口令也是宿主机的root用户的口令。您可以在目标主机启动以后再动手更改root用户的口令。

#在系统登录时提供banner信息
[root@localhost sysroot]# vim  etc/issue
[root@localhost sysroot]# cat etc/issue
Welcome to MageEdu Linux(http://www.magedu.com)...
minilinux
Kernel \r

#由于在rc.sysinit文件中启动了日志进程,因此系统在运行中会产生大量日志并将其显示于控制台;这将会经常性的打断正在进行的工作,为了避免这种情况,我们这里为日志进程建立配置文件,为其指定将日志发送至/var/log/messages文件;
[root@localhost sysroot]# vim  etc/syslog.conf
[root@localhost sysroot]# cat etc/syslog.conf
*.info    /var/log/messages