前言

系统:CentOS 6(VMware Workstation Pro)
前期准备:
Kernel 3.10.67 (其实大体差不多)
busybox 1.
22.1 --- 提供init服务和诸多命令
dropbear 2013.58 --- 提供ssh服务
开发包组:"Development Tools" "Server Platform Development"
Kernel : https://mirrors.edge.kernel.org/pub/linux/kernel/
busybox:https://busybox.net/downloads/
dropbear:https://matt.ucc.asn.au/dropbear/releases/
以上链接都是是官方的链接

补充一下系统启动的 流程

POST --> BootSequence(BIOS) --> BootLoader --> Kernel (ramdisk) --> rootfs(装载跟文件系统) --> /sbin/init

步骤:

  1. 前期准备
  2. 编译内核
  3. 编译busbox
  4. 编译dropbear
  5. 测试以及添加软件

博主写这篇文章的时候,已经在这个上面耽误了很多时间,头痛欲裂。


废话不多说,开整!

一:前期准备

  1. 在虚拟机新建一块8Gb的硬盘,昨晚后面mini linux的系统盘

  2. 分区

     ~]# fdisk /dev/sdb

    创建两个主分区,第一个100M,第二个5G(全部分配也行)即可,其实用不到这么多

  3. 分别格式化为ext4

     ~]# mkfs.ext4 /dev/sdb1
     ~]# mkfs.ext4 /dev/sdb2
  4. 挂载到当前主机的/mnt/boot /mnt/sysroot

     ~]# mkdir -pv /mnt/{boot,sysroot}
     ~]# mount /dev/sdb1 /mnt/boot
     ~]# mount /dev/sdb2 /mnt/sysroot
  5. 安装grub

     ~]# grub-install --root-directory=/mnt/ /dev/sdb
     ~]# ls /mnt/boot

    查看/mnt/boot目录下是否存在grub目录,存在即安装成功

  6. 编辑grub配置文件

     ~]# vim /mnt/boot/grub/grub.conf
     #编辑以下内容
     default 0
     timeout 3
     title Mini Linux(3.10.67)
         root(hd0,0)
         kernel /vmlinuz ro root=/dev/sda2
  7. 在/mnt/sysroot下创建常用文件夹

     ~]# cd /mnt/sysroot
     ~]# mkdir -p root home etc/{rc.d,sysconfig,modules} lib lib64 usr/{lib,lib64} sys proc dev boot mnt media bin sbin var/run

前期准备完成!

二:编译内核

1. 下载kernel源代码和开发环境

~]# wget https://mirrors.edge.kernel.org/pub/linux/kernel/v3.x/linux-3.10.67.tar.xz
~]# tar xvf linux-3.10.67.tar.xz -C /usr/src/
~]# cd /usr/src && ln -s linux-3.19.67 linux

解压到/usr/src,并为其创建软连接;

安装开发包组

~]# yum update -y
~]# yum groupinstall "Development Tools" "Server Platform Development" -y

2. 编译前配置

由于我们要制作的是Mini版的linux,所以要先去掉所有扩展的模块和功能,保证配置文件.config干净;

~]# make allnoconfig        #去掉全部可选功能
~]# make menuconfig         #进入文本配置界面

下面开始配置内核

主要“M”表示编译成模块,“*”表示编译进内核,空表示不编译

编译64bit kernel.png
选定编译64位的内核64-bit kernel
然后选择第三项:

Enable loadable module support 
#支持可加载模块支持,选定后,回车进入配置

动态加载和卸载.png

Module unloading 
#支持动态卸载

cpu.png

选择第5项:Processor type and features 设置cpu,回车进入下级菜单

cpu2.png

把第一项选定,修改第八项(如图):

Symmetric multi-processing support  #对称多处理器支持(多核)
Processor family                    #选择处理器系列,我这里是酷睿系列

PCI总线.png

开启PCI总线支持:

Bus options (PCI etc.)  #顶级菜单第七项,回车进入,回车后如下图
    PCI support         #启用PCI

PCI.png



配置可执行文件的支持,如下图:
可执行文件格式.png
进入二级目录选定以下选项:

