概述

busybox是一个轻量级的嵌入式操作系统,可根据源码对其进行定制及编译。在某些应用场景下,可能需要完整的系统,此时,ubuntu和debian是不错的选择。可以通过其官网获取到arm版本的文件系统,然后通过定制来满足应用需求。

busybox移植

下载最新busybox

1
wget https://busybox.net/downloads/busybox-1.31.1.tar.bz2

配置编译器前缀

1
2
3
make menuconfig

Setting->cross compile prefix 配置为arm-linux-gnueabi-

编译和安装

1
make && make install

安装完成后在其顶层目录生成_install目录。将其拷贝为rootfs目录。

1
cp _install ../rootfs

创建其他目录

在rootfs中创建其它需要的目录

1
mkdir mkdir mnt tmp var  sys proc etc lib dev  sbin root home

创建console和null

1
2
mknod  -m 666 dev/console c 5 1
mknod -m 666 dev/null c 1 3

添加及修改配置文件

将busybox的examples/bootfloppy/etc中的所有文件拷贝到rootfs/etc中。

1
cp busybox-1.31.1/examples/bootfloppy/etc/* rootfs/etc -arf

修改rootfs/etc/fstab内容为:

1
2
3
proc          /proc           proc       defaults              0  0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0

修改rootfs/etc/profile内容为:

1
2
3
4
5
6
PS1='[\u@\h \W]\# '
HOSTNAME=`/bin/hostname`
export USER LOGNAME PS1
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH

修改rootfs/etc/inittab内容为:

1
2
3
4
5
6
7
::sysinit:/etc/init.d/rcS
#::respawn:-/bin/sh ###不需要登陆
::respawn:-/bin/login ###需要登陆
#console::askfirst:-/bin/sh
#tty2::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r

修改rootfs/etc/init.d/rcS内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/bin/mount -n -t ramfs ramfs /var

/bin/mkdir -p /var/tmp
/bin/mkdir -p /var/modules
/bin/mkdir -p /var/run
/bin/mkdir -p /var/log
/bin/mount -a
/bin/hostname -F /etc/hostname

/bin/mount -t devtmpfs none /dev
/bin/mkdir -p /dev/pts
/bin/mkdir -p /dev/shm
#/bin/mknod /dev/pts/0 c 136 0
/bin/mount -n -t devpts none /dev/pts -o mode=0622
#echo /sbin/mdev > /proc/sys/kernel/hotplug
#/sbin/mdev -s

/sbin/ifconfig lo 127.0.0.1 netmask 255.0.0.0
/sbin/ifconfig eth0 up

创建rootfs/etc/hostname文件

1
2
touch rootfs/etc/hostname
echo busybox > rootfs/etc/hostname

创建rootfs/passwd文件

1
2
3
4
5
touch rootfs/etc/passwd
echo root::0:0:root:/root:/bin/ash > rootfs/etc/passwd
echo bin:*:1:1:bin:/bin: >> rootfs/etc/passwd
echo daemon:*:2:2:daemon:/sbin: >> rootfs/etc/passwd
echo nobody:*:1:99:99:Nobody:/: >> rootfs/etc/passwd

添加动态库

将所使用的编译器自带的动态库拷贝到rootfs/lib目录中。

1
cp /usr/arm-linux-gnueabi/lib/* rootfs/lib/ -arf

如果在busybox配置中选择了Settings->build Options ->Build busybox as a static binary,那么此处不需要拷贝动态库文件,但是要添加自己的程序到新做的文件系统中,则需要静态编译或者同事添加动态库。

文件系统目标目录文件为rootfs

debian系统

环境准备

系统安装debootstrap以及qemu-user-static

1
apt -y install debootstrap qemu-user-static

制作根文件系统镜像(可选)

首先使用dd命令制作一个镜像,本实验制作debian stretch文件系统,大小500M足够。

1
dd if=/dev/zero of=./stretch.img bs=1M count=500

将制作的镜像格式化为ext4文件系统格式。

1
mkfs.ext4 -b 4096 stretch.img

挂载新制作的文件系统。

1
mount stretch.img /mnt

获取基础文件

首先进入/mnt目录中,并将系统qemu-arm-static文件拷贝到目标文件系统中:

1
2
cd /mnt
cp /usr/bin/qemu-arm-static /mnt/usr/bin/

获取stretch系统基础文件到/mnt目录中。

1
debootstrap --foreign --arch armhf stretch . http://ftp.cn.debian.org/debian

系统配置

首先进一步获取和设置系统需要的基础文件。

1
LC_ALL=C LANGUAGE=C LANG=C chroot . /debootstrap/debootstrap --second-stage

配置dpkg

1
LC_ALL=C LANGUAGE=C LANG=C chroot . dpkg --configure -a

挂载procfs

1
echo proc   /proc   proc    defaults >> etc/fstab

其他定制

通过上面的步骤后基本系统已经完成,现在可以通过chroot切换到新做的stretch系统中进行一些定制,比如修改root密码,增加用户,下载安装程序等。

切换到debian stretch系统命令:

1
chroot .

修改root用户密码,执行下面的命令后根据提示完成密码修改:

1
passwd

退出debian stretch命令:

1
exit

至此,完成一个基本的debian stretch系统,可以打包保存/mnt目录下的所有文件为rootfs,也可以卸载stretch.img,以镜像的形式保存。这里以保存镜像为例。

卸载:

如果挂载了procfs或者其他的fs,先卸载之,然后使用下面的命令卸载系统镜像。

1
umount /mnt

镜像检查:

1
e2fsck -p -f stretch.img

resize:

1
resize2fs -M stretch.img

针对不同的内核版本,支持的文件系统特征不同,可以通过下面的命令查看删除或者添加特征,下例以has_journal为例说明。

1
2
3
tune2fs -l stretch.img | grep 'Filesystem features'  /* 查看特征 */
tune2fs -O ^has_journal stretch.img /* 删除特征 */
tune2fs -O has_journal stretch.img /* 添加特征 */

