我们本文构建的小型linux,只有一个kernel,并能使用一些基本的命令,还能提供ssh服务,整个linux系统装下来大小仅为10M左右。而我们通过源码编译来安装kernel,BusyBox和Dropbear来实现这些功能,这样会很大程度的节省我们的系统空间,重要的是系统非常的纯净,运行速度异常的快。既然我们的系统这么小,当然也可以做在U盘中,可以随时的带在身边,方便我们使用。
什么是BusyBox呢?
BusyBox 是一个集成了一百多个最常用linux命令和工具的软件。BusyBox 包含了一些简单的工具,例如ls、 cat 和 echo等等,还包含了一些更大、更复杂的工具,例如 grep、find、mount以及telnet等。
什么是Dropbear呢?
Dropbear是一个相对较小的SSH服务器和客户端,它运行在一个基于POSIX的各种平台,并且是一个Dropbear是开源软件,广泛应用于嵌入式开发平台。
下面开始我们的制作过程:
前提:
1、一个作为宿主机的Linux;本文使用的是RedHat Enterprise Linux 5.4;
2、在宿主机上提供一块额外的硬盘作为新系统的存储盘,这里添加使用一块IDE接口的新硬盘(如果添加的是SCSI的新硬盘,则后边的配置文件.config必须进行修改把SCSI驱动编译进kernel即可)
3、Linux内核源码,busybox源码;本文使用的是新版的linux-2.6.34.1.tar.bz2和
busybox-1.16.0.tar.bz2
下载地址:
http://www.kernel.org/pub/linux/kernel/v2.6/
http://www.linuxidc.com/Linux/2011-08/40704.htm
http://matt.ucc.asn.au/dropbear/
找到相应的软件包,并下载
提示:如果您用的是虚拟机,则当宿主机挂起的时候,不能再目标主机上修改文件,这样会导致文件系统损坏;想要在目标主机上修改的话,可以把宿主机关闭!
一、为系统上的新硬盘建立分区,这里根据需要先建立一个大小为100M的主分区作为新建系统的boot分区和一个512M的分区作为目标系统(即正在构建的新系统,后面将沿用此名称)的根分区;100M的分区格式化后将其挂载至/mnt/boot目录下;512M的分区格式化后将挂载至/mnt/sysroot目录;
先对新添加的磁盘分区:
#fdisk /dev/hda
格式化文件系统:
#mke2fs -j /dev/hda1
#mke2fs -j /dev/hda2
挂载文件系统:
#mkdir /mnt/boot (必须是boot目录)
#mkdri /mnt/sysroot
#mount /dev/hda1 /mnt/boot
#mount /dev/hda2 /mnt/sysroot
说明:
1、此处的boot和sysroot的挂载点目录名称尽量不要修改,尤其是boot目录,否则您必须保证后面的许多步骤都做了相应的改动;
2、新建系统的boot目录也可以跟根目录在同一个分区,这种方式比独立分区还要简单些,因此这里将不对此种方法再做出说明;
二、编译内核源代码,为新系统提供一个所需的内核(本例中的源代码包都位
于/usr/src目录中)
配置好yum源,编译kernel之前,我们的开发组要装好:
#yum groupinstall "Development Libraries" "Development Tools"
# cd /usr/src
# tar jxvf linux-2.6.34.1.tar.bz2
# ln -sv linux-2.6.34.1 linux
# cd linux
为了方便选择性的配置kernel,故您可下载kernel-2.6.30.5-i686.cfg(见附件)至当前目录中,并重命名为.config。这个文件是有人以前发行的用于嵌入式的一个小型linux中用于kernel编译的配置文件。
#cp kernel-2.6.30.5-i686.cfg /usr/src/linux/.config
配置我们要编译的kernel:
# make menuconfig
根据您的实际和规划选择所需要的功能(这里仅仅提供几种支持):
1,把对应网卡的驱动编译进kernel中:
Device Drivers-->Network device support-->Ethernet (10 or 100Mbit)-->(在这里选择对应要使用的网卡驱动,如过你是虚拟机的话对应的pcnet32要选上)
2,如果您使用的SCSI硬盘,则需要选择对SCSI驱动的支持:(可选)
Device Drivers-->Fusion MPT device support-->(里面的可以都选上)
Device Drivers-->SCSI device support-->SCSI low-level drivers-->(选择对应的SCSI的类型的支持)
3,支持动态加载模块:(可选)
选择:Enable loadable module support
4,支持文件系统:
File systems-->(在这里选择我们要支持的文件系统类型,如果你是ext3文件系统,确定其对应项选上)
5,选择我们对应的cpu架构,平台要与运行小linux的平台对应:
选择:Processor type and features-->Processor family-->(选择对应cpu的类型;如果要用的cpu是intel酷睿系列的选择Core 2/newer Xeon)
由于我们只需要kernel,故我们只编译kernel所在的arch目录即可,当用到其他,目录中的内容时,会自动添加:
# make SUBDIR=arch/
把我们的kernel复制如目标主机的磁盘分区:
# cp arch/x86/boot/bzImage /mnt/boot
三、编译busybox
# cd /usr/src
# tar -jxvf busybox-1.16.1.tar.bz2
# cd busybox-1.16.1
配置我们要编译的选项:
# make menuconfig
说明:
1、此处需要选择 Busybox Settings --> Build Options --> Build BusyBox as a static binary (no shared libs),这样可以把Busybox编译成一个不使用共享库的静态二进制文件,从而避免了对宿主机的共享库产生依赖(但你也可以不选择此项,而完成编译后把其依赖的共享库复制至目标系统上的/lib目录中即可)
2、修改安装位置为/mnt/root;方法为:Busybox Settings --> Installation Options --> (./_install) BusyBox installation prefix,修改其值为/mnt/sysroot(按住crtl键和backspace进行删除)
# make install
安装后的文件均位于/mnt/sysroot目录中;但为了创建initrd,并实现让其启动以后将真正的文件系统切换至目标系统分区上的根文件系统上,您还需要复制一份刚安装
在/mnt/sysroot下的busybox至另一个目录,以实现与真正的根文件系统分开制作。我们这里选择使用/mnt/temp目录:
# mkdir -pv /mnt/temp
# cp -r /mnt/sysroot/* /mnt/temp
四、制作initrd
# cd /mnt/temp
1、建立rootfs:
# mkdir -pv proc sys etc/init.d tmp dev mnt/sysroot
2、创建两个必要的设备文件:
# mknod dev/console c 5 1
# mknod dev/null c 1 3
3、为initrd制作init程序,此程序的主要用于系统启动的第一个阶段,主要任务是实现根文件系统的切换。因此,可以以脚本的方式来实现它:
# rm linuxrc
# vim 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 /init
给此脚本执行权限:
#chmod +x init
4、制作initrd
# find . | cpio --quiet -H newc -o | gzip -9 > /mnt/boot/initrd.gz
五、建立真正的根文件系统
# cd /mnt/sysroot
1、建立rootfs:
# mkdir -pv proc sys etc/init.d tmp dev/pts boot var/log
2、创建两个必要的设备文件:
# mknod dev/console c 5 1
# mknod dev/null c 1 3
3、建立系统初始化脚本文件
# vim etc/init.d/rcS
添加如下内容:
#!/bin/sh
echo -e " Welcome to \033[31mToyLinux\033[0m "
echo -e "Remounting the root filesystem ..........[ \033[32mOK\033[0m ]"
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -o remount,rw /
echo -e "Creating the files of device ............[ \033[32mOK\033[0m ]"
mdev -s
echo -e "Mounting the filesystem .................[ \033[32mOK\033[0m ]"
mount -a
swapon -a
echo -e "Starting the log daemon .................[ \033[32mOK\033[0m ]"
syslogd
klogd
echo -e "Configuring loopback interface ..........[ \033[32mOK\033[0m ]"
ifconfig lo 127.0.0.1/24
ifconfig eth0 172.16.100.9/16
# END
而后让此脚本具有执行权限:
#chmod +x etc/init.d/rcS
4、配置init及其所需要inittab文件
# cd /mnt/sysroot
# mv linuxrc init
# vim etc/inittab
添加如下内容:
::sysinit:/etc/init.d/rcS
console::respawn:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
5、为系统准备一个“文件系统表”配置文件/etc/fstab
# vim 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
6、由于在rcS文件中启动了日志进程,因此系统在运行中会产生大量日志并将其显示于控制台;这将会经常性的打断正在进行的工作,为了避免这种情况,我们这里为日志进程建立配置文件,为其指定将日志发送至/var/log/messages文件;
# vim etc/syslog.conf
添加如下一行:
*.info /var/log/messages
六、好了,至此一个简易的基于内存运行的小系统已经构建出来了,我们接下来为此系统创建所需的引导程序
# grub-install --root-directory=/mnt /dev/hda
说明:此处的/dev/hda为目标系统所在的那块新磁盘;
接下来为grub建立配置文件:
# vim /mnt/boot/grub/grub.conf
添加类似如下内容:
default=0
timeout=3
color light-green/black light-magenta/black
title ToyLinux (2.6.34.1)
root (hd0,0)
kernel /bzImage ro root=/dev/hda2 quiet
initrd /initrd.gz
接下来将此块硬盘接入一个新的主机(这里使用的是虚拟机),启动一下并测试使用。
提示:如果你用的是虚拟机,则先新建虚拟机之后再把我们的新磁盘添加进去,这样才能正常启动。
七、为新构建的ToyLinux启用虚拟控制台
这个可以通过宿主机来实现,也可以直接启动刚构建成功的小Linux进行配置。我们这里采用通过宿主机的方式(重新启动宿主机):
# cd /mnt/sysroot
将 etc/inittab文件改为如下内容:
::sysinit:/etc/init.d/rcS
tty1::askfirst:/bin/sh
tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh
tty5::askfirst:/bin/sh
tty6::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
注解:askfirst的意思是:当系统启动完成后,会给出一个提示信息:please enter to activate this console,我们直接回车就可以登录
现在就可以测试验正六个虚拟控制台的使用了。
八、尽管上述第七步已经实现了虚拟控制台,但其仍是直接进入系统,且系统没有用户帐号等安全设施,这将不利于系统的安全性。因此,接下来的这步实现为系统添加用户帐号(这里仍然基于宿主机实现)。
1、为目标主机建立passwd帐号文件
# cd /mnt/sysroot
# vim etc/passwd
添加如下内容:
root:x:0:0::/root:/bin/sh
而后为root用户创建“家”目录:
# mkdir root
2、为目标主机建立group帐号文件
# vim etc/group
添加如下内容:
root:x:0:
3、为目标主机建立shadow影子口令文件,这里采用直接复制宿主机的shadow文件中关于root口令行的行来实现
# grep "^root" /etc/shadow > etc/shadow
注:等目标主机启动时,root用户的口令也是宿主机的root用户的口令。您可以在目标主机启动以后再动手更改root用户的口令。
4、将 etc/inittab文件改为如下内容:
::sysinit:/etc/init.d/rcS
::respawn:/sbin/getty 9600 tty1
::respawn:/sbin/getty 9600 tty2
::respawn:/sbin/getty 9600 tty3
::respawn:/sbin/getty 9600 tty4
::respawn:/sbin/getty 9600 tty5
::respawn:/sbin/getty 9600 tty6
::shutdown:/bin/umount -a -r
::ctrlaltdel:/sbin/reboot
5,由于我们要认证用户的登录,需要名称解析服务,而我们的busybox不提供这个服务,故我们要将nsswitch依赖的库文件移植过来,并编辑/mnt/sysroot/etc/nsswitch.conf这个配置文件:(此步骤在宿主机上完成)
我们要添加名称解析的库文件,复制libnss3.so、libnssckbi.so、libnss_compat.so、libnss_db.so、libnss_dns.so、libnss_files.so这几个文件,也要把这几个文件所有连接文件文件也复制过去,用# cp -a ,把连接的属性也复制过去,这样就不用再手动创建链接了。
#cd /mnt/sysroot
#mkdir usr/lib lib
由于这些库文件是一些链接文件,故我用-a选项,保存其文件原来的特征不变:
#cp -a /usr/lib/libnss* usr/lib/
#cp -a /lib/libnss* lib
这里把它全复制过去,省事
由于login程序登录的时候要用到名称解析功能,故我们要编译nsswitch的配置文件:
#vim etc/nsswitch.conf
添加如下行:
passwd: files
shadow: files
group: files
hosts: files dns
好了,接下来就可以重新启动目标主机进行验正了。
九、在系统登录时提供banner信息(这个可以再目标主机上完成,这里还以在宿主机上完成为例)
# vi /mnt/sysroot/etc/issue
添加如下内容:
Welcome to ToyLinux...
注:这里的内容可以根据你的需要进行修改。
十、在系统启动时为系统提供主机名称(这个可以再目标主机上完成,这里还以在宿主机上完成为例):
1、创建保存主机名称的配置文件
#cd /mnt/sysroot
# mkdir etc/sysconfig
# vi etc/sysconfig/network
添加如下内容:
NETWORKING=yes
HOSTNAME=www.jia.com
2、编辑系统初始化脚本,实现开机过程中设定主机名称
# vi etc/init.d/rcS
在文件尾部添加如下行:
HOSTNAME=`/bin/hostname`
[ -e /etc/sysconfig/network && -r /etc/sysconfig/network ] && source
/etc/sysconfig/network
[ -z ${HOSTNAME} ] && HOSTNAME="localhost"
/bin/hostname ${HOSTNAME}
十一,安装dripbear提供ssh功能;
1、在宿主机上下载编译dropbear:
# tar xf dropbear-2012.55.tar.bz2
# cd dropbear-2012.55
# ./configure
#make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
说明:如果你想将dropbear进行静态编译,则可以使用如下命令,此时dropbear将不再依赖于别的库文件运行:# make STATIC=1
# make install
2、根据bcp.sh脚本移植刚安装生成的二进制文件dropbear、dropbearkey,这个脚本会自动移植命令所依赖的库文件:
#vim bcp.sh
添加如下内容:
#!/bin/bash
#
function BCP {
TARGET=/mnt/sysroot
COMMAND=`which $1 | grep -o "/.*"`
CMDPATH=${COMMAND%/*}
[ -d $TARGET$CMDPATH ] || mkdir -p $TARGET$CMDPATH
[ -e $TARGET$COMMAND ] || cp $COMMAND $TARGET$CMDPATH
for LIBFILE in `ldd $COMMAND | grep -o "/.*lib[^[:space:]]*"`; do
LIBPATH=${LIBFILE%/*}
[ -d $TARGET$LIBPATH ] || mkdir -p $TARGET$LIBPATH
[ -e $TARGET$LIBFILE ] || cp $LIBFILE $TARGET$LIBPATH
done
}
while true; do
read -p "A Command: " MYCMD
case $MYCMD in
q|Q)
echo "Quit..."
exit 0
;;
*)
! which $MYCMD &> /dev/null && echo "Wrong command..." && continue
BCP $MYCMD
;;
esac
done
移植命令及所依赖的库文件:
#bash bcp.sh
输入命令完成后,输入q退出:
A Command:dropbear
A Command:dropbearkey
A Command:q
3、为系统添加devpts文件系统,以实现按需打开pty设备:
编辑目标主机的fstab文件,添加如下行:
devpts /dev/pts devpts mode=620 0 0
4、为目标主机提供/etc/shells文件,dropbear在用户登录时为以之验正用户的shell是否为可信任shell,故:
#vim /mnt/sysroot/etc/shells
添加如下内容:
/bin/ash
/bin/sh
/sbin/nologin
以下操作在目标主机上进行:
5、启动目标主机后,在目标主机上为dropbear提供主机密钥(如果是虚拟机确保宿主机已经关闭):
1) 生成rsa格式的密钥:
# mkdir /etc/dropbear
# /usr/local/bin/dropbearkey -t rsa -s 2048 -f
/etc/dropbear/dropbear_rsa_host_key
2)生成dss格式的密钥:
# /usr/local/bin/dropbearkey -t rsa -f /etc/dropbear/dropbear_dss_host_key
6、启动dropbear服务:
当我们用ssh登录的时候,会显示着个文件中的信息:
# echo "Welcome magedu.com linux" > /etc/issue.net
# touch /var/log/lastlog
启动服务:
# /usr/local/sbin/dropbear -b /etc/issue.net
注意:
1,当输入用户名,密码已成功,但是登录不进系统时:
重新挂载虚拟文件系统即可:
#mount -t devpts devpts /dev/pts
OK!我们的小linux就制作完成了!启用的很多功能,如提供web服务等都可以再添加进去,一起做吧!