Rootfs 定制化
概述
Rootfs(根文件系统)定制化是指根据产品需求对 Ubuntu 根文件系统进行个性化配置的过程。
运行原理
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 中修改变量。
HOSTNAME、 ROOT_PASSWD、 U_NAME、 U_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 中修改变量 TIMEZONE
与 LANGUAGE_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 分区启动系统。至此恢复完成。