Kernel support for ELF binaries #ELF二进制格式支持
Write ELF core dumps with partial segments  #ELF二进制格式支持
Kernel support for scripts starting with #! #脚本文件的支持
#如下图

可执行文件2.png

配置内核的网络支持
返回至一级目录;进入如下菜单:

-*- Networking support
        Networking options
            选定如图所示的选项

Network3.png

解释:

TCP/IP networking   #TCP/IP支持
    IP: multicasting    #多播/组播支持
    IP: advanced router #高级路由
    IP: kernel level autoconfiguration  #内核自动控制

其他的选项可不选

配置硬件驱动

回到顶级目录

Device Drivers  #驱动配置
    Generic Driver Options  #通用驱动程序选项
         Maintain a devtmpfs filesystem to mount at /dev    #维护一个devtmpfs文件系统挂载到/dev(设备文件)
            Automount devtmpfs at /dev, after the kernel mounted the rootfs #自动将devtmpfs挂载到/dev

如下图:
devtmpfs.png

配置硬盘驱动,博主在虚拟机进行测试的,硬盘是SCSI口的;
查看主机的硬盘详情;

~]# lspci

SCSI.png
可以看到是SCSI,Fusion-MPT格式的,我们进入Device Drivers目录(如下图)

Device.png

进入下面的菜单

SCSI device support
    SCSI device support     #启用SCSI设备支持
    SCSI disk support       #启用SCSI磁盘支持

再次回到Device Drivers菜单,然后进入以下菜单

[*] Fusion MPT device support   #启用Fusion MPT设备支持

选定以后勾选以下选项
MPT.png

    Fusion MPT ScsiHost drivers for SPI     #用于SPI的Fusion MPT ScsiHost驱动程序(串行硬盘接口)
    Fusion MPT ScsiHost drivers for FC      #用于FC的Fusion MPT ScsiHost驱动程序(光纤通道)
    Fusion MPT ScsiHost drivers for SAS     #用于SAS的Fusion MPT ScsiHost驱动程序(SAS通道和stat接口类似)
    Fusion MPT misc device (ioctl) driver       #Fusion MPT杂项设备(ioctl)驱动程序(必选,因为我们看到的信息就是MPT设备)
    Fusion MPT logging facility     #日志功能,可有可无

这一步操作,把SCSI驱动程序编译进内核,接着配置网卡驱动,回到Device Drivers菜单,选择Network device support,如图,要先把它选定
网络设备.png
然后回车进入目录
网络2.png
选择如图几项,其他都不需要,然后进入Ethernet driver support,选择如下图几项,没有勾选的一律不选择,但是注意要和自己的平台硬件匹配,我这里是e1000
网络3.png

注意:我们把Intel(R) PRO/1000 Gigabit Ethernet support编译成模块,也就是e1000的网卡驱动

接着:我们配置usb驱动,用以驱动键盘和鼠标
回到Device Drivers找到USB support,勾选然后进入菜单
我们主要启用usb2.0 usb1.0 usb3.0,如下图
usb1.png
usb2.png

usb设备启用以后,我们启用输入设备(键盘、鼠标)驱动

回到Device Drivers找到Input device support,勾选然后进入菜单
主要配置键盘和鼠标:勾选以下几项,其他暂时不勾选
key.png
最后一步,选择支持的文件系统
回到顶级菜单,进入File systems;选择内核可识别的文件系统,这里我们需要支持ext3ext4:
ext.png

保存退出

3. 编译内核

~]# make -j 4 bzImage

只编译内核,编译完成的路径在:arch/x86/boot/bzImage
复制内核文件到/mnt/boot

~]# cp arch/x86/boot/bzImage /mnt/boot/vmlinuz

4. 编译网卡模块

~]# make M=/make M=drivers/net/ethernet/intel/e1000

复制内核模块到目标(mini linux)

~]# cp drivers/net/ethernet/intel/e1000/e1000.ko /mnt/sysroot/lib/modules/e1000.ko

内核编译到此结束

三 :移植busybox

busybox:https://busybox.net/downloads/

1.下载busybox

~]# wget https://busybox.net/downloads/busybox-1.22.1.tar.bz2
~]# tar xvf busybox-1.22.1.tar.bz2
~]# cd busybox-1.22.1

解压源代码

2.编译busybox

