跳到主要内容

Rootfs 定制化

概述

Rootfs(根文件系统)定制化是指根据产品需求对 Ubuntu 根文件系统进行个性化配置的过程。


运行原理


Rootfs 编译流程

rootfs 定制化流程图


ext4 基础镜像

ubuntu-rootfs.ext4 是 Rootfs 定制化的基础,它包含:

  • Ubuntu 基础系统
  • 系统核心库和工具
  • 基础软件包

所有定制化修改都基于这个基础镜像进行。


编译产物路径

构建完成后主要文件路径如下:

  • 预构建的 ext4:
    • build/tmp/deploy/images/aimodule/ubuntu-rootfs.ext4
  • 完整的 rootfs 镜像:
    • build/tmp/deploy/images/aimodule/m1000-image-ubuntu-aimodule-xxx.rootfs.wic

boot-ubuntu.wks 控制分区结构(label、size、source 等)。


快速开始

准备工作

从 TOS 下载 ubuntu-image-xxx.ext4 或下载 m1000-image-ubuntu-aimodule-xxx.rootfs.wic 并解压为 ext4:

# 查看 wic 分区信息
fdisk -l m1000-image-ubuntu-aimodule-xxx.rootfs.wic

Disk m1000-image-ubuntu-aimmodule-20260308205733.rootfs.wic: 32 GiB, 34360804352 bytes, 67110946 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 0F763A1C-8B96-4004-8B93-3C3BFDCB3E51

Device Start End Sectors Size Type
m1000-image-ubuntu-aimodule-20260308205733.rootfs.wic1 2048 67110911 67108864 32G Linux filesystem

# 提取 ext4 分区(结合 sector size 和 Linux filesystem 的 Start 来取分区)
dd if=m1000-image-ubuntu-aimodule-xxx.rootfs.wic \
of=ubuntu-image.ext4 bs=$sector_size skip=$Start count=$Sectors

# 解包得到 Linux filesystem ubuntu-image.ext4
# 拷贝到 downloads 目录下
cp ubuntu-image.ext4 m1000-soc-sw-sdk/downloads/.

指定 ext4 为基础镜像

修改 m1000-soc-sw-sdk/meta/meta-mt-distro/recipes-images/rootfs/ubuntu-rootfs-ext4-prebuild.bb

  • UBUNTU_ROOTFS_EXT4_NAME = ubuntu-image-xxx.ext4
访问说明

如需获取本文中未提供直接下载链接、仅标注为从 TOS 获取的资源,请邮件联系 tao.tao@mthreads.com。我们会协助您完成 NDA 流程,并在签署后提供访问权限。


安装编译依赖以及 rootfs 编译

# 进入 SDK 目录
cd m1000-soc-sw-sdk

# 清理并安装 Kernel 相关依赖
bitbake linux-mthreads -c cleanall

# 脚本在 ${DEPLOYDIR}/debs/ 下编译出 deb 包
build-linux-deps.sh

# 一步构建 rootfs.wic
bitbake m1000-image-ubuntu

# 或分步构建
bitbake ubuntu-rootfs-ext4-prebuild
bitbake m1000-image-ubuntu

Rootfs 安装 deb 包

步骤 1:Kernel 包编译安装

bitbake linux-mthreads -c cleanall
build-linux-deps.sh

生成的 deb 包位于 ${DEPLOYDIR}/debs/ 下,在 sdk 编译 rootfs 时自动安装,包括:

  • Kernel image
  • 驱动 ko
  • libc 库文件
  • 头文件包

步骤 2:安装 MUSA、MUSA-SDK、all_debs

方法一:编译 rootfs 时自动安装

musa_*-AB100_arm64.deb 以及需要打入镜像的 deb 放入:

m1000-soc-sw-sdk/musa-debs/

方法二:手动安装

# 挂载 ext4
sudo mount -o loop ubuntu-rootfs.ext4 ./mnt
sudo mount --bind /sys ./mnt/sys
sudo mount --bind /dev ./mnt/dev
sudo mount --bind /dev/pts ./mnt/dev/pts
sudo mount --bind /proc ./mnt/proc
sudo cp /etc/resolv.conf ./mnt/etc/resolv.conf

# 进入 chroot 环境
sudo chroot ./mnt
sudo chmod 1777 /tmp

# 安装 deb 包
dpkg -i xxx.deb

