概述:

       本篇博客是一个自制类嵌入式Linux系统的制作手册,内容涵盖使用宿主机通过busybox实

    现制作类嵌入式Linu系统的详细过程,一步一步教你如何制作属于你自己的linux系统,同时

    帮助你更加清楚的了解linux系统的组成结构,本篇博客需要读者对linux系统的启动流程及ssh

    远程连接有一定的了解,这部分很多博客都有介绍,这里就不说明了,不了解的读者可以先去

    看看这方面的博客。

      制作的整个过程比较漫长(主要是编译源码需要耗费大量时间,因此,在编译内核时,记

    得另起虚拟终端先完成其它操作),建议初次操作在VMware虚拟机中实现,以免操作过程不小心

    造成无法恢复的错误,整个操作过程需要耐心,细心的完成,请做好心理准备!


linux系统启动流程:

    POST-->BIOS(Boot Sequence)-->MBR(bootloader(grub))-->Kernel

        -->initrd(虚根)-->ROOTFS(真正的根文件系统)-->/sbin/init


目标系统主体构成:

    Kernel(linux-2.6.38.5编译得到) + initrd(busybox制作) + ROOTFS (busybox制作)


目标系统实现的主要功能:

    有虚拟终端、有主机名、实现账户认证、具有IP地址、能ssh远程登录; 


实现环境:

    本文所有操作均在Xshell5中通过ssh远程登录VMware中的宿主机完成

    VMware版本:VMware10  

    宿主机配置(虚拟机分配的资源是2核CPU,512M内存)


准备工作:

    1、需要一个作为宿主机的Linux;本文使用的是Redhat Enterprise Linux 5.8;

    2、在宿主机上提供一块额外的硬盘作为新系统的存储盘,

     作者添加的是一块20G的IDE接口的新硬盘;

    3、本文使用到的各源码版本信息:linux-2.6.38.5内核、busybox-1.20.2和dropbear-2016.72

    4、部分文件下载链接:

     busybox,dropbear,bincopy.sh脚本,编译2.6.38内核的.conf文件


一、准备磁盘

    在虚拟机中添加一块20G的IDE磁盘(此处为/dev/hda),供目标系统使用。接着打开宿主虚拟机


    1、划分分区

        cd
        fdisk /dev/hda
            n
            p
            1
            
            +100M
            n
            p
            2
            
            +512M
            w
            
        partprobe /dev/hda
        sync
        sync


    2、格式化分区并挂载至指定目录

        mke2fs -j /dev/hda1         #/boot分区
        mke2fs -j /dev/hda2         #/分区
        mkdir /mnt/{boot,sysroot}
        mount /dev/hda1 /mnt/boot
        mount /dev/hda2 /mnt/sysroot

    

二、编译内核及必要模块

    解压linux-2.6.38.5.tar.gz至/usr/src/

    1、下载较新版本linux内核

        cd
        wget "https://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.38.5.tar.gz"
        tar xf linux-2.6.38.5.tar.gz -C /usr/src

    2、编译需要的模块及内核核心

        说明:make menuconfig    # 编译配置

      根据您的实际和规划选择所需要的功能;本实例计划制作一个具有网络的功能的微型

      linux且不打算使用内核模块,因此,这里选择把本机对应的网卡驱动直接编译进了内

      核。作者使用的是vmware Workstation虚拟机,所以,所需的网上驱动是pcnet32的,

      其它的均可按需要进行选择。选择完成后需要保存至当前目录下.config文件中。为了

       实现后面的功能,请务必将文件系统中的ext3和网卡的驱动程序直接编译进内核;否则,

      就需要手动装载这些相关文件系统的模块;

        (作者最终使用的.config配置文件为config-2.6.38.5-i686.cfg,见博文顶部下载链接)

        cd /usr/src
        ln -sv linux-2.6.38.5 linux
        cd linux
        # 下载配置文件kernel-2.6.38.1-i686.cfg,复制到当前目录中,并重命名为.config。
        cp /root/kernel-2.6.38.1-i686.cfg .config
        make menuconfig     # 编译配置,根据个人需求进行修改
        screen
        make SUB=X86        # 编译内核核心

    

