概述:
本篇博客是一个自制类嵌入式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、目标系统启动界面
2、远程连接测试结果:
VMware端:(tty1输入账号密码登录需要ctrl+c几次才能登录,直接进入tty2测试即可)
Xshell端:测试远程ssh连接目标主机(以及目标主机远程连接其它主机)
3、整个操作结束后,目标系统/boot目录中各文件大小:
可以看到目标系统能够正常的运行并实现了远程ssh连接,此时目标系统还未安装各类工具软件,可自行配置yum源,yum源配置可参加作者博客Linux Redhat5.8系统配置yum源,接着就可以使用yum下载工具了,学习笔记,还有许多不足之处还望见谅!