# 退出
rm -f /etc/resolv.conf
exit
sudo umount ./mnt/sys
sudo umount ./mnt/dev/pts
sudo umount ./mnt/dev
sudo umount ./mnt/proc
sudo umount ./mnt

系统配置定制

步骤 1:修改用户名、密码、机器名

方法一:修改配置文件

/meta/meta-mt-distro/recipes-images/rootfs/ubuntu-rootfs-ext4-prebuild.bb 中修改变量。

HOSTNAMEROOT_PASSWDU_NAMEU_PASSWD

重新编译 rootfs,烧录启动开发板。

方法二:手动挂载修改

# 挂载 ext4
sudo mount -o loop ubuntu-rootfs.ext4 ./mnt

# 修改配置文件
# ...

# 卸载
sudo umount ./mnt

# 重新编译 rootfs
bitbake m1000-image-ubuntu -c cleanall
bitbake m1000-image-ubuntu

步骤 2:修改时区、语言与编码

/meta/meta-mt-distro/recipes-images/rootfs/ubuntu-rootfs-ext4-prebuild.bb 中修改变量 TIMEZONELANGUAGE_SELECTION

步骤 3:替换 APT 源

# 首先挂载 ext4 并 chroot
cat /etc/apt/sources.list

# 进行手动修改
# ...

分区定制

步骤 1:修改分区大小

/meta/meta-mt-apollo/wic/boot-ubuntu.wks 定义了 rootfs 分区的组织。

可以在 / 分区添加 size 选项控制分区大小,扩大 root 分区到 64G 如下:

part / --source rawcopy --sourceparams="file=ubuntu-rootfs.ext4" --fstype=ext4 --label root --align 1024 --size 64G --uuid=20e840e0-7803-4ca1-982c-9480b33f4094
提示

注意

  • 分区大小要大于等于 ext4 大小
  • 为了不过多占用服务器资源,在此处的大小调整不宜过大
  • 如果需要大幅度调大 root 分区,请参考下一节"系统运行时拓展分区"

步骤 2:系统运行时扩展分区

如果打开了 MTT E300_recovery 功能,那么会在开机时自动创建 recovery 分区,用以恢复出厂设置,同时对 root 分区进行自动扩容,无需手动修改。

不开启还原功能时,分区即为 ext4 大小,需要在 SDK 中以实际大小编译 rootfs,然后在系统启动时扩大 root 分区。

参考烧录指南,开发板启动后:

# 查看块设备
lsblk

# 使用 parted 进行管理
parted /dev/nvme0n1
(parted) print free
(parted) resizepart 2

# 手动定制分区的 end
End? [8759MB] 500G

# 如果是使用全部空间
End? [8759MB] 100%

(parted) quit

# 调整 rootfs 的大小
resize2fs /dev/nvme0n1p2

# 查看扩容结果
df -h
lsblk

步骤 3:添加裁剪组件

希望修改是永久的,在下次编译也生效,请挂载修改 downloads 下的 ext4

sudo mount -o loop old.ext4 ./mnt
sudo mount --bind /sys ./mnt/sys
sudo mount --bind /dev ./mnt/dev
sudo mount --bind /dev/pts ./mnt/dev/pts
sudo mount --bind /proc ./mnt/proc
sudo cp /etc/resolv.conf ./mnt/etc/resolv.conf

sudo chroot ./mnt
sudo chmod 1777 /tmp
# 在此环境下进行修改

rm -f /etc/resolv.conf
exit

sudo umount ./mnt/sys
sudo umount ./mnt/dev/pts
sudo umount ./mnt/dev
sudo umount ./mnt/proc
sudo umount ./mnt

mv modified.ext4 /downloads/.

# 修改 UBUNTU_ROOTFS_EXT4_NAME 为自定义的 ext4

跨架构支持

如果宿主机架构不同导致 chroot 失败,请按照如下步骤使用 qemu:

sudo apt update
sudo apt install qemu-user-static binfmt-support

# 安装后并未立即启用具体格式对应的解释器
sudo update-binfmts --display

# qemu-aarch64 对应的是 disabled
sudo update-binfmts --enable qemu-aarch64

# 复制 qemu 静态二进制到挂载目录
cp /usr/bin/qemu-aarch64-static /mount/usr/bin/

示例 1:删除添加浏览器

# 查看已安装的浏览器
dpkg -l | grep -E "firefox"

# 删除浏览器
apt-get purge firefox*