由于我们是移植,打造mini liux,需要静态编译busybox,需要的软件包glibc-static

~]# yum install glibc-static -y

编译前配置:

~]# make menuconfig

我们需要编译成单文件,不需要动态库;依次进入以下菜单

Busybox Settings
    Build Options
        Build BusyBox as a static binary (no shared libs)

busybox.png
然后退出并保存

编译busybox:

~]# make -j 4
~]# make install

默认安装在源码目录下的_install文件夹

3.移植busybox

~]# cp -a -d _install/* /mnt/sysroot/

-a -d不改变属性,不追踪符号链接(直接复制符号链接)

4.提供inittab文件

在/mnt/sysroot/etc下新建文件inittab,键入以下内容

::sysinit:/etc/rc.d/rc.sysinit      #开机执行系统初始化脚本,脚本位于/etc/rc.d/rc.sysinit
::respawn:/sbin/getty 9600 tty1     #打印登录提示符,创建虚拟终端(tty1),速率为9600
::respawn:/sbin/getty 9600 tty2
::respawn:/sbin/getty 9600 tty3
::ctrlaltdel:/sbin/reboot           #用户按Ctrl+Alt+Del执行/sbin/reboot
::shutdown:/bin/umount -a -r        #用户执行关机时,卸载所有磁盘

编辑初始化脚本/mnt/etc/rc.d/sysinit

#!/bin/sh
#

local_info="\033[32m[Info]\033[0m"
echo -e "\Welcome to \033[32mMini\033[0m Linux !"

echo -e "${local_info} Mounting filesystem..."
mount -t proc proc /proc
mount -t sysfs sysfs /sys

echo -e "${local_info} Scan /sys and to populate to /dev..."
mdev -s     #将sys目录下识别到的设备全部输出到dev目录下

mount -o remount,rw /dev/sda2 /
mount -t ext4 /dev/sda1 /boot
[ -d /dev/pts ]||mkdir /dev/pts     #挂载devpts之前,要先检查dev下是否存在pts,不存在就创建,否则devpts会挂载失败
mount -a
echo -e "${local_info} Loading the e1000 module..."
insmod /lib/modules/e1000.ko    #装载网卡驱动

echo -e "${local_info} Seting network..."
ifconfig lo 127.0.0.1 up
ifconfig eth0 192.168.123.123 up
echo -e "${local_info} Seting Hostname..."
[ -f /etc/sysconfig/network ]&& . /etc/sysconfig/network
[ -z ${HOSTNAME} -o "$HOSTNAME" == '(none)' ]&& HOSTNAME="localhost"
hostname $HOSTNAME

提供fstab profile文件,文件路径/mnt/sysroot/etc/fstab /mnt/sysroot/etc/profile

#fstab
sysfs           /sys    sysfs   defaults        0       0
proc            /proc   proc    defaults        0       0
devpts          /dev/pts        devpts  mode=620        0       0
/dev/sda1       /boot   ext4    defaults        0       0
/dev/sda2       /       ext4    defaults        0       0

profile

#profile
export PS1='[\u@\h \W]\$'   #这一行主要是命令提示符最前面的信息; [用户名@主机名 当前路径]\$ 
# \$ 表示用户uid为0,显示为#,uid不为0显示$
if [ $UID -eq 0 ];then
    export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
fi

建立用户文件,组文件,密码文件

~]# cd /mnt/sysroot/etc
~]# touch passwd group shadow

分别键入以下信息:
注意#passwd不要添加,只是为了区分那些文件填写如什么内容

#passwd
root:x:0:0:Admin User:/root:/bin/ash

#group
root:x:0:

#shadow
root:EOTtKzdfBrqDk:18164:0:99999:7:::

EOTtKzdfBrqDk表示用户密码;创建新密码如下:

~]# openssl passwd -1 -salt ABCD
#输入密码,把输出的字符串全部复制,替换上面的密码,-1表示md5加密,-salt表示密码中添加杂质

设置shadow文件权限为400

~]# chmod 400 shadow
~]# sync

完成数据同步后,关闭宿主机,新建虚拟机,磁盘选择之前我们新建的,应该可以正常进行登录系统了
到此,busybox移植完毕

