kernel是内核,采用自己定制,最小化编译。busybox是提供rootfs,相当于用户空间。dropbear是提供远程ssh服务的,相当于openssl,但是它是轻量级的。ngnix是在定制的系统上提供的web服务。

环境:采用VMware虚拟机

一、编译内核

前提:查看自己的cpu类型,pci类型,内核只编译所需的驱动就可以。

例如:查看cpu类型,不同的机器可能不同

1

查看pci类型:

2

3

开始编译:

1、下载内核源代码,下载地址是 kernel.org。这里使用的内核版本是 3.13.6

2、解压内核文件并配置

tar xf linux-3.13.6.tar.xz -C /usr/src
cd /usr/src
ln -sv linux-3.13.6 linux
cd linux
make allnoconfig
make menuconfig  # 需要依赖ncusres-devel
make

编译完成。

在make menuconfig时选择对应的选项,常用的如下:(都是直接编译进内核)

4

5

6

7

 

8

9

10

11

12

13

14

15

16 

选择上面的选项编译完成后,会在当前目录下提供生成arch/x86/boot/bzImage内核映像压缩文件,作用等同于系统中vmlinuz文件。

二、编译busybox

1、获取busybox源码包  这里使用的版本是:busybox-1.22.1

2、开始编译

tar xf busybox-1.22.1.tar.bz2
cd  busybox-1.22.1
make menuconfig
make
make install

对于make menuconfig的选项说明:

17

18

 

注意:在执行make时,可能会出现 如下错误:

/usr/bin/ld: cannot find -lcrypt
collect2: ld returned 1 exit status
make: *** [busybox_unstripped] Error 1

出现这个错误的原因是因为在配置busybox的时候,通常配置为静态编译,所以编译后在最后的链接阶段需要链接crypt的静态库文件(libcrypt.a),而非动态库文件(libcrypt.so*),该库文件由glibc提供,通常系统中只安装了glibc,而没有安装glibc-static。

解决方法:

安装glibc-static包   yum install glibc-static

安装完成后,会在当前目录下生成一个_install目录,里面文件如下,实际上就生成一个busybox二进制程序,其他都是他的链接文件,主要的目的是模拟Linux的各种命令。但是我们发现里面,没有bash,但是这里sh兼容bash。

功能相当强大啊,就一个命令。看看这个文件的大小:

20

19

三、准备系统的启动盘

大致原理如下:

21

模拟实现系统启动盘

# 1、在虚拟机中添加块新的磁盘(在VMware中模拟实现)。划分2个主分区,大小分别为50M、512M,并格式化。

# 2、创建模拟boot目录和根文件系统,并挂载
mkdir /mnt/boot /mnt/sysroot -p
mount /dev/sdb1 /mnt/boot
mount /dev/sdb2 /mnt/sysroot

# 3、提供内核文件以及对应的grub

# 安装grub
grub-install --root-directory=/mnt  /dev/sdb

# 复制内核编译完成的bzImage文件到 /mnt/boot目录下:
cp /usr/src/linux/arch/x86_64/boot/bzImage /mnt/boot/

# 提供grub的配置文件
# vim /mnt/grub/grub.conf,文件内容如下:
# 这里不需要initramfs,因为这里内核可以直接挂载根文件系统
timeout=3
default=0
title Mini Linux Cl5
    root (hd0,0)
    kernel /bzImage ro root=/dev/sda2 init=/sbin/init