三、给系统导入内核vmlinuz (编译完成后,在/arch/x86/boot找到bzImage文件,将该文件作为内核)

    提示:由于编译过程比较慢,本步骤可在其余操作完成后再执行

    cd /usr/src/linux/arch/x86/boot       
    
    cp bzImage /mnt/boot/vmlinuz
    sync
    sync

    

四、编译busybox

    1、下载busybox-1.20.2.tar.bz2

        tar xf busybox-1.20.2.tar.bz2 -C /root

    2、配置busybox编译文件

      说明:make menuconfig    # 编译配置

      1、此处需要选择 Busybox Settings --> Build Options -->  Build BusyBox as 

         a static binary (no shared libs),这样可以把Busybox编译成一个不使用共享库的

         静态二进制文件,从而避免了对宿主机的共享库产生依赖,

      2、同时,你还可以修改busybox的安装位置,方法为:Busybox Settings --> 

         Installation Options --> (./_install) BusyBox installation prefix,修安装位置

         ,本文作者没有对其进行修改。

        cd /root/busybox-1.20.2
        make menuconfig     # 编译配置


    3、进入busybox-1.20.2的include目录下,创建mtd目录,并复制ubi-user.h文件

      说明:旧版本的内核缺乏编译busybox-1.20.2所需的头文件ubi-user.h

        cd /root/busybox-1.20.2/include
        mkdir mtd
        cp /usr/src/linux-2.6.38.5/include/mtd/ubi-user.h ./mtd/

    4、编译busybox

        cd /root/busybox-1.20.2
        make install

