转自: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下载工具了,学习笔记,还有许多不足之处还望见谅!