前面是通过自定义内核配置制作的一个非常精简的Linux,这个Linux只能执行已经移植的有限的几个命令程序,为了使其具有更多功能,且控制其大小,使用kernel + busybox。
busybox模拟实现了linux的各种命令程序。BusyBox 是一个集成了三百多个最常用Linux命令和工具的软件。
Mini Linux:kernel + busybox
1、下载busybox-1.23.2.tar.bz2
2、解压缩:tar xf busybox-1.23.2.tar.bz2
3、编译,linux的编译安装有两种方式,一种是共享库的编译方式,每个程序运行要依赖外部的共享库,这种程序要移植,需要将共享库一同移植;另一种是静态编译方式,将其依赖的各种库文件直接编译进程序内部,这种程序只需要一个文件即可,移植方便。
对busybox,使用静态编译方式。静态编译需要依赖glibc-static
4、配置busybox选项:make menuconfig
Busybox Settings ---> 下的 Build Options --->
其中第一项: Build BusyBox as a static binary (no shared libs)就是编译busybox为静态模式。
然后:Installation Options ("make install" behavior) ---> ,配置编译后安装位置,即安装选项,在移植时,只需将这个目录移植到目标系统对应位置即可。
What kind of applet links to install (as soft-links) ---> 选项:
可以将各种应用配置成作为软连接或硬链接等。
然后主菜单下的---Applets就是配置模拟的各种应用,并且分了类:
Archival Utilities ---> 归档类工具, Coreutils ---> 是核心工具,Console Utilities ---> 是控制台的相关文件,Shells--->是各种shell工具。
配置完成后,保存退出,生成.config文件。
最后编译和安装:make && make install
5、编译、安装后,查看安装目录:
linuxrc模拟成init,不需要,只需要将bin、sbin和usr移植到目标系统即可。
将我们的目标系统原来根目录下的bin、sbin和usr删除,然后拷贝这三个文件目录到目标系统:
测试一下,切换根目录:
因为没有/bin/bash,可以使用ash,兼容bash。
/sbin下也有init程序,所以grub.conf可以修改kernel行,init=可以去掉,采取系统默认加载项,默认会去加载/sbin/init,也可以直接修改为init=/sbin/init。
6、重新启动Mini Linux,测试:
这时将运行一个busybox系统,但是这个系统将依赖于/etc/inittab配置文件,是模拟CentOS5。他根据inittab指令知道如何运行系统。所以提供一个inittab:
上图第二行的shell应该改成sh
然后添加初始化脚本:
chmod +x rc.d/rc.sysinit ,给此文件添加执行权限。
查看/proc目录,发现加载没成功,是mount命令使用的错误,不支持-n选项
mount -t proc proc /proc ,不过文件系统的挂载,一般是通过/etc/fstab文件配置实现的,编写fstab文件:
为何fstab就能挂载文件系统呢?是在rc.sysinit中实现,mount 有一个选项 -a:
-a Mount all filesystems in fstab,所以在rc.sysinit中添加语句mount -a;设备发现功能在busybox中使用的是mdev,语句mdev ,-s其将发现的设备添加到/dev中,mdev -s is to be run during boot to scan /sys and populate /dev.。
还有一点是,现在的系统启动后还是一个控制终端,而真正的系统可以使用虚拟终端,这里也可以使用虚拟终端,编辑inittab文件:
将原来的console改为tty。重新启动系统后,按ctrl+alt+F2:
启动了tty2。此时系统就是busybox系统。
如何基于模块的方式加载网络设备,使busybox小系统支持网络功能:
先查看网卡信息,lspci和modinfo
通过lspci查看网卡是以太网控制器,Intel的82545EM GE,网卡模块是e1000:
可以看到,模块是2.6.32内核版本的,当前使用的是3.10.67,需要重新编译对应版本的网卡驱动模块文件。
在linux内核源码目录下,运行make menuconfig
先要使系统支持网络功能:Networking support ---> 下的 Networking options --->
主要是将TCP/IP networking选中。
然后是 Device Drivers ---> 下的 Network device support ---> 选中,然后进入其子菜单,选择:Ethernet driver support (NEW) ---> ,其下提供了各种网卡的驱动,只选择Intel的1000GE。
退出后,执行make -j 4 bzImage
重新生成的内核中将包含网络功能和对应网卡驱动(都编译进内核),替换原来生成的bzImage。
重新启动Mini Linux:
可以支持网络功能和配置网卡了,网卡驱动在内核中,可以识别出网卡。
配置网络IP地址:
因为虚拟机配置的网络为桥接模式,配置IP地址与主机IP的在同一网段才可以。
测试网卡驱动使用模块编译方式:make menuconfig,在 Device Drivers ---> 下 --- Network device support 下 Ethernet driver support --->下,将Intel的网卡驱动改为M模式
重新编译内核:make bzImage,此时生成的内核不包含网卡驱动。
现在要编译一个驱动程序模块,编译方法是指定哪个路径下的那个文件:
我们需要编译Intel的e1000网卡驱动。使用modinfo e1000,看一下depends:即依赖的文件,如果有,移植时要一同移植。
编译单个内核模块:
# cd /usr/src/linux
# make M=drivers/net/etnernet/intel/e1000/
# make M=path/to/somedir/
拷贝生成的ko文件到新系统对用路径:
cp drivers/net/ethernet/intel/e1000/e1000.ko /mnt/sysroot/lib/modules/
重新启动MiniLinux,进行系统后,运行ifconfig:
发现跟上次配置不一样了,找不到网卡了,因为这一次,网卡驱动没有编译进内核,而是单独编译成一个模块,而模块没有加载,可以手动加载一下:
insmod /lib/modules/e1000.ko
驱动模块加载后,ifconfig命令就能识别到网卡了。
下一步,就是将加载模块做到初始化模块,使其能启动时自动加载。可以在rc.sysinit中添加加载模块命令,同时可以配置IP和主机名:
在/etc下创建sysconfig目录,其下创建network文件,其内容为:HOSTNAME=diyminilinux.testcc.com
登录认证:
切换根系统:chroot /mnt/sysroot /bin/sh
root用户的id为1000不合适,相关信息需要修改:
shadow中的内容直接拷贝宿主机中的root: head -1 /etc/shadow > /mnt/sysroot/etc/shadow
chmod 400 /mnt/sysroot/etc/shadow
要想启动时启动认证,需要启动时运行getty,编辑/etc/inittab:
getty运行时会打印登录提示符,要求输入用户和密码
执行rc.sysinit有错误,主机名没有设置正确,登录提示出现了。
输入用户名和密码,登录成功,显示在tty1登录。
rc.sysinit中,[ -z "$HOSTNAME" -o "$HOSTNAME"=="(none)" ] && HOSTNAME='localhost'这一行执行有问题。问题所在:判断=或==两边必须有空格,"$HOSTNAME" == "(none)"才行。
修改后再次启动:
主机名显示出来了
网卡也能识别出来,说明手动加载的网卡模块成功了。
系统启动时,打印欢迎信息,主要是issue文件的使用:在/mnt/sysroot/etc/下新建issue文件:
Welcome to DIYMiniLinux(https://www.DIY.com)
kernel \r
实现ssh功能,主要是目标主机上安装dropbear。
dropbear 是轻量的 sshd 服务器,与 OpenSSH 相比,他更简洁,更小巧,运行起来占用的内存也更少。
1、下载源代码:dropbear-2013.62.tar.bz2
2、解压:tar xf dropbear-2013.62.tar.bz2
3、进入dropbear源码目录,执行./configure 、 make && make install,全部使用默认选项
4、移植,将安装在宿主机上的dropbear移植到目标主机上,使用前面写的移植脚本:
需要拷贝的是dropbear、dropbearkey、dbclient
5、远程链接使用的伪终端,需要在dev目录下创建pts目录,这样新建伪终端设备文件在此保存。
然后在/etc/fstab中进行挂载:
6、还需要为目标系统的dropbear生成密钥文件:
在etc下创建dropbear目录,在此目录保存密钥文件
密钥文件名称及位置,可以看其源代码文件中的options.h文件:
7、对于远程登录,对安全要求很高,要求登录的shell是安全shell,至于如何判断是安全shell,需要在/etc/创建shells文件,将安全的shell添加进去:
vim /mnt/sysroot/etc/shells
8、dropbear在用户登录时要将用户名转换为ID号,并检查用户的账号信息。这个转换需要网络功能转换服务,这用到nsswitch,需要配置nsswitch.conf
nsswitch读取文件需要相应的库文件,主要在/usr/lib64下的libnss*文件和/lib64下的libnss*:
注意链接文件。
读取文件,只需要libnss_files模块。
以上是从宿主机移植到目标机的过程。
重新启动系统:
issue欢迎信息生效了。
前面做测试时,宿主机是直接挂起,但是在测试dropbear时,登录时需要写文件,这时如果宿主机是挂起的,就会造成文件系统的不一致,所以,要将宿主机关机。
启动后,可以在用户目录下创建.profile:
export PS1='[\u@\h \w]\$'
再次登录后:
变成我们熟悉的模式了。
9、运行dropbear:dropbear -F -E
可以看到,22端口已经监听。使用xshell登录:
输入密码时登录不了:
在目标机上,使用passwd重置一遍密码,结果就通过了,通过后,xshell不显示终端界面,原因是目标机上/dev/pts没有挂载成功,在前面,/etc/fstab中设置的devpts挂载没起作用。
手动创建/dev/pts,然后挂载:mount -t devpts devpts /devpts
然后就可以了。
好像是mdev -s会覆盖/dev,所以挂载时调换一下位置,在/etc/rc.d/rc.sysinit中,在mdev -s后,
mkdir /dev/pts
mount -t devpts devpts /dev/ots
取消/etc/fstab中的挂载,再次启动,就可以了。
至此,一个完整的Mini Linux就完成了,实现了最基本的功能,还可以远程登录。