跳到主要内容

FASTBOOT 异构 ROOTFS 功能

在快启流程中,除了启动 BOOT、KERNEL 阶段的性能优化,还有启动到内核中 ROOTFS 加载速度提升。

提升 ROOTFS 加载的方式内核原生提供了 RAMDISK 方式,可以非常快速的读取最小化的 RAMDISK,在 RAMDISK 中运行应用。SDK 更进一步,提供了并行的异构 RAMDISK 功能。相较于传统 RAMDISK 使用异构方式读取解压,提升启动速度,最大化启动性能。

传统的异构 RAMDISK 流程如下:

  • BOOT 初始化 FLASH,加载内核和异构固件
  • BOOT 跳转进入异构固件和内核
  • Linux 在初始化阶段,异构固件读取 RAMDISK 给内核使用
  • 内核启动 RAMDISK 中的应用程序,执行应用

异构 RAMDISK

但是异构 RAMDISK 的缺点也很明显:

  • 需要独立打包 RAMDISK 分区,占用存储容量
  • 一次需要一份独立完整的 RAMDISK,其实更多时候不需要完整的功能但是由于 ROOTFS 还未加载所以需要全部带上
  • RAMDISK 普遍较大,会占用较多预留内存,低内存方案会出现同一时刻内存共存瓶颈
  • RAMDISK 初始化后还需要初始化真正的 ROOTFS,后续服务还是会延后

所以 SDK 提供了另外一套更加简单通用的方案:异构 ROOTFS 方案,通过异构核心,在 Linux 启动阶段从 Linux 的 ROOTFS 中读取需要的文件加载到内存,到 Linux 中直接运行已经加载到内存中的文件,例如应用 APP,可以用异构 ROOTFS 提前加载。这样内核在挂载文件系统的时候就可以直接从内存中运行,而不需要自行读取,解压 ROOTFS。而且由于是直接从同一份 ROOTFS 中读取,所以不需要单独的 RAMDISK 分区,存储占用更少,每次只需要读取必须的文件,读取效率更高,内存需求更少。

异构 ROOTFS 流程如下:

异构 ROOTFS

三种启动方式的比较如下,可以选择自己适合的方式:

类别异构 RAMDISK异构 ROOTFS普通快启
存储占用高,需要单独存放 RAMDISK低,从 Linux 的 ROOTFS 中读取低,与异构 ROOTFS 一致
内存占用高,需要预留压缩空间和解压空间低,只需要运行空间低、无快启优化
启动速度最快,流程最简单,启动速度最快快,流程稍复杂,但也有提升一般、没有 ROOTFS 加载优化

异构 ROOTFS 功能配置

Linux 端相关配置

设备树预留内存配置

首先设备树需要配置 ROOTFS 的预留内存,与 RAMDISK 的标准配置无异

linux,initrd-start = <0x47c00000>;
linux,initrd-end = <0x48000000>;

配置地址

预留内存的大小需要参考需要读取的文件的总大小,一般布局如下:

ROOTFS 文件加载地址

设备树驱动配置

对于使用异构 ROOTFS 的情况,因为还是需要挂载 ROOTFS,所以存储控制器不能配置延后,但是为了保证控制器的时序,需要使用异构锁保证控制器的使用唯一性。设备树不需要配置 deferred-device

内核选项配置

内核需要配置启用 AMP ROOTFS 功能,配置项如下

CONFIG_AW_AMP_ROOTFS
Allwinner BSP  --->
Device Drivers --->
Misc Devices Drivers --->
[*] Allwinner AMP Rootfs Support

配置项

还需要配置内核控制器的异构锁的通讯模块

CONFIG_AW_RPMSG_NOTIFY
Allwinner BSP  --->
Device Drivers --->
Rpmsg drivers --->
<*> Allwinner rpmsg notify driver

异构锁配置

Flash 驱动也需要加上配置

CONFIG_AW_SPIF_DELAYINIT
CONFIG_AW_SPIF_DELAYINIT_RPROC_NAME
Allwinner BSP  --->
Device Drivers --->
<*> Memory Technology Device (AW_MTD) support --->
<*> SUNXI SPIF Controller
[*] SUNXI SPIF Controller Delay Init
(6010000.e907_rproc) SUNXI SPIF Controller Delay Init Rproc Name

FLASH 驱动配置

备注

这里的 Ramdisk Delay Init Rproc Name 配置的名字是异构核心的名字,可以在系统启动后运行

ls /dev/rpmsg_ctrl*

获取异构核的名字

这里的 e907_rproc@06010000 就是异构核心的名字,填入的时候需要改一下格式,改为 6010000.e907_rproc 即可

如果不方便启动系统看配置,可以检查内核设备树 bsp/configs/linux-6.6-xuantie/sun252iw1p1.dtsi

内核设备树看名称

RTOS 端功能配置

异构 ROOTFS 的主要操作基本上在 RTOS 端,所以 RTOS 端的配置需要更加注意。

配置 RTOS 存储驱动

SPI NOR 存储驱动配置

Drivers Options  --->
soc related device drivers --->
AW Flash Drivers --->
[*] Tina Flash Read
Select Storage Type (SPINOR) --->
[*] Flash Wait for Flag
(0) Flash Wait RTC Data Index
(2) Flash Wait RTC Data Bit
(4064) Flash GPT Offset
(128) Flash Boot Package Offset

存储配置驱动项如下:

