- smb/resources/embedded/rootfs-build-methods/debootstrap/README.md
- smb/resources/embedded/rootfs-build-methods/yocto/README.md
Debootstrap 与 Yocto 实操教程
第一部分:Debootstrap
Debootstrap 是 Debian 官方提供的工具,用于构建 Debian/Ubuntu 根文件系统。相比 Buildroot 和 Yocto,Debootstrap 更简单直接,适合需要 Debian 生态的应用场景。
核心特点
- 基于 APT 包管理:直接使用 Debian 官方仓库的二进制包
- 简单易用:一个命令即可生成完整 rootfs
- 跨架构支持:通过 QEMU 实现 ARM64 rootfs 交叉构建
- Debian 兼容:适合需要完整 Debian 生态的应用
使用场景
- Docker 镜像基础
- Debian/Ubuntu 目标系统
- 交叉编译开发环境
- 需要完整包生态的嵌入式系统
环境准备
docker run -it --name debootstrap-build \
-v $(pwd)/workspace:/workspace \
debian:bullseye bash
安装必要工具:
apt-get update && apt-get install -y \
debootstrap \
qemu-user-static \
binfmt-support \
wget \
curl \
sudo \
locales
# 设置 locale
sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen
locale-gen
export LANG=en_US.UTF-8
基本用法
支持的架构:amd64 (x86_64)、arm64 (AArch64)、armel/armhf (ARM)、i386、ppc64el、riscv64
Debian 版本代号:stable (当前: Bookworm 12)、testing (Trixie)、unstable (Sid),或直接使用代号 bookworm, trixie, sid
构建 Debian Bookworm ARM64 RootFS:
mkdir -p /workspace/debian-rootfs
cd /workspace
# 最小安装
debootstrap --arch arm64 bookworm ./debian-rootfs http://deb.debian.org/debian
# 或包含推荐包
debootstrap --arch arm64 --include=locales,curl,wget,git,openssh-server \
bookworm ./debian-rootfs http://deb.debian.org/debian
构建 Ubuntu RootFS:
mkdir -p /workspace/ubuntu-rootfs
cd /workspace
# Ubuntu 22.04 ARM64
debootstrap --arch arm64 jammy ./ubuntu-rootfs http://archive.ubuntu.com/ubuntu/
# Ubuntu 24.04 ARM64
debootstrap --arch arm64 noble ./ubuntu-rootfs http://archive.ubuntu.com/ubuntu/
跨架构构建(重要)
在 x86 机器上构建 ARM64 rootfs,需要 QEMU 模拟。
# 复制 QEMU 静态二进制到 rootfs
cp /usr/bin/qemu-aarch64-static ./debian-rootfs/usr/bin/
# 启用 binfmt_misc(容器内通常已启用)
mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
配置 APT 源(可选优化):
# 进入 chroot 环境
LANG=C.UTF-8 chroot ./debian-rootfs /bin/bash
# 配置 APT
cat > /etc/apt/sources.list << 'EOF'
deb http://deb.debian.org/debian bookworm main contrib non-free
deb http://deb.debian.org/debian bookworm-updates main contrib non-free
deb http://deb.debian.org/debian-security bookworm-security main
EOF
# 更新包列表
apt-get update
# 安装必要组件
apt-get install -y \
locales \
sudo \
dbus \
udev \
systemd \
network-manager
# 设置 locale
sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen
locale-gen
echo 'LANG=en_US.UTF-8' > /etc/default/locale
# 退出 chroot
exit
RootFS 基础配置
# 1. 设置主机名
echo "my-device" > ./debian-rootfs/etc/hostname
# 2. 配置网络
cat > ./debian-rootfs/etc/resolv.conf << 'EOF'
nameserver 8.8.8.8
nameserver 8.8.4.4
EOF
# 3. 设置 root 密码
chroot ./debian-rootfs /bin/bash -c "echo 'root:password' | chpasswd"
# 或清空密码(不安全,仅测试用)
chroot ./debian-rootfs /bin/bash -c "passwd -d root"
# 4. 添加用户
chroot ./debian-rootfs /bin/bash -c "useradd -m -s /bin/bash user"
chroot ./debian-rootfs /bin/bash -c "echo 'user:password' | chpasswd"
chroot ./debian-rootfs /bin/bash -c "echo 'user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers"
# 5. 配置 SSH(可选)
chroot ./debian-rootfs /bin/bash -c "apt-get install -y openssh-server"
# 允许 root 登录(仅测试)
sed -i 's/#PermitRootLogin.*/PermitRootLogin yes/' ./debian-rootfs/etc/ssh/sshd_config
打包 RootFS
# 1. 创建 tarball
cd ./debian-rootfs
tar --numeric-owner -cvpzf ../debian-bookworm-arm64.tar.gz .
ls -lh ../debian-bookworm-arm64.tar.gz
# 2. 创建镜像文件
dd if=/dev/zero of=debian.img bs=1M count=2048 status=progress
mkfs.ext4 -F debian.img
mkdir -p /mnt/rootfs
mount -o loop debian.img /mnt/rootfs
tar -xzf debian-bookworm-arm64.tar.gz -C /mnt/rootfs
umount /mnt/rootfs
# 3. 使用 guestfish 自动化
apt-get install libguestfs-tools
guestfish --ro \
--add debian.img \
--mount /dev/sda1:/ \
--download /etc/apt/sources.list /tmp/sources.list
guestfish \
--add debian.img \
--mount /dev/sda1:/ \
--tar-in debian-bookworm-arm64.tar.gz /
测试 RootFS
使用 QEMU 启动:
# 需要内核镜像(从 debootstrap 外部获取)
wget https://boot.netboot.xyz/ipxe/nokernel/linux-aarch64 -O linux-aarch64
# 启动(需要目标板内核,这里用通用内核演示概念)
qemu-system-aarch64 \
-M virt \
-cpu cortex-a53 \
-m 512M \
-kernel vmlinuz \
-initrd initrd.img \
-append "root=/dev/vda console=ttyAMA0" \
-drive file=debian.img,if=vda,format=raw \
-nographic
使用 systemd-nspawn:
apt-get install systemd-container
# 进入 rootfs
systemd-nspawn -D ./debian-rootfs -M my-container
# 或后台运行
systemd-nspawn -bD ./debian-rootfs
使用 chroot:
# 挂载虚拟文件系统
mount -t proc proc ./debian-rootfs/proc
mount -t sysfs sys ./debian-rootfs/sys
mount --bind /dev ./debian-rootfs/dev
# 进入
chroot ./debian-rootfs /bin/bash
# ... 操作完成后
exit
umount ./debian-rootfs/dev
umount ./debian-rootfs/sys
umount ./debian-rootfs/proc
进阶配置
添加 ROS(如果需要):
chroot ./debian-rootfs /bin/bash
apt-get install -y curl
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | apt-key add -
sh -c 'echo "deb http://packages.ros.org/ros/ubuntu bookworm main" > /etc/apt/sources.list.d/ros.list'
apt-get update
apt-get install -y ros-noetic-ros-base
exit
添加 Docker 支持:
chroot ./debian-rootfs /bin/bash
curl -fsSL https://get.docker.com | sh
# 或手动安装
apt-get install -y docker.io containerd
systemctl enable docker
exit
自定义 systemd 服务:
cat > ./debian-rootfs/etc/systemd/system/hello.service << 'EOF'
[Unit]
Description=Hello Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/hello.sh
Restart=always
[Install]
WantedBy=multi-user.target
EOF
cat > ./debian-rootfs/usr/bin/hello.sh << 'EOF'
#!/bin/bash
echo "Hello from rootfs!" | logger
while true; do
sleep 60
done
EOF
chmod +x ./debian-rootfs/usr/bin/hello.sh
chroot ./debian-rootfs /bin/bash -c "systemctl enable hello"
Multistrap(高级用法)
当需要更精细控制时,使用 multistrap:
apt-get install multistrap
cat > multistrap.conf << 'EOF'
[General]
cleanup=true
noauth=true
unpack=true
debootstrap=minimal
[Minimal]
packages=locales,openssh-server,iputils-ping,curl,wget
source=http://deb.debian.org/debian
suite=bookworm
architectures=arm64
[Development]
packages=gcc,make,git,python3,cmake
source=http://deb.debian.org/debian
suite=bookworm
architectures=arm64
EOF
multistrap -f multistrap.conf -d ./rootfs
常见问题
Q: debootstrap 失败 “Releases file missing”
# 使用正确的 sources.list
debootstrap --foreign --no-check-gpg ...
# 或使用快照源
debootstrap bookworm ./rootfs http://snapshot.debian.org/archive/debian/20240101/
Q: 容器内无法运行 QEMU
# 检查 binfmt_misc
cat /proc/sys/fs/binfmt_misc/status
# 手动注册
echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x00\xb7:/usr/bin/qemu-aarch64-static:OC' > /proc/sys/fs/binfmt_misc/register
Q: 如何减小 rootfs 体积
# 清理 apt 缓存
chroot ./debian-rootfs /bin/bash -c "apt-get clean && rm -rf /var/lib/apt/lists/*"
# 清理日志
rm -rf ./debian-rootfs/var/log/*.log
# 清理临时文件
rm -rf ./debian-rootfs/tmp/*
# 重新打包
tar --numeric-owner -cvzf small-rootfs.tar.gz -C ./debian-rootfs .
参考链接:
- Debootstrap 官方文档:https://wiki.debian.org/Debootstrap
- Debian 架构支持:https://www.debian.org/ports/
- QEMU 官方文档:https://www.qemu.org/documentation/
- Multistrap 文档:https://wiki.debian.org/Multistrap
第二部分:Yocto/OpenEmbedded
Yocto Project 是 Linux 基金会旗下的开源项目,提供了完整的嵌入式 Linux 构建框架。OpenEmbedded 是其核心构建引擎,Poky 是参考发行版。
架构
Yocto 架构
┌─────────────────────────────────────────────────────────────┐
│ BitBake │
│ (任务调度器) │
├─────────────────────────────────────────────────────────────┤
│ Meta-Layers (层层叠加的配置) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ meta-poky│ │ meta-oe │ │ meta-yocto-bsp │ │ meta-custom │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────────────────────────┤
│ OpenEmbedded Core │
│ (基础构建系统) │
└─────────────────────────────────────────────────────────────┘
关键术语
| 术语 | 说明 |
|---|---|
| Layer | 功能模块集合,一个 layer 就是一个目录 |
| Recipe (.bb) | 软件包构建配方,描述如何获取、编译、打包 |
| Recipe append (.bbappend) | 追加修改已有 recipe |
| BitBake | 任务调度器,类似 make 但更强大 |
| conf | 配置文件目录 |
| BSP | Board Support Package,板级支持包 |
| SDK | Software Development Kit,交叉编译工具链 |
环境准备
docker run -it --name yocto-build \
-v $(pwd)/workspace:/yocto-build \
debian:bullseye bash
安装依赖:
apt-get update && apt-get install -y \
build-essential \
git \
wget \
curl \
cpio \
unzip \
rsync \
bc \
python3 \
python3-dev \
libncurses-dev \
libncurses5-dev \
libssl-dev \
zlib1g-dev \
bison \
flex \
patch \
diffutils \
file \
gawk \
locales \
chrpath \
sudo \
which
# 设置 locale
sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen
locale-gen
export LANG=en_US.UTF-8
获取 Poky(Yocto 官方参考发行版)
# 方法一:Git 克隆(推荐)
cd /yocto-build
git clone -b scarthgap --depth 1 https://git.yoctoproject.org/poky
cd poky
# 方法二:下载 tarball
cd /yocto-build
wget http://downloads.yoctoproject.org/releases/yocto/yocto-5.0/poky-scarthgap-5.0.tar.bz2
tar xjf poky-scarthgap-5.0.tar.bz2
cd poky-scarthgap-5.0
构建流程
# 1. 初始化构建环境(必须使用 poky 中的脚本),会创建 build/ 目录并切入
source oe-init-build-env
查看可用机器:ls conf/machine/
常用机器:qemuarm64、qemux86-64、raspberrypi3-64、imx8mmevk
配置 conf/local.conf:
# 设置目标架构
MACHINE ??= "qemuarm64"
# 设置并行编译
PARALLEL_MAKE = "-j 8"
BB_NUMBER_THREADS = "8"
# 设置下载目录(加速重复构建)
DL_DIR ?= "/yocto-build/downloads"
# 设置构建产物输出目录
SSTATE_DIR ?= "/yocto-build/sstate-cache"
# 禁用不需要的组件加速构建
EXTRA_IMAGE_FEATURES = ""
构建镜像:
# 构建最小系统
bitbake core-image-minimal
# 构建带调试工具的镜像
bitbake core-image-minimal-dev
# 构建完整系统
bitbake core-image-full-cmdline
# 构建带 Qt5 的镜像(需要添加 meta-qt5 层)
bitbake core-image-qt
首次构建耗时 1-3 小时(网络和机器性能决定)。
关键配置文件
conf/local.conf:
# 机器选择
MACHINE ??= "qemuarm64"
# 打包格式
IMAGE_FSTYPES = "ext4 wic"
# 目标地域
IMAGE_LINGUAS = "en-us"
# 额外包
CORE_IMAGE_EXTRA_INSTALL = "packagegroup-core-ssh-openssh"
conf/bblayers.conf:
# 添加额外的 meta 层
BBLAYERS += " \
/path/to/meta-qt5 \
/path/to/meta-ros \
"
层管理
# 查看已有层
bitbake-layers show-layers
# 添加官方扩展层
git clone -b scarthgap https://github.com/ros/meta-ros.git
git clone -b scarthgap https://github.com/meta-qt5/meta-qt5.git
bitbake-layers add-layer /path/to/meta-ros
bitbake-layers add-layer /path/to/meta-qt5
# 创建自定义层
bitbake-layers create-layer meta-custom
# 结构:
# meta-custom/
# ├── conf/layer.conf
# ├── recipes-example/
# └── classes/
构建产物
ls tmp/deploy/images/qemuarm64/
产物包括:
core-image-minimal-qemuarm64.ext4- 根文件系统镜像core-image-minimal-qemuarm64.wic- 完整磁盘镜像(含 bootloader)zImage- 内核镜像u-boot.imx或u-boot.elf- bootloadercore-image-minimal-qemuarm64.manifest- 包列表
QEMU 运行
# 方式一:使用 runqemu
runqemu qemuarm64 nographic
# 方式二:指定镜像
runqemu qemuarm64 tmp/deploy/images/qemuarm64/core-image-minimal-qemuarm64.ext4
# 带启动参数
runqemu qemuarm64 nographic bootparams="root=/dev/vda console=ttyAMA0,115200"
# 带端口映射(SSH 到 localhost:2222)
runqemu qemuarm64 user-net
进阶:创建自定义 Recipe
创建 meta-custom/recipes-hello/hello/hello_1.0.bb:
SUMMARY = "Hello World Application"
DESCRIPTION = "A simple hello world application"
HOMEPAGE = "https://example.com"
AUTHOR = "Your Name <[email protected]>"
SECTION = "apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://hello.c \
file://Makefile"
S = "${WORKDIR}"
do_compile() {
oe_runmake
}
do_install() {
install -d ${D}${bindir}
install -m 0755 hello ${D}${bindir}
}
创建源码目录并编译:
mkdir -p meta-custom/recipes-hello/hello/files
# 放入 hello.c 和 Makefile
bitbake hello
常见问题
Q: 构建太慢怎么办
# 使用本地 sstate 缓存
SSTATE_DIR = "/yocto-build/sstate-cache"
# 使用可信上游
BB_NO_NETWORK = "0"
# 清理重建
bitbake core-image-minimal -c cleansstate
bitbake core-image-minimal
Q: 如何添加包到镜像
# 方法一:在 local.conf 中全局添加
IMAGE_INSTALL_append = " vim git"
# 方法二:创建 custom-image.bb
bitbake custom-image
Q: 如何修改已有包
使用 .bbappend:
# meta-custom/recipes-core/busybox/busybox_%.bbappend
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
SRC_URI += "file://defconfig"
Yocto vs Buildroot 选择
| 维度 | Yocto/OpenEmbedded | Buildroot |
|---|---|---|
| 学习曲线 | 陡峭 | 平缓 |
| 构建速度 | 慢(首次) | 快 |
| 定制粒度 | 源码级别 | 包级别 |
| 生态 | 大厂都在用 | 社区驱动 |
| 适用场景 | 商业产品、车规、工规 | 快速原型、小批量 |
参考链接:
- Yocto 官网:https://www.yoctoproject.org/
- 官方文档:https://docs.yoctoproject.org/
- OpenEmbedded 官网:https://www.openembedded.org/
- Layer Index:https://layers.openembedded.org/