[转]从开始到结束,手把手教你使用busybox构建类嵌入式Linux系统
转自:http://tobeys.blog.51cto.com/10620284/1775531
概述:
本篇博客是一个自制类嵌入式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、划分分区
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
cd fdisk /dev/hda n p 1 +100M n p 2 +512M w partprobe /dev/hda sync sync |
2、格式化分区并挂载至指定目录
1
2
3
4
5
|
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内核
1
2
3
|
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,见博文顶部下载链接)
1
2
3
4
5
6
7
8
|
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文件,将该文件作为内核)
提示:由于编译过程比较慢,本步骤可在其余操作完成后再执行
1
2
3
4
5
|
cd /usr/src/linux/arch/x86/boot cp bzImage /mnt/boot/vmlinuz sync sync |
四、编译busybox
1、下载busybox-1.20.2.tar.bz2
1
|
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,修安装位置
,本文作者没有对其进行修改。
1
2
|
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
1
2
3
|
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
1
2
|
cd /root/busybox-1 .20.2 make install |
五、制作initrd.gz
1、复制_install文件至/tmp/busybox,删除不必要的文件并创建需要的目录
1
2
3
4
5
6
7
|
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、手动创建两个必要的设备文件
1
2
3
|
cd /tmp/busybox/ mknod dev /console c 5 1 mknod dev /null c 1 3 |
3、为initrd制作init程序,实现rootfs的切换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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
1
2
3
4
|
cd /tmp/busybox/ find . | cpio -H newc --quiet -o | gzip -9 > /mnt/boot/initrd .gz sync sync |
六、安装grub并编辑grub配置文件(为系统创建所需的引导程序)
1
2
3
4
5
6
7
8
9
10
11
12
|
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
1
2
3
4
5
6
7
|
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)
1
2
3
4
5
6
7
8
9
10
11
12
|
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是伪终端文件系统,用于远程连接
1
2
3
4
5
6
7
8
|
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、创建设备文件
1
2
3
|
cd /mnt/sysroot mknod dev /console c 5 1 mknod dev /null c 1 3 |
5、建立系统初始化脚本文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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
1
2
3
4
|
cd /mnt/sysroot vim etc /syslog .conf *.info;auth.none /var/log/messages auth.* /var/log/secure |
2、手动创建/var/log/secure文件,并指定权限(用户登录日志)
1
2
|
touch /var/log/secure chmod 600 /var/log/secure |
7、在系统启动时为系统提供主机名称
说明:从rc.sysinit文件中可以看出本系统中作者的主机名存储在etc/hostname文件中,
你也可以自行指定路径,并修改rc.sysinit中相关内容即可。
1
2
3
4
|
cd /mnt/sysroot vim etc /hostname 添加如下内容: HOSTNAME=MixLinux |
8、inittab中配置了用户需要通过账户认证才能登录系统,因此接下来需要添加必要的文件
说明:这里为目标主机提供root用户的认证信息
1、为目标主机建立passwd帐号文件、group帐号文件、shadow影子口令文件:
1
2
3
|
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
1
2
3
4
|
/root/bincopy .sh 键入 bash ,最后输入q退出 sync sync |
9、为系统设置输入提示信息([root@localhost root]#)
1
2
3
4
|
cd /mnt/sysroot/root vim .bash_profile PS1= '[\u@\h \W]\$ ' export PS1 |
10、执行完第9步后,提示信息可能无法获取用户名,并会出现I have no name!的提示信息
原因:这个主要是没有配置名称解析服务造成的。
提示:若要为目标主机提供ssh远程连接服务,则该步骤可跳过
1、为名称解析服务复制必要的库文件:
1
2
3
|
cd /mnt/sysroot cp -d /lib/libnss_files * lib/ cp -d /lib/libnss_dns * lib/ |
2、为目标主机建立名称解析文件nsswitch.conf
1
2
3
4
5
6
|
vim etc /nsswitch .conf 添加如下内容: passwd : files group: files shadow: files hosts: files dns |
11、在系统登录时提供banner信息
提示:issue中的内容可以根据你的需要进行修改。
1
2
|
cp /etc/issue /mnt/sysroot/etc/ vim /mnt/sysroot/etc/issue # 自定义显示信息 |
八、接下来将此块硬盘接入一个新的主机(这里使用的是虚拟机),启动并测试使用。
提示:在测试前,务必在宿主机中多次键入sync指令,避免修改后的数据未同步至硬盘中
若在测试时发生分区损坏问题,可参见作者另一篇博文:Linux裁剪系统时硬盘损坏的解决方法
九、通过dropbear为系统提供ssh远程连接服务
1、下载dropbear
1
2
|
cd /root wget "https://matt.ucc.asn.au/dropbear/dropbear-2016.72.tar.bz2" --no-check-certificate |
2、解压编译dropbear
1
2
3
4
5
|
tar xf dropbear-2016.72. tar .bz2 cd /root/dropbear-2016 .72 . /configure make make install |
3、移植dropbear
提示:移植二进制程序及其依赖的库文件,方能实现其在目标系统上正常运行。建议使用脚本
进行(这里将其保存为bincopy.sh),其会自动移植指定的命令及依赖的库文件。
脚本参见博文顶部下载链接
1
2
3
4
5
6
7
|
/root/bincopy .sh # 依次输入dropbear、dropbearkey、dbclient,最后输入q退出 # 这些命令会被存储于目标系统的/usr/local/sbin # 或/usr/local/bin目录中 sync sync |
4、添加需要的配置文件和依赖库文件
1
2
3
4
5
6
7
8
9
10
|
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文件中的用户远程登录
1
2
3
4
5
6
7
8
9
10
11
|
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:秘钥长度"
1
2
|
mkdir /mnt/sysroot/etc/dropbear dropbearkey -t rsa -f /mnt/sysroot/etc/dropbear/dropbear_rsa_host_key 2048 |
7、测试
启动目标主机,设定好网络属性后(一切正常,则此时应该已经设定完成)
提示:由于目标系统添加了日志功能,目标系统启动后将向硬盘中写入数据,此时宿主机
若还挂载着硬盘,将会造成磁盘数据混乱。因此本次测试前,记得将/mnt/sysroot/目录
下的文件打包备份一份,以备下回恢复分区使用
使用如下命令启动dropbear服务即可。
1
2
|
/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下载工具了,学习笔记,还有许多不足之处还望见谅!