CONFIG_DRIVERS_AW_FLASH_READ=y
CONFIG_DRIVERS_AW_FLASH_READ_SPINOR=y
# CONFIG_DRIVERS_AW_FLASH_READ_EMMC is not set
# CONFIG_DRIVERS_AW_FLASH_READ_SPINAND is not set
CONFIG_DRIVERS_AW_FLASH_WAIT_FLASH=y
CONFIG_DRIVERS_AW_FLASH_WAIT_FLASH_WAIT_INDEX=0
CONFIG_DRIVERS_AW_FLASH_WAIT_FLASH_WAIT_BIT=2
# CONFIG_DRIVERS_AW_FLASH_WRITE is not set
CONFIG_DRIVERS_AW_FLASH_GPT_OFFSET=4064
CONFIG_DRIVERS_AW_FLASH_BOOTPKG_OFFSET=128
# CONFIG_DRIVERS_AW_FLASH_DEBUG is not set
# CONFIG_DRIVERS_AW_FLASH_USE_HWLOCK is not set

RTOS Flash 驱动配置

  1. 选择 CONFIG_DRIVERS_AW_FLASH_READ 驱动
  2. 配置使用的 FLASH 类型,这里选择 SPI NOR
  3. 配置 [*] Flash Wait for Flag,设置 FLASH 的等待标志,这里按默认即可
  4. 配置 FLASH 的 GPT OFFSET,配置需要与 FLASH MAP 一致,需要找到 uboot-board.dts 中的 flash_map 参考下图配置即可

FLASH MAP 配置

配置 RTOS 解压组件

目前异构 ROOTFS 只支持 LZO 压缩格式解压,需要配置 LZO 压缩格式支持

System components  --->
thirdparty components --->
[*] Compress Support --->
[*] LZO Compress

配置项目如下:

CONFIG_COMPONENTS_COMPRESS=y
CONFIG_COMPONENTS_COMPRESS_LZO=y

配置 LZO 压缩支持

配置 RTOS 文件系统

需要配置开启 RTOS 的文件系统支持,目前异构 ROOTFS 仅支持 SquashFS 文件系统

System components  --->
thirdparty components --->
Filesystem Components --->
[*] SquashFS filesystem support

配置文件系统

配置 RTOS 异构 ROOTFS 功能

CONFIG_PRELOAD_COMPENENTS=y
CONFIG_PRELOAD_COMPENENTS_RPMSG_NOTIFY_NAME="spif"
CONFIG_PRELOAD_COMPENENTS_RPMSG_NOTIFY_PARA=""
CONFIG_USE_PRELOAD_ROOTFS=y
CONFIG_PRELOAD_ROOTFS=y
CONFIG_PRINT_ROOTFS_LOADTIME=y
CONFIG_ROOTFS_LOADADDR=0x47c00000
CONFIG_ROOTFS_PARTITION_SIZE=0x400000
CONFIG_ROOTFS_LOAD_FILES="usr/lib/libc.so lib/libgcc_s.so.1 bin/busybox init"

配置界面如下:

System components  --->
aw components --->
AW Fastboot Preloads Compenents --->
[*] Fastboot Preloads Compenents
(spif) Preloads compenents rpmsg notify name
Select Preload Components Type (Rootfs) --->
[*] load kernel rootfs
[*] Print load time
(0x47c00000) rootfs load address
(0x400000) rootfs load address size
(xxxx) rootfs load file list. e.g. liba libc

异构 ROOTFS 功能

这里主要是配置启用功能,加载地址,可用的长度,还有需要加载到内存的文件,内存长度参考下图,填写基地址和长度即可。

配置长度

CONFIG_PRINT_ROOTFS_LOADTIME 配置是打印读取每个文件的耗时,用于耗时优化,属于调试功能可以不用开启。

CONFIG_ROOTFS_LOAD_FILES 配置后面跟着的是文件列表,需要通过异构 ROOTFS 方式加载的文件列表,例如如下配置

CONFIG_ROOTFS_LOAD_FILES="usr/lib/libc.so usr/lib/liblog.so lib/librt_media.so lib/libawion.so lib/libgcc_s.so.1 bin/busybox bin/demo_video_in init"

包括了运行需要的库,busybox,应用 APP demo_video_in,启动脚本 init。请根据 ROOTFS 中实际的文件路径填写。

增加异构 ROOTFS 启动流程

修改 RTOS 的 main 函数,新增 ROOTFS 启动流程代码,例如在 rtos/lichee/rtos/projects/v861_e907/bga_perf1/src/main.c 中,找到 cpu0_app_entry 函数,这样添加代码

#ifdef CONFIG_PRELOAD_COMPENENTS
extern void flash_load_data_async(void);
flash_load_data_async();
#endif

增加加载流程

文件系统相关配置

由于异构 ROOTFS 只支持 LZO 压缩格式,需要配置打包构建的 ROOTFS 使用 LZO 压缩,这个配置需要同时配置 Kernel 使用 LZO 压缩,和 ROOTFS 构建使用 LZO 压缩。

Kernel 使用 LZO 压缩

执行 m kernel_menuconfig

File systems  --->
[*] Miscellaneous filesystems --->
<*> SquashFS 4.0 - Squashed file system support
[*] Include support for LZO compressed file systems

内核使用 LZO 压缩

ROOTFS 构建打包 LZO 格式

执行 m menuconfig

Target Images  --->
[*] squashfs --->
Compression (lzo) --->

打包使用 LZO 格式

使用异构 ROOTFS 功能

编译打包烧录后,即可测试异构 ROOTFS 功能,可以在小核控制台看到异构 ROOTFS 的相关打印

异构打印

常见问题

RTOS 打印 get_boot_param failed

get_boot_param failed

请确认配置 FLASH 的 GPT OFFSET,配置需要与 FLASH MAP 一致,需要找到 uboot-board.dts 中的 flash_map 参考下图配置即可

FLASH MAP 配置