五、制作initrd.gz

    1、复制_install文件至/tmp/busybox,删除不必要的文件并创建需要的目录

        cd /root/busybox-1.20.2
        mkdir -pv /tmp/busybox
        cp _install/* /tmp/busybox/ -a
        cd /tmp/busybox/
        ls
        rm -f linuxrc 
        mkdir proc sys etc dev mnt/sysroot lib/modules tmp -pv


    2、手动创建两个必要的设备文件

        cd /tmp/busybox/
        mknod dev/console c 5 1
        mknod dev/null c 1 3

        

    3、为initrd制作init程序,实现rootfs的切换

        cd /tmp/busybox/
        vim init
        添加如下内容:
            #!/bin/sh
            #cd 
            echo "mountting proc and sys..."
            mount -t proc proc /proc 
            mount -t sysfs sysfs /sys
            echo "init the other devices..."
            mdev -s
            echo "mount /dev/hda2..."
            mount -t ext3 /dev/hda2 /mnt/sysroot
            echo "switch_root..."
            exec switch_root /mnt/sysroot /sbin/init
        
        chmod +x init  #    添加执行权限


    4、给系统制作initrd 

        cd /tmp/busybox/
        find . | cpio -H newc --quiet -o | gzip -9 > /mnt/boot/initrd.gz
        sync
        sync

        

六、安装grub并编辑grub配置文件(为系统创建所需的引导程序)

    grub-install --root-directory=/mnt /dev/hda
    cd /mnt/boot
    vim grub/grub.conf
    添加内容形如:
        default=0
        timeout=3
        title mix-busybox-make Linux (2.6.38)
                root(hd0,0)
                kernel /vmlinuz ro root=/dev/hda2
                initrd /initrd.gz
    sync
    sync

                

七、制作sysroot(建立真正的根文件系统)

    1、复制busybox

        cd /root/busybox-1.20.2
        cp _install/* /mnt/sysroot/ -a
        cd /mnt/sysroot/
        ls
        rm -f linuxrc 
        mkdir proc sys dev/pts tmp var/{local,lock,run,log} -pv
        mkdir mnt/sysroot lib/modules etc/rc.d/init.d root usr/lib boot media -pv


    2、为init进程提供配置文件:(inittab)

        cd /mnt/sysroot
        vim  etc/inittab
        添加如下内容:
            ::sysinit:/etc/rc.d/rc.sysinit
            ::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
            ::ctrlaltdel:/sbin/reboot
            ::shutdown:/bin/umount -a -r

            

    3、为系统准备一个“文件系统表”配置文件/etc/fstab

    说明:devpts是伪终端文件系统,用于远程连接

        cd /mnt/sysroot
        vim  etc/fstab
        添加如下内容:
            sysfs    /sys    sysfs   defaults   0 0
            proc     /proc    proc    defaults   0 0
            devpts    /dev/pts  devpts   mode=620   0 0
            /dev/hda1  /boot   ext3    defaults   0 0
            /dev/hda2  /     ext3    defaults   1 1

    4、创建设备文件

        cd /mnt/sysroot
        mknod dev/console c 5 1
        mknod dev/null c 1 3

    

    5、建立系统初始化脚本文件

        cd /mnt/sysroot
        vim  etc/rc.d/rc.sysinit
        添加如下内容:
            echo -e "\twelcome to \033[31mMix\033[0m Linux"
            echo -e "Set the hostname"
            [ -f /etc/hostname ] && . /etc/hostname
            [ -z "$HOSTNAME" -o "$HOSTNAME" == '(none)' ] && HOSTNAME="localhost"
            hostname $HOSTNAME
            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
            echo -e "start log service..."
            syslogd
            klogd
            # 网络IP地址根据个人情况自行设定,例如我的网关是192.168.134.1,
            # 设置IP地址为:192.168.134.9/24
            # 提示:编辑脚本时将中文注释删除,否则可能会出错
            echo -e "Configuring loopback interface ..."
            ifconfig  lo  127.0.0.1/24
            ifconfig eth0 192.168.134.9/24
            
        # 给脚本添加执行权限
        chmod +x  etc/rc.d/rc.sysinit

        

    6、rc.sysinit中启用了日志进程,为避免大量日志显示于控制台打断正常工作,

    我们为日志进程建立日志配置文件,为其指定将日志发送至/var/log/{messages,secure}文件中

        1、在etc下创建配置文件syslog.conf

            cd /mnt/sysroot
            vim etc/syslog.conf
                *.info;auth.none        /var/log/messages
                auth.*             /var/log/secure


        2、手动创建/var/log/secure文件,并指定权限(用户登录日志)

            touch /var/log/secure
            chmod 600 /var/log/secure

            

    7、在系统启动时为系统提供主机名称

    说明:从rc.sysinit文件中可以看出本系统中作者的主机名存储在etc/hostname文件中,

      你也可以自行指定路径,并修改rc.sysinit中相关内容即可。

        cd /mnt/sysroot
        vim etc/hostname
        添加如下内容:
            HOSTNAME=MixLinux

 

    8、inittab中配置了用户需要通过账户认证才能登录系统,因此接下来需要添加必要的文件

    说明:这里为目标主机提供root用户的认证信息

        1、为目标主机建立passwd帐号文件、group帐号文件、shadow影子口令文件:

            grep "^(root)\>" /etc/passwd > /mnt/sysroot/etc/passwd
            grep "^(root)\>" /etc/shadow > /mnt/sysroot/etc/shadow
            grep "^(root)\>" /etc/group > /mnt/sysroot/etc/group

        2、为目标主机移植bash程序(移植二进制程序的脚本见博文顶部下载链接)

       说明:未移植bash前,作者在在运行目标系统时出现以下错误

           在挂载/dev/hda2时报错:cat't find file or directory

                    /root/bincopy.sh
                        键入bash,最后输入q退出
                    sync
                    sync

    9、为系统设置输入提示信息([root@localhost root]#)

        cd /mnt/sysroot/root
        vim .bash_profile 
            PS1='[\u@\h \W]\$ '
            export PS1


    10、执行完第9步后,提示信息可能无法获取用户名,并会出现I have no name!的提示信息

    原因:这个主要是没有配置名称解析服务造成的。

    提示:若要为目标主机提供ssh远程连接服务,则该步骤可跳过 

        1、为名称解析服务复制必要的库文件:

            cd /mnt/sysroot
            cp -d /lib/libnss_files*  lib/
            cp -d /lib/libnss_dns*  lib/

        2、为目标主机建立名称解析文件nsswitch.conf

            vim etc/nsswitch.conf
            添加如下内容:
                passwd:  files
                group:  files
                shadow:  files
                hosts:  files dns

    11、在系统登录时提供banner信息  

      提示:issue中的内容可以根据你的需要进行修改。

        cp /etc/issue /mnt/sysroot/etc/
        vim /mnt/sysroot/etc/issue   # 自定义显示信息

        

八、接下来将此块硬盘接入一个新的主机(这里使用的是虚拟机),启动并测试使用。

    提示:在测试前,务必在宿主机中多次键入sync指令,避免修改后的数据未同步至硬盘中

     若在测试时发生分区损坏问题,可参见作者另一篇博文:Linux裁剪系统时硬盘损坏的解决方法


九、通过dropbear为系统提供ssh远程连接服务 

    1、下载dropbear

cd /root
wget "https://matt.ucc.asn.au/dropbear/dropbear-2016.72.tar.bz2" --no-check-certificate

    2、解压编译dropbear

        tar xf dropbear-2016.72.tar.bz2 
        cd /root/dropbear-2016.72
        ./configure
        make
        make install

    3、移植dropbear

     提示:移植二进制程序及其依赖的库文件,方能实现其在目标系统上正常运行。建议使用脚本

     进行(这里将其保存为bincopy.sh),其会自动移植指定的命令及依赖的库文件。

     脚本参见博文顶部下载链接

        /root/bincopy.sh
            # 依次输入dropbear、dropbearkey、dbclient,最后输入q退出
            # 这些命令会被存储于目标系统的/usr/local/sbin
            #  或/usr/local/bin目录中
            
         sync
         sync


    4、添加需要的配置文件和依赖库文件

        cd /mnt/sysroot
        vim etc/nsswitch.conf
        # 添加如下内容:
            passwd: files
            group: files
            shadow: files
            hosts: files dns
        cp -d /lib/libnss_files* /mnt/sysroot/lib/
        cp -d /usr/lib/libnss3.so  /mnt/sysroot/usr/lib/
        cp -d /usr/lib/libnss_files* /mnt/sysroot/usr/lib/


    5、创建shells文件、编辑etc/fstab、为远程登录的用户提供伪终端设备文件

      提示:在第七步中已经完成部分操作,完成部分可跳过

        说明:dropbear默认情况下仅允许默认shell存在于/etc/shells文件中的用户远程登录

        cd /mnt/sysroot
        vim etc/shells
        添加如下内容:
            /bin/sh
            /bin/bash
            /bin/hush
            /bin/ash
        vim etc/fstab  # 第七步骤中已经完成
        # 添加如下内容:
            devpts    /dev/pts    devpts  mode=620   0 0
        mkdir dev/pts   # 第七步骤中已经完成


    6、使用dropbear生成主机秘钥

        说明:dropbear中的选项"-t:指定秘钥编码类型","-f:秘钥存路径","2048:秘钥长度"

        mkdir /mnt/sysroot/etc/dropbear
        dropbearkey -t rsa -f /mnt/sysroot/etc/dropbear/dropbear_rsa_host_key 2048

   

    7、测试

        启动目标主机,设定好网络属性后(一切正常,则此时应该已经设定完成)

        提示:由于目标系统添加了日志功能,目标系统启动后将向硬盘中写入数据,此时宿主机

        若还挂载着硬盘,将会造成磁盘数据混乱。因此本次测试前,记得将/mnt/sysroot/目录

        下的文件打包备份一份,以备下回恢复分区使用

        使用如下命令启动dropbear服务即可。

            /usr/local/sbin/dropbear # 启用ssh远程连接服务
            /usr/local/bin/dbclient -l root 192.168.134.2 # 远程登录其它主机


        接下来就可以远程进行连接测试了。 

 

十、作者测试结果 

1、目标系统启动界面

从开始到结束,手把手教你使用busybox构建类嵌入式Linux系统_第1张图片


2、远程连接测试结果:

    VMware端:(tty1输入账号密码登录需要ctrl+c几次才能登录,直接进入tty2测试即可)

从开始到结束,手把手教你使用busybox构建类嵌入式Linux系统_第2张图片


Xshell端:测试远程ssh连接目标主机(以及目标主机远程连接其它主机)

从开始到结束,手把手教你使用busybox构建类嵌入式Linux系统_第3张图片


3、整个操作结束后,目标系统/boot目录中各文件大小:

从开始到结束,手把手教你使用busybox构建类嵌入式Linux系统_第4张图片  


可以看到目标系统能够正常的运行并实现了远程ssh连接,此时目标系统还未安装各类工具软件,可自行配置yum源,yum源配置可参加作者博客Linux Redhat5.8系统配置yum源,接着就可以使用yum下载工具了,学习笔记,还有许多不足之处还望见谅!