# 4、提供rootfs
###############################################################################################
# 复制命令
cp -a /root/busybox-1.22.1/_install/* /mnt/sysroot/

# 创建必要的目录
mkdir /mnt/sysroot/{root,boot,proc,sys,dev,usr,lib64}
#################################################################################################

##################################################################################################
# 提供配置文件,busybox在执行init程序时需要配置文件inittab
# vim /mnt/sysroot/etc/inittab ,内容如下:
# init 程序会以inittab文件为配置文件,格式如下:

#读取/etc/rc.d/rc.sysinit配置文件(在这里是/mnt/sysroot/etc/rc.d/rc.sysinit)
::sysinit:/etc/rc.d/rc.sysinit
# 开启4个虚拟终端,执行getty命令,此命会调用login程序登陆,respawn是退出时重新执行login,
# 所以此时需要进行用户认证
::respawn:/sbin/getty 19200 tty1
::respawn:/sbin/getty 19200 tty2
::respawn:/sbin/getty 19200 tty3
::respawn:/sbin/getty 19200 tty4
# crtl +alt + del 键的作用
::ctrlaltdel:/sbin/reboot
# 设定关机时的动作,也比较关键。如果没有这一项的话,会出现开机后,
## 新创建的文件的内容可能会改变
::shutdown:/bin/umount -a -r
#################################################################################################

################################################################################################
# 提供用户,密码,组文件
# 密码由 openssl passwd -1 -salt `openssl rand -hex 4` 生成
# cat /mnt/sysroot/etc/passwd 
root:x:0:0:root:/root:/bin/sh
centos:x:500:500::/home/centos:/bin/sh

# cat /mnt/sysroot/etc/shadow 
root:$1$8dadd7c5$r7vRrjpLnBzq08KXzy4mA0:16296:0:99999:7:::
centos:$1$8dadd7c5$r7vRrjpLnBzq08KXzy4mA0:16307:0:99999:7:::

# cat /mnt/sysroot/etc/group 
root:x:0:
centos:x:500:
#############################################################################################

#############################################################################################
# 提供/etc/rc.d/rc.sysinit(在这里是/mnt/sysroot/etc/rc.d/rc.sysinit)文件,
## 文件内容如下:

#!/bin/sh
#
echo -e "\033[31mWelcom Mini Linux\033[0m"
mount -a     # 此选项会去读取文件/etc/fstab
mdev -s    # 是busybox提供的会自动扫描设备的命令
mount -n -o remount,rw /dev/sda2 /   # 这一项比较重要,如果没有这一项的话,
## 根文件系统是只读的

# 提供网卡地址
ifconfig lo 127.0.0.1 netmask 255.255.255.255 up
ifconfig eth0 172.16.10.14 netmask 255.255.0.0 up

# 如果编译时没有设置主机名,需要以下设置主机名
#[ -r /etc/sysconfig/network ] && . /etc/sysconfig/network
#[ -z "$HOSTNAME" -o "$HOSTNAME" == "(none)" ] && hostname localhost || hostname $HOSTNAME
#####/etc/sysconfig/network文件内容如下:
# HOSTNAME=www.clusteLinux.com
echo -e "\033[31mEND\033[0m"
##########################################################################################

###########################################################################################
# 创建fstab文件
/dev/sda2             /                       ext4    defaults         0 0
/dev/sda1         /boot                     ext4    defaults          0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
##########################################################################################

#########################################################################################
# 用户登录时,会去读取profile文件,在这里可以设置提示符等;
# vim  etc/profile 内容如下:

export PS1=[\u@\h \W]$
#########################################################################################

结果:

24

22

23 

26

 

四、安装dropbear

dropbear: 更小环境下,提供简单ssh远程连接服务。类似于openssh工具,但是它更轻量级。安装完dropbear后,会生成以下几个命令:

dropbear:是dropbear的服务端,类似于sshd

dbclient:是dropbear的客户端,类似于ssh

dropbearkey: 是秘钥生成工具,类似于ssh-keygen

ropbearconvert:实现openssh和dropbear之间的秘钥转换

    例如:dropbearconvert openssh dropbear /etc/ssh/ssh_host_rsa_key /etc/dropbear_rsa_host_key

scp:远程复制工具

安装配置dropbear

########1、安装dropbear#######################
# 下载dropbear软件,这里使用的版本是dropbear-2013.58.tar.bz2
# 开始安装

tar xf dropbear-2013.58.tar.bz2 
cd dropbear-2013.58
./configure
make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install
# dropbear默认是安装到/usr/local目录下的。./configure完成后,会生成一个option.h的文件,
## 里面定义了各种属性。例如:/var/run/dropbear.pid,所以在对应烦人磁盘上的目录要存在。

#####2、复制dropbear dbclient dropbearkey  scp到对应的虚拟根文件系统下############
# 使用bincp.sh的脚本,将命令和对应的库复制到虚拟根文件系统下,
## 脚本内容如下(具体还含义在函数博客中有详细说明)

#!/bin/bash
#
target=/mnt/sysroot/ 

[ -d $target ] || mkdir $target 

preCommand() {
    if which $1 &> /dev/null; then
    commandPath=`which --skip-alias $1`
    return 0
    else
    echo "No such command."
    return 1
    fi
} 

commandCopy() {
    commandDir=`dirname $1`
    [ -d ${target}${commandDir} ] || mkdir -p ${target}${commandDir}
    [ -f ${target}${commandPath} ] || cp $1 ${target}${commandDir}
} 

libCopy() {
    for lib in `ldd $1 | egrep -o "/[^[:space:]]+"`; do
    libDir=`dirname $lib`
    [ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}
    [ -f ${target}${lib} ] || cp $lib ${target}${libDir}
    done
} 

read -p "Plz enter a command: " command 

until [ "$command" == 'quit' ]; do 

  if preCommand $command ; then
    commandCopy $commandPath
    libCopy $commandPath
  fi 

  read -p "Plz enter a command: " command
done

# 需要注意的是,scp命令需要单独复制对应的命令和所依赖的库,避免和系统中的scp冲突

#####################3、定义安全的shell##########################
# vim /mnt/sysroot/etc/shells 内容如下,可以添加信任的shell,必要的
/bin/sh

#################4、移植nsswitch######################################
# 在使用ssh远程工具连接的时候,用户名的解析要借助于nsswitch。
# bash的用户名解析也是这种机制,所以如果要使用bash作为默认shell的话,移植nsswitch是必要的

cp -a -d /lib64/libnss_files-2.12.so /lib64/libnss_files.so.2  /mnt/sysroot/lib64/

cp -a -d /usr/lib64/libnss3.so /usr/lib64/libnss_files.so /usr/lib64/libnsspem.so \
/usr/lib64/libnsssysinit.so /usr/lib64/libnssutil3.so /mnt/sysroot/usr/lib64/


###############5、确保pid文件所在的目录存在###################################
mkdir /mnt/sysroot/var/run

###########################6、提供服务脚本####################

# vim /mnt/sysroot/etc/init.d/dropbear 内容如下:
#####################################################################
#!/bin/sh
#
dbprog='/usr/local/sbin/dropbear'
dbkeygen='/usr/local/bin/dropbearkey'
dsskey='/etc/dropbear/dropbear_dss_host_key'
rsakey='/etc/dropbear/dropbear_rsa_host_key'
rsakeysize=2048
dbport=22 

gendsskey() {
    if [ ! -f $dsskey ]; then
        echo "Generating dss key file."
        [ -d /etc/dropbear ] || mkdir /etc/dropbear
        $dbkeygen -t dss -f $dsskey
    fi
} 

genrsakey() {
    if [ ! -f $rsakey ]; then
        echo "Generating rsa key file."
        [ -d /etc/dropbear ] || mkdir /etc/dropbear
        $dbkeygen -t rsa -s $rsakeysize -f $rsakey
    fi
} 

start() {
    gendsskey
    genrsakey 

    if ! pidof dropbear &> /dev/null; then
        echo "Starting dropbear"
        $dbprog -p $dbport
        retval=$?
    else
        echo "$dbprog is already running..."
        return 1
    fi
    if [ $retval -eq 0 ]; then
        echo "OK"
        return 0
    else
        echo "Failure"
        return 1
    fi
} 

stop() {
    if pidof dropbear &> /dev/null; then
        echo "stopping dropbear sucess..."
        killall dropbear
        retval=$?
    else
        echo "$dbprog is not running..."
        return 1
    fi    
} 

restart() {
    stop
    sleep 1
    start
} 

usage() {
    echo "Usage: `basename $0` {start|stop|restart}"
} 

case $1 in 
start)
    start
    ;;
stop)
    stop
    ;;
restart)
    restart
    ;;
*)
    usage
    ;;
esac
##################################################################

chmod +x /mnt/sysroot/etc/init.d/dropbear


############7、提供devpts挂载文件系统并设置开机自启动########################

# /mnt/sysroot/etc/rc.d/rc.sysinit 在这个文件中,在mdev -s 之后,mount -a之前,添加:

# mdev -s
mkdir /dev/pts
# mount -a

#######在/mnt/sysroot/etc/fstab中添加#################################

devpts            /dev/pts        devpts  defaults    0 0 

#####################################################################

# 设置开机自启动
for i in /etc/rc/S* ; do
        $i start
done

#####################################################################

mkdir  /mnt/sysroot/etc/rc/
cd /mnt/sysroot/etc/rc/
ln -s   ../../etc/init.d/dropbear  ./S01dropbear

####################################################################

#################8、设置环境变量#########################

# 在 /mnt/sysroot/profile 文件中添加:
export PATH=/bin:/sbin:/usr/bin:/usr/sbin


结果:

27

28

29

30


 

五、通过安装nginx提供web服务

过程如下:

1、编译,配置ngnix
useradd nginx
./configure --conf-path=/etc/nginx/nginx.conf --user=nginx --group=nginx \
--without-pcre --without-http_rewrite_module
make && make install

# 提供主页面
echo "hello" > /usr/local/nginx/html/index.html

2、复制到虚拟根文件系统下
cp -a /etc/ngnix/ /mnt/sysroot/etc
cp -a /usr/local/nginx/ /mnt/sysroot/usr/local/

3、复制nginx所依赖的库文件
#使用bincp.sh脚本完成,注意此时nginx要在PATH环境变量中

4、修改 /mnt/sysroot/etc/profile 文件,添加:
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/nginx/sbin/

在minilinix上添加ngnix用户就可以了,结果:

31

32


至此配置完毕。本文是自己的理解,如有偏离和错误,欢迎指正。