# 下载并安装新的浏览器
wget -O firefox-arm64.tar.xz "https://archive.mozilla.org/xxx"
tar -xJf firefox-arm64.tar.xz
ln -sf /opt/firefox/firefox /usr/bin/firefox

示例 2:删除桌面环境

# 查看桌面环境
dpkg -l | grep -E "ubuntu-desktop|gnome-desktop|xfce4"

# 删除桌面环境
apt-get purge ubuntu-desktop*
apt-get purge gnome-shell

示例 3:删除图形登陆界面

# 查看显示管理器
dpkg -l | grep -i gdm3

# 删除 gdm3
apt-get purge gdm3

示例 4:安装命令或工具

apt install -y vim net-tools curl wget htop unzip tar gdb strace lsof

系统服务配置

步骤 1:自动登录

/meta/meta-mt-distro/recipes-images/rootfs/ubuntu-rootfs-ext4-prebuild.bb 中修改

AUTO_LOGIN ?= "true"

步骤 2:system service 自动启动应用

步骤 1:创建执行程序的测试脚本

创建 /usr/local/bin/autorun.sh

#!/bin/bash

echo "$(date): Autorun service test completed." > /var/log/autorun-test.log
logger -t AUTORUN_TEST "Autorun service executed successfully! Time:$(date)"

touch /tmp/system-startup-complete.flag

echo "Test script execution completed, exiting."

步骤 2:创建 service 文件

cat > /etc/systemd/system/autorun.service << 'EOF'
[Unit]
Description=Auto Run Test Service
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/autorun.sh
RemainAfterExit=yes
User=root
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

步骤 3:启用服务,创建软连接

systemctl enable autorun.service

# 输出示例:
# Created symlink /etc/systemd/system/multi-user.target.wants/autorun.service -> /etc/systemd/system/autorun.service.

umount ext4 并且进行正常的编译和烧录

启动后查看 log 信息确认 service 自动启动成功:

# 验证是否执行成功,查看日志或者检查标志文件
journalctl -u autorun.service
ls -l /tmp/system-startup-complete.flag
cat /var/log/autorun-test.log

步骤 3:调整 service 开机启动顺序

systemd 中,启动顺序主要通过以下方式控制:

[Unit]
# 在当前服务之后启动的服务
Before=some-other.service

# 在当前服务之前启动的服务
After=network.target

# 强依赖关系 - 必须启动成功
Requires=network.target

# 弱依赖关系 - 希望启动,但不强制
Wants=network.target

# 冲突服务 - 不能同时运行
Conflicts=some-conflicting.service

常见的运行阶段控制

# 命令行系统启动阶段执行
[Install]
WantedBy=multi-user.target

# 在进入图形化桌面后执行
[Install]
WantedBy=graphical.target

调整 autorun.service 在网络可用、图形化界面启动前运行

调整顺序后的示例如下:

[Unit]
Description=Auto Run Test Service
After=network-online.target
Wants=network-online.target
Before=graphical.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/autorun.sh
RemainAfterExit=yes
User=root
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

恢复出厂设置

步骤 1:启用 Recovery 分区

提示

确保烧录的 firmware 是最新的,U-Boot 支持 recovery 分区恢复。U-Boot shell 中 bootcmd 支持 autoboot 功能。开启recovery功能时请确保设备有足够空间(推荐 >= 64G)。

编译出 rootfs.wic 并烧录,在第一次开机时会自动创建 recovery 分区并且对 root 分区进行扩容。耗时约 10s,图形化桌面有终端进度提示信息。

lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
mmcblk0 179:0 0 58.3G 0 disk
├─mmcblk0p1 179:1 0 38.2G 0 part
└─mmcblk0p2 179:2 0 20G 0 part
mmcblk0boot0 179:32 0 4M 1 disk
mmcblk0boot1 179:64 0 4M 1 disk
nvme0n1 259:0 0 953.9G 0 disk
├─nvme0n1p1 259:1 0 933.9G 0 part /
└─nvme0n1p2 259:2 0 20G 0 part

步骤 2:执行恢复出厂设置

需要恢复出厂设置时,执行:

sudo m1000-recovery

脚本会自动在 recovery 分区下创建标识,自动重启,U-Boot 检测到标识就从 recovery 分区启动,并且自动执行恢复脚本,从 squashfs 恢复 root 分区,恢复完成后自动重启,从 root 分区启动系统。至此恢复完成。