调整 Linux 布局
备注
本章的内容适用于 NAND flash。
如何缩减固件的大小
在某些情况下,用户可能需要减小固件大小。以下是关于如何缩小固件大小的说明。
如何缩减 ROOTFS 固件的大小
可以删除这些目录中不需要的插件。
<sdk>/sources/yocto/meta-realtek/meta-sdk/recipes-core/images/ameba-image-core.bb
<sdk>/sources/yocto/meta-realtek/meta-realtek-bsp/recipes-core/packagegroups/packagegroup-rtk-commands.bb
<sdk>/sources/yocto/meta-realtek/meta-realtek-bsp/recipes-core/packagegroups/packagegroup-rtk-network.bb
再次编译,生成一个新的 rootfs.img,你会发现它的大小比之前更小。
如何缩减 KERNEL 固件的大小
制定新的布局
在章节 如何缩减 ROOTFS 固件的大小 和 如何缩减 KERNEL 固件的大小 的步骤之后,分区大小的示例如下。其中,遵循的 OEM 是预期的一个额外分区(下同)。

备注
恢复内核是 initramfs,具有固定大小,固件大小为 4.484M,因此内核分区至少为 5M。
NAND 闪存分区的基本单位是块(其大小为 128KB),因此布局的划分应为块的整数倍。
不建议减少 km4_boot_all.bin、km0_km4_app.bin、boot.img 和 vbmeta.img 的大小,因为它们本身就较小,只占用很少的块,减少它们的成本相对较高。
vbmeta.img 和 dtb.img 的总大小小于一个块。然而,如果只为它们分配一个块,由于 NAND 中可能存在坏块,如果为它们分配的块是坏的,那这些固件就无法再被写入。因此,为了系统的鲁棒性,建议为它们至少分配两个块。
DTS 中每个布局的偏移量和大小
例如,对于 generic 128M 机器,DTS 中每个布局的偏移量和大小如下所示。

其中,A 表示 dtb 和内核的 A 部分,B 表示 dtb 和内核的 B 部分。十六进制值是基于 FLASH 基地址的偏移量。
ImageTool 中每个布局的偏移量和大小
例如,对于 generic 128M 机器,ImageTool 中每个布局的偏移量和大小如下所示。其中所有十六进制值均通过 DTS 中每个布局的偏移量和大小 章节中的偏移量计算得出。

备注
必须确保最后的结束地址等于 0x10000000。
如何调整 DTS 中布局的大小
对于内核 5.4.x,DTS 文件的目录是 <sdk>/sources/kernel/linux-5.4/arch/arm/boot/dts
,对于内核 6.6.x,目录是 <sdk>/kernel/linux-6.6/arch/arm/boot/dts/realtek/ameba
。
用户可以根据 DTS 中每个布局的偏移量和大小 章节中的偏移量和大小,配置分区 reg 的值。
下图显示了调整 DTS 中布局前后的对比示例。


如何调整 Uboot defconfig
defconfig 文件的路径是:
<sdk>/sources/boot/uboot/configs
CONFIG_MTDPARTS_DEFAULT
修改前
CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:0x20000@0x20000(cert-bin),0x40000@0x620000(misc),0x40000@0x6A0000(vbmeta),0x40000@0x6E0000(r-vbmeta),0x60000@0x780000(r-dtb),0xA00000@0x11E0000(r-uImage),0x60000@0x720000(dtb),0xA00000@0x7E0000(uImage)"
修改后
根据 DTS 中每个布局的偏移量和大小 章节中的偏移量和大小, CONFIG_MTDPARTS_DEFAULT 应该为:
CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:0x20000@0x20000(cert-bin),0x40000@0x620000(misc),0x40000@0x6A0000(vbmeta),0x40000@0x6E0000(r-vbmeta),0x40000@0x760000(r-dtb),0x500000@0XCA0000(r-uImage),0x40000@0x720000(dtb),0x500000@0x7A0000(uImage)"
IMAGE 加载到 DDR 配置
NAND 允许有 2% 的坏块,因此此处加载固件的大小应略小于 DTS 中每个布局的偏移量和大小 章节中计算的大小。
- IMG_FLASH_SIZE:
从闪存传输到 DDR 的内核固件的大小。
- FDT_FLASH_SIZE:
从闪存传输到 DDR 的 dtb 固件的大小。分配给 dtb 固件的空间已经是最大值(64KB),因此 FDT_FLASH_SIZE 将不再调整。
- RECOVERY_IMG_FLASH_SIZE:
从闪存传输到 DDR 的恢复内核固件的大小。
- RECOVERY_FDT_FLASH_SIZE:
从闪存传输到 DDR 的恢复 dtb 固件的大小。
- SYS_TEXT_BASE:
固件从闪存传输到 DDR 后的 DDR 起始地址(不调整)。
- KERNEL_ADDR:
传输到 DDR 的内核固件的起始地址(不调整)。
- FDT_ADDR:
传输到 DDR 的 dtb 固件的起始地址。分配给 dtb 固件的空间已经是最大值(64KB),因此 FDT_ADDR 将不再调整。
修改前后的对比如下所示。


