基于Buildroot我们已经可以较为轻松的构建可用的文件系统,不过在实际使用中还是不可避免的有所缺陷。
对于桌面端Ubuntu、Centos系统来说,除了第三方源码编译外,最主要的软件安装方式其实和Windows平台类似。使用离线包(dpkg)或在线安装(apt,yum)这两种方式。对于嵌入式设备来说,其原理上差异不大,理论上当然也支持;将编译构建完成的系统以软件包的形式存储在服务器中,通过命令下载、解压、构建、提供二进制格式的软件离线和在线安装包支持;Debian系统正是基于这一理念设计的。不过因为支持功能增多,Debian也会占用更多资源,所以一般用于更高性能的SOC。
本节目录如下所示。
debian系统的版本说明如下所示。
本例在桌面端Ubuntu22.04系统中使用bookworm版本的Debian进行构建,其它版本需要自己验证修改。
注意: Ubuntu也是基于debian进行深度定制的系统,每个版本都基于debian系统生成。理论上每个版本的Ubuntu都可以构建所有的Debian系统。不过考虑到实际兼容性,以及支持环境的不同,桌面端Ubuntu版本和需要构建的debian的版本最好保持版本一致,这样可以避免很多兼容性问题。这里以debian-bookworm为例,桌面端版本选择Ubuntu 22.04 LTS,也是本系列文章选择的系统。
Ubuntu版本 | Ubuntu代号 | Debian代号 | Debian版本 |
---|---|---|---|
24.04 LTS | Noble | trixie/sid | 13 |
23.10 | Mantic | trixie/sid | 13 |
23.04 | Lunar | bookworm/sid | 12 |
22.04 LTS | jammy | bookworm/sid | 12 |
21.10 | Impish | bullseye/sid | 11 |
20.04 LTS | Focal | bullseye/sid | 11 |
19.10 | Eoan | buster/sid | 10 |
18.04 LTS | Bionic | buster/sid | 10 |
17.10 | Artful | stretch/sid | 9 |
16.04 LTS | xenial | stretch/sid | 9 |
15.10 | Wily | jessie/sid | 8 |
14.04 LTS | Trusty | jessie/sid | 8 |
构建Debian系统的流程包含如下流程。
注: 作为通用平台系统,Debian在基本构建上适配大部分板级硬件,一般来说只分32/64位系统,以及输出串口的区别。
配置中主要修改项。
CHIP_ARCH配置 | 对应的平台说明 |
---|---|
amd64 | 64位x86版本系统 |
i386 | 32位x86版本系统 |
arm64 | 64位arm版本系统 |
armhf | 32位arm硬浮点版本系统 |
armel | 32位arm软浮点版本系统 |
本例程中以清华源的镜像构建debian文件系统,快速构建Debian系统的脚本如下所示。
# 定义构建时用到的参数
OPT_OS_VER=bookworm
CHIP_ARCH=armhf
qemu_arch=arm
NFS_PATH="/home/freedom/Desktop/user_git/sdk/nfs"
run_as_client() {
$@ > /dev/null 2>&1
}
# 挂载系统目录到用户目录()
mount_chroot()
{
sudo mount -t proc chproc "${NFS_PATH}"/proc
sudo mount -t sysfs chsys "${NFS_PATH}"/sys
sudo mount -t devtmpfs chdev "${NFS_PATH}"/dev || sudo mount --bind /dev "${NFS_PATH}"/dev
sudo mount -t devpts chpts "${NFS_PATH}"/dev/pts
}
# 移除系统目录
umount_chroot()
{
while grep -Eq "${NFS_PATH}.*(dev|proc|sys)" /proc/mounts
do
sudo umount -l --recursive "${NFS_PATH}"/dev >/dev/null 2>&1
sudo umount -l "${NFS_PATH}"/proc >/dev/null 2>&1
sudo umount -l "${NFS_PATH}"/sys >/dev/null 2>&1
sleep 5
done
}
# 1. 实现构建系统的必要环境
sudo apt-get install debootstrap debian-archive-keyring qemu-user-static -y
# 2. 使用debootstap完成从镜像源下载文件
if [ ! -d ${NFS_PATH}/bin/ ]; then
sudo debootstrap --foreign --verbose --arch=${CHIP_ARCH} ${OPT_OS_VER} ${NFS_PATH} http://mirrors.tuna.tsinghua.edu.cn/debian/
fi
# 安装qemu-*-static
sudo chmod -Rv 777 ${NFS_PATH}/usr/
cp /usr/bin/qemu-${qemu_arch}-static ${NFS_PATH}/usr/bin/
chmod +x ${NFS_PATH}/usr/bin/qemu-${qemu_arch}-static
# 基于debootstrap完成后续安装
cd ${NFS_PATH}
mount_chroot
# 3. 进行debootstrap第二部分的安装
LC_ALL=C LANGUAGE=C LANG=C sudo chroot ${NFS_PATH} /debootstrap/debootstrap --second-stage --verbose
# 安装必要的软件
LC_ALL=C LANGUAGE=C LANG=C sudo chroot ${NFS_PATH} apt-get install vim libatomic1 -y
umount_chroot
通过上述步骤就可以构建完成基于debian的系统。debian系统的安装主要有debootstrap命令完成,主要包含以下几部分。
脚本都是基于上述步骤完成。其中debootstrap理解比较简单,可以理解为下载安装工具;其功能就是从镜像源下载压缩包,解压并安装文件到指定目录。比较复杂的反而是chroot工具,它是Linux和类Unix系统中的一个命令,用于改变当前进程及其子进程的根目录;相当于在系统中单独创建一个隔离的执行环境,执行新系统应用。不过chroot最强大的部分还不止于此,其另一个用途是可以配合qemu工具,在x86环境下模拟一个嵌入式平台的运行环境,执行嵌入式平台的应用。正是依赖这一点,才能够完成debootstrap的第二部分安装以及必要的软件安装。
理解了这两个程序的用法,整个步骤就比较清晰可见了;构建debian系统也就没有秘密和难度可以,后续Ubuntu构建反而更近一步简化操作,相对来说更加简单。顺理成章就来到了第二节,使用chroot沙箱模式进行系统的定制化。
本节主要使用chroot进入沙箱模式配置debian系统,实现用户定制的专属系统;其主要步骤如下所示。
# 进入构建目录
cd "${NFS_PATH}"/
# 进入nfs系统
workdir=$(pwd)
sudo mount -t proc chproc "${workdir}"/proc
sudo mount -t sysfs chsys "${workdir}"/sys
sudo mount -t devtmpfs chdev "${workdir}"/dev || sudo mount --bind /dev "${workdir}"/dev
sudo mount -t devpts chpts "${workdir}"/dev/pts
LC_ALL=C LANGUAGE=C LANG=C sudo chroot "${workdir}"
在chroot环境中,使用apt-get安装必要的软件。
# 安装必要的软件
apt-get install vim net-tools dialog apt-utils -y
添加用户,增加用户管理。
# 增加用户
adduser freedom
# 添加密码
# 对于用户增加sudo使用权限
visudo
# +
freedom ALL=(ALL:ALL) ALL
增加串口打印服务,用于串口打印和系统命令输入。
# Debian默认只支持tty1输出,也就是屏幕,如果希望串口输出,增加相应服务
# 复制串口ttymxc0启动服务,所有步骤完成
cd /etc/systemd/system/getty.target.wants
# [ TIME ] Timed out waiting for device dev-ttymxc0.device.
# 对于其它SOC芯片,需要将ttymxc0更新为相应的串口(例如ttyS1)
cp -d getty@tty1.service getty@ttymxc0.service
对于构建号的系统,后续打包成tar.gz或者img格式,就可以用于下载和运行。可以看到,debian系统的主要流程如下所示。
至此,关于debian系统的初步构建实现完毕。
对于构建过程中的问题,整理了如下项,可根据实际情况确认解决。
调用chroot时,显示/bin/bash: exec format error。
原因: chroot进入沙箱模式时,相当于在x86跨平台执行arm端的应用,需要arm虚拟机环境的支持。
解决办法:
# 确定是否安装qemu-user-static
sudo apt-get install qemu-user-static update-binfmts -y
# 如果确定安装,判断系统中是否支持开启binformat的支持
# 这个机制原理时内核通过检测文件的起始字节来确定调用的程序,如果未开启,使用命令开启
update-binfmts --display
# 如果发现qemu-arm未开启,使用如下命令开启,然后检测是否开启
update-binfmts --enable qemu-arm
update-binfmts --display
# 如果发现没有qemu-arm选项,此时还有最后的办法,自己导入支持
# 除非理解为什么这么做,而且知道表示含义,否则不要执行这一步,这一步会改变系统配置,如果写入
# 值有错,可能会导致数据损坏,大部分命令都无法启动
######################## 导入qemu-arm ############################
touch /usr/share/binfmts/qemu-arm
# 向文件中写入配置内容
cat << EOF | sudo tee /usr/share/binfmts/qemu-arm
package qemu-user-static
interpreter /usr/libexec/qemu-binfmt/arm-binfmt-P
magic \x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00
offset 0
mask \xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff
credentials yes
fix_binary yes
preserve yes
EOF
# 导入对armhf虚拟环境的支持
sudo update-binfmts --import /usr/share/binfmts/qemu-arm
######################## 导入qemu-aarch64 ############################
# 创建配置文件
sudo touch /usr/share/binfmts/qemu-aarch64
# 向文件中写入配置内容
sudo cat << EOF | sudo tee /usr/share/binfmts/qemu-aarch64
package qemu-user-static
interpreter /usr/libexec/qemu-binfmt/aarch64-binfmt-P
magic \x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00
offset 0
mask \xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff
credentials yes
fix_binary yes
preserve yes
EOF
# 导入对aarch64虚拟环境的支持
sudo update-binfmts --import /usr/share/binfmts/qemu-aarch64
# 检查是否启用成功
update-binfmts --display
如下所示即为成功。
直接开始下一章节说明: 基于ubuntu构建文件系统