ubuntu系统

制作根文件系统镜像(可选)

首先使用dd命令制作一个镜像,大小500M足够。(实际大小根据实际生产环境决定)

1
dd if=/dev/zero of=./ubuntu.img bs=1M count=500

将制作的镜像格式化为ext4文件系统格式。

1
mkfs.ext4 -b 4096 ubuntu.img

挂载新制作的文件系统。

1
mount ubuntu.img /mnt

获取文件系统目录树

1
wget http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04-core-armhf.tar.gz

定制跟文件系统

先将下载的ubuntu系统解压到挂载的Ubuntu镜像中:

1
tar -xvf ubuntu-base-16.04-core-armhf.tar.gz -C /mnt

安装虚拟机启动器

1
cp /usr/bin/qemu-arm-static /mnt/usr/bin/

配置域名服务器

1
echo nameserver 8.8.8.8 > /mnt/etc/resolv.conf

修改软件源

用vim或nano或其它编辑器打开/mnt/etc/apt/source.list,将如下两行前面的注释符号‘#’去掉。

1
2
# deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security universe
# deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security universe

修改主机名

主机名修改为“ubuntu”(自定义)

1
echo ubuntu > /mnt/etc/hostname

挂载所需文件系统

1
2
3
4
mount -t proc /proc /mnt/proc
mount -t sysfs /sys /mnt/sys
mount -o bind /dev /mnt/dev
mount -o bind /dev/pts /mnt/dev/pts

切换到新文件系统

1
LC_ALL=C LANGUAGE=C LANG=C chroot /mnt

添加串口服务

1
2
cp /lib/systemd/system/serial-getty@.service /lib/systemd/system/serial-getty@ttyS2.service
systemctl enable serial-getty@ttyS2.service

/lib/systemd/system/serial-getty@ttyS2.service文件里面的“%i.device”改为“%i”,此处如果目标板使用的串口是AMA的话,该文件应被命名为serial-getty@ttyAMA0.service,其它串口相同。

设置root用户密码

1
passwd root

其它定制

除了以上基本定制外,还可以做其它任何需要的定制,比如添加一个常用用户,安装一些常用软件,

完成系统定制

完成系统定制后首先退出该系统

1
exit

接着卸载文件系统

1
2
3
4
umount /mnt/proc
umount /mnt/sys
umount /mnt/dev/pts
umount /mnt/dev

如果是直接挂载制作好的镜像(第一步),继续卸载根文件系统

1
2
sync
umount /mnt

如果是挂载镜像操作,继续执行下面的操作以保证镜像的正确性。

镜像检查:

1
e2fsck -p -f ubuntu.img

resize:

1
resize2fs -M ubuntu.img

如果出现Unrecognised features问题,请参考debian系统制作中关于特征的说明。