内核和 dtb 在 DDR 中的位置本来就很小,因此不需要额外修改。恢复 initramfs 的大小需要为 0x500000 保留一个坏块,因此调整为 0x4E0000。
编译时如何调整 UBI 的大小
userdata ubi -c
其位于 <sdk>/source/yocto/meta-sdk/recipes-core/images/ameba-image-userdata.bb
。
在修改前,内容如下:
MKUBIFS_ARGS = "-m 2048 -e 126976 -c 297 --jrn-size=380928"
然后你将其大小调整为 56.75M,首先向下取整为 56M,然后按照以下公式计算:
MKUBIFS_ARGS = "-m 2048 -e 126976 -c 404 --jrn-size=380928"
rootfs ubi -c
其位于 <sdk>/source/yocto/meta-realtek-bsp/conf/machine/rtl8730elh-va7.conf
。
在修改前,内容如下:
MKUBIFS_ARGS = "-F -m 2048 -e 126976 -c 436 -j 380928"
然后你将其大小调整为 20.19M,首先向下取整为 20M,然后按照以下公式计算:
MKUBIFS_ARGS = "-F -m 2048 -e 126976 -c 116 -j 380928"
如何调整 ImageTool 的布局
修改之前,默认的起始地址和结束地址在 ImageTool 中显示如下。

你可以根据 ImageTool 中每个布局的偏移量和大小 章节调整起始地址或结束地址。
修改后,新的起始地址与结束地址可能如下所示。

添加 OEM 分区
新文件 ameba-image-oem.bb
用户可以在路径 <sdk>/sources/yocto/meta-realtek/meta-sdk/recipes-core/images
中添加新文件 ameba-image-oem.bb,其内容如下:
# Copyright 2023 Realtek.
# Released under the MIT license (see COPYING.MIT for the terms)
SUMMARY = "This is the oem image."
IMAGE_FSTYPES = "ubi"
MKUBIFS_ARGS = "-m 2048 -e 126976 -c 260 --jrn-size=380928"
UBINIZE_ARGS = "-m 2048 -p 131072"
UBI_IMGTYPE = "ubifs"
IMAGE_NAME_SUFFIX = ".oem"
IMAGE_INSTALL = ""
IMAGE_LINGUAS = ""
PACKAGE_INSTALL = ""
inherit image
这里的 260 是按照如下公式所计算得到:
用户可以使用 bitbake 命令来编译这个 ameba-image-oem。
在 DTS 中挂载 MTD 块
对于 generic 128M 机器,用户可以修改文件 rtl8730e-spi-nand-128m.dtsi
以挂载特定的 MTD 块。
这里,我们在 dts 文件中添加一个 MTD block 10。
// Add ubi.mtd=10 at end of this line.
bootargs = "console=ttyS0,1500000 earlycon psci=enable ubi.mtd=8 ubi.block=0,0 root=/dev/ubiblock0_0 rootfstype=squashfs,ubifs ubi.mtd=9 ubifs ubi.mtd=10";
自动加载 OEM 分区
用户可以在脚本文件 <sdk>/sources/yocto/meta-realtek/meta-realtek-bsp/recipes-core/initscripts/initscripts-1.0/overlay.sh
中添加步骤,使 OEM 分区自动挂载。
pivot_root /mnt/merged /mnt/merged/rom
#Add the procedure here.
mkdir -p /oem
mount -t ubifs /dev/ubi2_0 /oem
if [ ! -e /run/udev ] ; then
mkdir -p /run/udev
fi
另一种方法是,用户可以通过修改 rcS 文件来实现自动挂载: <sdk>/sources/yocto/meta-realtek/meta-sdk/recipes-rtk/rtk-rc-local/rtk-rc-local/rcS
。用户可以选择其中任意一种方式。
cat /etc/motd
#Add the procedure here.
mkdir -p /oem
mount -t ubifs /dev/ubi2_0 /oem
# Set country to Worldwide
#iw reg set 00
单独编译 OEM。
bitbake ameba-image-oem
编译
在编译新的固件之前,用户需执行 mclean 来清理旧的固件。
mclean
执行 m 或者 bitbake 来最后编译新的固件。
调试
在 Uboot 阶段无法加载内核
在 uboot 加载内核时可能会出现问题,如下图所示。用户可以执行 env print 或者 printenv ,然后可以看到环境变量与预期不同。

对于此问题,建议用户检查以下信息:
参考 如何调整 Uboot defconfig 章节,确保被修改的内容符合预期。
首先清理之前旧的固件。
bitbake atf-ameba -c cleanall bitbake u-boot-ameba -c cleanall
重新编译,确保修改的内容在新的固件里。
找不到 OEM 固件
在编译其,用户可以先手动编译 OEM 固件。
bitbake ameba-image-oem
下面的步骤描述了如何把它添加到命令 m 中。
下载固件
用户可以按照下面所示手动修改布局:


或者,用户可以给 Image-Tool 载入 AmebaSmart_Linux_NAND_128MB_Anker.rdev
。
如果 OEM 是手动独自编译的,用户可以改为下载 meba-image-oem-rtl8730elh-va7-20240906032841.oem.ubi
。如果用户已经如 envsetup.sh (找不到 OEM 固件)所述将这个文件重命名为 oem.img,请下载这个 oem.img。
功能验证
启动正常
在启动过程中,用户可以看到如下所示的信息:

用户可以看到这些信息与期望的布局是一样的。
并且,如果 OEM 固件被加载,用户可以看到如下所示的更多信息:




恢复系统
recovery 的 dts 文件如下所示:

如果您需要修改这个 dts 文件,可以按照以下方式调整 reg 值:

如果用户使用 USB 进行恢复,应该将 udev-extraconf 添加到 ameba-image-core.bb
中以支持 USB。