注意:进行测试的时候宿主机和目标主机不能同时开机,挂起也不行,容易出现文件系统错误!

四: 编译dropbear

dropber为其提供ssh服务

1.下载dropbear源代码

~]# wget https://matt.ucc.asn.au/dropbear/releases/dropbear-2013.58.tar.bz2
~]# tar xvf dropbear-2013.58.tar.bz2
~]# cd dropbear-2013.58

新版本的dropbear同样可以,我这里暂时使用13.58版本

2.编译dropbear

~]# .configure

注意:不要添加--enable-pam,因为busybox不支持pam认证机制

~]# make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
~]# make install

默认安装到/usr/local/sbin /usr/local/bin

3.移植dropber到mini linux

由于有依赖库,我们这里用脚本进行移植,脚本如下:

此处内容需要评论回复后(审核通过)方可阅读。

~]# bincp.sh

根据提示,一次只能移植一个程序,分别移植:dropbear dbclient dropbearkey dropbearconvert scp

4.生成key文件

~]# mkdir /mnt/sysroot/etc/dropbear&&cd /mnt/sysroot/etc/dropbear
~]# dropbearkey -t rsa -s 2048 -f dropber_rsa_host_key
~]# dropbearkey -t dss -f dropbear_dss_host_key

5.配置nsswitch

在/mnt/sysroot/etc下新建文件nsswitch.conf;键入以下内容:

passwd: files
group:  files
shadow: files
hosts:  files dns

移植ns的库文件:

~]# cd /mnt/sysroot/lib64
~]# cp -d /lib64/libnss_files* ./
~]# cd ../usr/lib64
~]# cp -d /usr/lib64/libnss3.so ./
~]# cp -d libnss_files* ./
~]# sync

五: 测试、软件添加

关闭宿主机,启动目标主机;
我的第一个终端打不开,需要第二个终端才能ctrl+alt+f2
mini.png
这是我登录后的系统,系统提示在issue中定义;下面是我的issue文件内容;文件位于/etc/issue

Welcome to YouTm Mini Linux(https://blog.beijixs.cn:10443)
Kernel \r 

\r是一个内置宏,显示内核版本的

hostname在/etc/sysconfig/network定义;如下

HOSTNAME=YouTm

下面我们启动dropbear进行测试:

~]# dropbear -E -F

前台运行,方便调试,-p只当监听端口
下面是我链接成功的图片:
ssh.png

如果链接不上,未知错误,建议修改用户密码,可能是之前的密码dropbear无法解析,博主就出现过这样的问题,反反复复登录不上去,修改密码就行了

附一个dropbear启动脚本,通过pid文件判断dropbear是否运行,由于系统没有配置关机后操作,所以用pid确定程序是否运行有bug,因为系统关机的时候,dropbear没有停止运行,导致pid未被清除;

#!/bin/sh
#COLOR#
green="\033[32m"
red="\033[31m"
end="\033[0m"
##COLOR#
PID_FILE="/var/run/dropbear.pid"
fun_status(){
    if [ -f "$PID_FILE" ];then
        PID=`cat ${PID_FILE}`
        echo -e "Dropbear is runing(${green}pid:${PID}${end})."
        return 0
    else
        PID="none"
        echo -e "Dropbear is ${red}not${end} run."
        return 23
    fi
}
fun_start(){
    if fun_status &> /dev/null;then
        echo -e "Dropbear is runing(${green}pid:${PID}${end})."
        exit 2
    else
        echo -n "Starting dropbear..."
        /usr/local/sbin/dropbear
        sleep 3
        if fun_status &> /dev/null;then
            echo -e "${green}done${end}"
        else
            echo -e "${red}failure${end}"
        fi
    fi
}
fun_stop(){
    if fun_status &> /dev/null;then
        echo -n "Stoping dropbear..."
        kill $PID
        echo -e "${green}done${end}"
    fi
}
fun_restart(){
    fun_stop
    fun_start
}
AGE=$1
case $AGE in
    start|stop|restart|status)
        fun_$AGE
    ;;
    *)
        echo "Usage:/etc/init.d/dropbear {start|stop|restart|status}"
    ;;
esac
Last modification:September 30th, 2019 at 08:41 pm
If you think my article is useful to you, please feel free to appreciate