build_embed_linux_system

基于debian构建文件系统

基于Buildroot我们已经可以较为轻松的构建可用的文件系统,不过还是有些缺陷,如下所示。

  1. 系统需要增加新的软件和库时,仍然需要重新构建系统或者从源码编译移植
  2. Buildroot一定程度解决了包,编译器和系统之间的兼容性问题。不过对于不同版本(如Ubuntu18.04和Ubuntu22.04),不同类型(如Fedora系统)的系统,编译问题仍然存在,且难度随着包支持增多而显著增加
  3. Buildroot支持的包虽然很多,不过仍然很难覆盖全面,一些小众需求的移植仍然困难

熟悉使用桌面端Ubuntu,Centos系统的了解,除了基础的源码编译,最主要的软件安装方式其实和Windows平台类似,使用离线包(dpkg)和在线安装(apt,yum)这两种方式。对于嵌入式设备来说,理论上当然也支持,将编译构建完成的系统以压缩包的形式存储在服务器中,通过命令下载,解压,构建,提供二进制格式的软件离线和在线安装包支持。Debian系统正是基于这一理念设计的。不过因为支持功能增多,Debian也会占用更多资源,所以一般用于更高性能的SOC。本节目录如下所示。

debian_ver

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

build_sh

快速构建Debian系统的脚本如下所示。本例程中以清华源的镜像构建debian文件系统,执行构建脚本如下所示。

# 定义用到的参数
OPT_OS_VER=bookworm
CHIP_ARCH=armhf
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命令完成,主要包含以下几部分。

  1. 通过debootstrap从镜像源下载文件,构成debian集成文件
  2. 通过chroot配合qemu-x-static搭建虚拟环境,通过debootstrap文件构建完整系统
  3. 通过apt-get,dpkg等工具安装系统比较文件如vim,net-tools等

chroot_structure

可以直接使用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}"

image

install_soft

在chroot环境中,使用apt-get安装必要的软件。

# 安装必要的软件
apt-get install vim -y
apt-get install net-tools -y

至此,关于debian系统的构建实现完毕。可以看到,debian系统的构建基本上就是从服务器下载资源,解压打包后,通过apt-get安装软件,完成系统的构建。其中最重要的部分就是通过chroot进入沙箱模式,完成系统的配置。

issue_fix

issue_1

调用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

######################## 导入qemu-aarch64 ############################
# 此时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

# 导入配置
sudo update-binfmts --import /usr/share/binfmts/qemu-aarch64

# 检查是否启用成功
update-binfmts --display

如下所示即为成功。

image

next_chapter

返回目录

直接开始下一章节说明: 基于ubuntu构建文件系统