跳到主要内容

FASTBOOT 功能配置

FASTBOOT(快速启动)是一种能显著缩短系统启动时间、提升设备响应速度的启动机制。本文档将详细介绍配置FASTBOOT系统时需要涉及的模块和仓库设置,包括SDK构建配置、BOOT0配置以及存储设备配置。如果您不想深入了解这些细节,可以直接使用SDK提供的快启开发方案进行板级配置。

SDK 已提供的快启方案

SDK已经内置了便捷的快启开发方案,让您能快速部署和使用FASTBOOT功能。在执行lunch命令选择配置时,如果能看到启动方式为FASTBOOT的选项,说明相关功能已经成功部署。您可以基于此方案进行二次开发,无需自行处理复杂的快启配置。

方案列表

使用 QuickConfig 切换快启通路

SDK提供了board_use_fastboot_nor配置命令,可以一键切换到SPI NOR存储介质的快启模式。只需执行以下命令即可完成切换:

quick_config board_use_fastboot_nor

切换完成后,请参考以下章节进行个性化参数配置:

  • 获取相关参数
  • 配置内核快启
  • 配置 Rootfs 提前启动应用

手动快启通路配置

本节以V861-BGA_PERF1板级为例,演示如何将默认的普通SPI NOR启动模式切换为SPI NOR快启模式。在SDK中,V861-BGA_PERF1的配置路径如下:

  • 设备配置(含设备树、分区表、板级配置项):device/config/chips/v861/configs/bga_perf1
  • 目标配置(含ROOTFS配置、ROOTFS加载文件):openwrt/target/v861/v861-bga_perf1
  • RTOS设备配置(RTOS引脚功能设置):rtos/board/v861_e907/bga_perf1/configs
  • RTOS功能配置(RTOS功能设置、RTOS主函数):rtos/lichee/rtos/projects/v861_e907/bga_perf1
备注

板级配置分为两种方案:NOR方案和非NOR方案。切换NOR快启时需修改NOR配置;切换非NOR存储(如SPI NAND、eMMC、SD Nand)时需修改非NOR配置。以下是V861-BGA_PERF1板级的配置文件示例:

  • SPI NOR存储的板级配置文件:
    • BoardConfig:BoardConfig_nor.mk
    • boot_package:boot_package_nor.cfg
    • 分区表:sys_partition_nor.fex
  • 非NOR存储的板级配置文件:
    • BoardConfig:BoardConfig.mk
    • boot_package:boot_package.cfg
    • 分区表:sys_partition.fex

获取相关参数

在适配快启系统前,您需要先编译一次普通固件,收集一些关键启动参数信息,主要包括bootargs和分区配置。这些参数在后续配置中会用到,所以这一步是必须的。

收集 cmdline 配置

系统启动后,执行以下命令查看并保存cmdline配置:

cat /proc/cmdline

cmdline配置

命令输出的数据就是cmdline,请将其保存好,后续需要写入到board.dts文件中。

BOOT0 切换快启通路

引用配置文件

SDK已经预配置了针对不同存储介质的快启BOOT0配置文件,包括:

  • cfg_mmc_fastboot.mk:适用于eMMC、TF卡、SD Nand等存储介质的快启配置
  • cfg_nand_fastboot.mk:适用于SPI NAND存储介质的快启配置
  • cfg_nor_fastboot.mk:适用于SPI NOR存储介质的快启配置

快启 BOOT0 配置文件

SPI NOR 存储介质配置

修改板级目录下的SPI NOR专用配置文件device/config/chips/v861/configs/bga_perf1/BoardConfig_nor.mk,在LICHEE_SPL_BOARD_MK配置项中添加spinor-cfg_nor_fastboot,表示为SPI NOR配置启用快启功能:

LICHEE_SPL_BOARD_MK:="spinor-cfg_nor_fastboot"

SPI NOR 快启 BOOT0 配置

此外,还需要配置备份ENV的大小,以减少ENV的Flash读取时间:

LICHEE_REDUNDANT_ENV_SIZE:=0x1000

ENV 大小配置

需要配置内核压缩模式为 LZ4 以获取最快的解压速度:

LICHEE_COMPRESS:=lz4

配置内核压缩 LZ4

提示

修改BoardConfig文件后,请重新执行lunch命令以重新加载配置

MMC 存储介质配置

MMC存储介质包括所有使用SDIO总线通信的存储设备,如eMMC、SD Nand和TF卡。需要修改板级目录下的通用配置文件device/config/chips/v861/configs/bga_perf1/BoardConfig.mk(注意:不是SPI NOR专用的BoardConfig_nor.mk),在LICHEE_SPL_BOARD_MK配置项中添加mmc-cfg_mmc_fastboot

LICHEE_SPL_BOARD_MK:="mmc-cfg_mmc_fastboot"

MMC 快启 BOOT0 配置

同样需要将内核压缩模式配置为LZ4以获得最快的解压速度:

LICHEE_COMPRESS:=lz4

配置内核压缩 LZ4

提示

修改BoardConfig文件后,请重新执行lunch命令以重新加载配置

SPI NAND 存储介质配置

修改板级目录下的通用配置文件device/config/chips/v861/configs/bga_perf1/BoardConfig.mk,在LICHEE_SPL_BOARD_MK配置项中添加nand-cfg_nand_fastboot

LICHEE_SPL_BOARD_MK:="nand-cfg_nand_fastboot"

SPI NAND BoardConfig 配置

同样需要将内核压缩模式配置为LZ4:

LICHEE_COMPRESS:=lz4

配置内核压缩 LZ4

提示

修改BoardConfig文件后,请重新执行lunch命令以重新加载配置

SPI NAND 裸分区配置

对于SPI NAND存储介质,还需要额外配置裸分区布局。具体操作是:在device/config/chips/v861/configs/bga_perf1目录下新建一个名为spl.dts的文件,作为BOOT0的分区配置文件,然后写入以下内容:

#include "spl.dtsi"

&sunxi_flashmap {
nand_map {
partition0 {
part_name = "boot_param";
phy_block_num = <2>;
};
partition1 {
part_name = "boot";
phy_block_num = <160>;
};
partition2 {
part_name = "boot_backup";
phy_block_num = <160>;
};
partition3 {
part_name = "riscv0";
phy_block_num = <32>;
};
partition4 {
part_name = "riscv0_bak";
phy_block_num = <32>;
};
};
};

上述配置定义了SPI NAND的分区布局,每个分区都有特定的功能,确保系统在启动和运行时的稳定性与可靠性。由于NAND Flash可能会出现坏块,配置中特别设计了备份机制来应对这种情况。

分区功能说明

  1. boot_param

    • 分区名称: boot_param
    • 物理块数量: 2
    • 功能描述: 存储系统启动参数。由于这些参数在系统初始化时只会写入一次,且只占用2个物理块,所以不需要双备份,这样可以提高存储效率和访问速度。
  2. boot

    • 分区名称: boot
    • 物理块数量: 160
    • 功能描述: 存储操作系统内核,是设备启动的核心部分。160个物理块的大小足以存储内核及相关启动文件。考虑到NAND Flash可能出现坏块,我们为这个分区设计了备份机制。
  3. boot_backup

    • 分区名称: boot_backup
    • 物理块数量: 160
    • 功能描述: 作为boot分区的备份,存储一份完整的内核镜像。当主内核分区出现故障(如遇到坏块)时,可以从这个备份分区恢复,确保系统的可靠性。
  4. riscv0

    • 分区名称: riscv0
    • 物理块数量: 32
    • 功能描述: 存储RISC-V架构处理器(通常是E907小核)的实时操作系统(RTOS)文件。32个物理块的大小适合存储RTOS的必要组件,支持实时计算和任务调度功能。
  5. riscv0_bak

    • 分区名称: riscv0_bak
    • 物理块数量: 32
    • 功能描述: 作为riscv0分区的备份,确保在原分区出现问题时,可以快速从备份中恢复数据,避免因坏块导致的系统故障。
注意

由于NAND Flash的特性,使用时需要注意以下几点:

  • 裸分区管理: 每个分区都是物理连续且地址固定的。如果写入过程中遇到坏块,该块的数据将不可用,因此备份分区对于保障数据完整性至关重要。
  • 自动恢复机制: 系统会自动检测主分区的坏块情况,一旦出现问题,会立即切换到相应的备份分区,确保系统继续稳定运行。

SPI NOR 存储介质配置项说明

在BOOT0配置文件brandy/brandy-2.0/spl/board/sun252iw1p1/cfg_nor_fastboot.mk中,通过一系列配置项来实现快启功能。

ENV 相关配置

  1. 配置ENV大小

通过CFG_SUNXI_ENV_SIZE配置项来设置ENV分区的大小,确保与BoardConfig中的配置保持一致:

CFG_SUNXI_ENV_SIZE=0x1000

ENV SIZE 配置

  1. 配置ENV备份

通过CFG_SUNXI_HAVE_REDUNDENV配置项来启用或禁用ENV分区的备份功能。如果分区表中只有一个ENV分区(没有备份),则需要禁用这个选项。

信息

建议启用ENV分区备份功能,因为ENV分区可能会被读写修改,存在写操作过程中突然断电导致数据损坏的风险。

CFG_SUNXI_HAVE_REDUNDENV=y

ENV 备份配置

提示

修改 BoardConfig 请重新 lunch 以重新加载

压缩相关配置

快启系统通常会选择LZ4压缩格式,因为它是目前解压速度最快的压缩格式。这里只需与BoardConfig中的配置保持同步即可:BoardConfig配置了哪种压缩格式,就启用对应格式的压缩配置;同时,关闭不使用的压缩格式可以减少BOOT0的代码大小,进一步提高加载速度。

配置压缩格式

提示

修改BoardConfig文件后,请重新执行lunch命令以重新加载配置

快启核心配置选项

以下是快启系统的核心配置项,这些配置直接影响启动速度和流程:

CFG_BOOT0_LOAD_KERNEL=y        # 启用BOOT0直接加载内核功能,简化启动流程
CFG_KERNEL_BOOTIMAGE=y # 配置内核使用bootimage格式,整合内核及相关启动文件
CFG_LOAD_DTB_FROM_KERNEL=y # 从内核镜像中加载设备树(DTB),减少单独加载步骤
CFG_KERNEL_CHECKSUM=n # 禁用内核校验和检查,注释说明:设为y会检查内核校验和但降低启动速度
CFG_KERNEL_LOAD_ADDR=0x42600000 # 指定内核在内存中的加载地址,需与内核编译时的链接地址一致
CFG_SUNXI_FDT_ADDR=0x40c00000 # 指定设备树(DTB)在内存中的加载地址
CFG_FASTBOOT_EFEX=y # 启用快速启动的EFEX功能,优化启动流程
CFG_EARLY_BOOT_RISCV=y # 启用RISC-V核心的早期启动,加速系统初始化过程
CFG_SUNXI_NO_UPDATE_FDT_CHOSEN=y # 禁用更新设备树中的chosen节点,减少启动时间
CFG_SUNXI_NO_UPDATE_FDT_PARA=y # 禁用更新设备树中的参数,进一步减少启动速度

配置项详细说明

  1. CFG_BOOT0_LOAD_KERNEL

    • 默认值: y(启用)
    • 功能: 让BOOT0(系统启动的第一阶段引导程序)直接加载内核
    • 作用: 简化启动流程,减少中间环节,从而提高启动速度
  2. CFG_KERNEL_BOOTIMAGE

    • 默认值: y(启用)
    • 功能: 配置内核使用bootimage格式
    • 说明: 目前快启只支持bootimage格式的固件,这也是SDK的默认格式。这种格式会将内核及相关启动文件整合在一起,方便快速加载
  3. CFG_LOAD_DTB_FROM_KERNEL

    • 默认值: y(启用)
    • 功能: 从内核镜像(bootimage)中加载设备树(DTB)
    • 作用: 设备树包含硬件设备信息,将其与内核打包在一起可以减少单独加载的步骤,提高启动效率
  4. CFG_KERNEL_CHECKSUM

    • 默认值: n(禁用)
    • 功能: 控制是否检查内核镜像的校验和
    • 说明: 设为y时会验证内核的完整性,但会降低启动速度;快启模式下默认禁用,以换取更快的启动速度
  5. CFG_KERNEL_LOAD_ADDR

    • 默认值: 0x42600000
    • 功能: 指定内核镜像在内存中的加载地址
    • 注意事项: 这个地址必须与内核编译时的链接地址一致,否则会导致启动失败
  6. CFG_SUNXI_FDT_ADDR

    • 默认值: 0x40c00000
    • 功能: 指定设备树(DTB)在内存中的加载地址
    • 说明: 设备树将被加载到RAM中的这个位置,供内核访问硬件设备信息
  7. CFG_FASTBOOT_EFEX

    • 默认值: y(启用)
    • 功能: 启用快速启动的EFEX功能
    • 说明: EFEX是支持USB一键烧录的功能,它不会增加启动时间,所以默认开启即可
  8. CFG_EARLY_BOOT_RISCV

    • 默认值: y(启用)
    • 功能: 让RISC-V核心(通常是E907小核)提前启动
    • 作用: 与常规模式相比,提前启动RISC-V核心可以更早地运行RTOS,执行相关的快启操作,加速系统初始化过程
  9. CFG_SUNXI_NO_UPDATE_FDT_CHOSEN

    • 默认值: y(启用)
    • 功能: 禁用更新设备树中的chosen节点
    • 说明: chosen节点通常包含启动参数,禁用更新可以减少启动时间,是快启模式的优化项之一
  10. CFG_SUNXI_NO_UPDATE_FDT_PARA

    • 默认值: y(启用)
    • 功能: 禁用更新设备树中的参数
    • 说明: 进一步减少不必要的设备树修改操作,提高启动速度,是快启模式的重要优化项

配置BOOT0关闭打印

要关闭BOOT0阶段的调试打印(这也能提高启动速度),可以修改板级配置文件device/config/chips/v861/configs/bga_perf1/sys_config.fex,找到debug_mode = 8这一行,将其改为:

debug_mode = 0

这样就可以关闭BOOT0的打印输出了。

debug_mode 配置

其他配置功能

CFG_SHORT_COMMIT_LOG 配置可以减少快启阶段的启动打印信息。由于 BOOT0 阶段的调试打印是 CPU 阻塞发送的,减少这个阶段的打印信息对提升启动速度有明显帮助。

配置快启专用的 OpenSBI

快启系统需要 BOOT0 直接跳转内核,因此需要使用专门的 OpenSBI 固件。配置步骤如下:

  1. 修改 OpenSBI 拷贝配置
    • 打开板级配置文件:device/config/chips/v861/configs/bga_perf1/BoardConfig_nor.mk
    • 添加以下配置,指定需要从 device/config/chips/v861/bin 拷贝到打包仓库的 OpenSBI 文件:
      LICHEE_OPENSBI_BIN_NAME:=opensbi_sun252iw1p1_fastboot

OpenSBI 拷贝配置

提供的 OpenSBI 固件示例:

OpenSBI 固件

提示

修改 BoardConfig 文件后,请重新执行lunch命令以重新加载配置

  1. 配置 OpenSBI 打包
    • 在板级目录下新建 boot_package_nor.cfg 文件
    • 写入以下配置内容(注意:文件末尾必须添加三行空行,否则可能导致打包失败):
      [package]
      ;item=Item_TOC_name, Item_filename,
      item=opensbi, opensbi_sun252iw1p1_fastboot.fex
    对于非 NOR 存储介质方案,需要新建 boot_package.cfg 文件,配置内容与上述一致。

配置内核快启参数

快启系统跳过了 U-Boot 阶段,原本由 U-Boot 传递给内核的启动参数现在需要手动配置。这部分需要使用到之前在【获取相关参数部分】保存的数据。

  1. 配置内核启动参数

    • 打开内核设备树文件:device/config/chips/v861/configs/bga_perf1/linux-6.6-xuantie/board.dts
    • 添加 chosen 节点,并将之前保存的 cmdline 数据填入 bootargs(注意:bootargs 的配置不可换行,否则会导致内核参数解析错误):
      chosen {
      bootargs = "之前保存的 cmdline 参数"; // 例如: "earlycon console=ttyS0,115200 root=..."
      };

    配置 bootargs

  2. 配置系统内存资源

    • 同样在设备树文件中,配置内存资源(这部分原本也是由 U-Boot 自动配置的)

    • 内存配置需要关注起始地址和内存大小:

      • 起始地址默认是 0x40000000
      • 内存大小根据实际硬件配置:
        • 128MB 内存配置为 0x08000000
        • 512MB 内存配置为 0x20000000
        • 以此类推
      memory@40000000 {
      device_type = "memory";
      reg = <0x00000000 0x40000000 0x00000000 0x08000000>; // 0x08000000 代表 128MB 内存
      };

    内存节点

  3. 配置存储控制器,在有 U-Boot 的普通流程中,存储控制器是由 U-Boot 自动识别启用的,在快启的时候就需要手动启用了,例如这里是通过 SPIF 控制器接 SPI NOR 外设,所以需要启用这个驱动。

SPIF 启用驱动

如果是 SD NAND 或 eMMC,需要启用对应的控制器例如 SDC2,或 SDC0

同步快启分区配置

完成上述配置后,需要同步分区信息。可以通过 quick_config 工具自动同步,也可以手动同步。

使用 quick_config 同步(推荐)

quick_config 工具支持同步三种存储介质的分区参数:

  • NOR 介质:sync_partition_nor_to_bootargs
  • MMC 介质:sync_partition_to_bootargs
  • SPI NAND(UBI)介质:sync_nand_partition_to_bootargs

执行 quick_config 命令即可完成配置。配置后还需要手动设置逻辑分区的起始地址,具体方法请参考【配置逻辑分区地址】部分。

手动同步分区表

打开使用的分区表文件,记录每个分区的名称和对应的 block 编号(从 1 开始):

提示

注意:mtdblock0 是裸分区,不在分区表上,默认名称为 uboot

将分区表的信息一一对应填写到 bootargs 中即可。注意:虽然下面的示例为了展示对应关系换行显示,但实际配置时必须将 bootargs 写在一行。

同步分区表

配置逻辑分区地址

需要注意:SPI NOR 和 MMC 设备需要配置逻辑分区地址,而 SPI NAND 设备不需要,因为它们的分区管理方式不同。

对于 SPI NOR 和 MMC 设备,还需要同步配置 mbr_offset 来确定逻辑分区的起始地址:

  1. 打开板级目录下的 uboot-board.dts 文件
  2. 找到 sunxi_flashmap 节点中的 logic_offset
  3. 计算 mbr_offsetlogic_offset × 512(因为 logic_offset 的单位是扇区,每个扇区大小为 512Byte)

配置逻辑分区地址

修改 lunch 菜单显示快启

如果希望在执行 lunch 命令时,默认显示当前板级的快启配置,可以修改板级 target 目录下的配置文件,将其设置为 FASTBOOT 模式:

修改文件路径:

openwrt/target/v861/v861-bga_perf1/lunch_menu.mk

lunch menu 显示配置

将快启的 quick_config 配置加入 quick_config 命令

默认情况下,快启板级可以使用基本的快启配置,但如果需要从常电模式切换到快启模式,还需要额外配置:

  1. 打开板级目录下的 quick_config.json 文件
  2. 将快启的配置加入 include 字段中

修改 quick_config 配置

这样配置后,就可以使用快启特有的配置参数了,例如启动加速模块:

配置参数示例

配置 BOOT0 解压加速

在启动阶段,其实大部分时间是从存储加载固件到内存解压运行,存储读取速度是有上限的,所以更多会用优化解压性能的方式加速读取和解压的流程。

SDK 目前支持 LZ4 压缩格式的解压加速功能,可以通过修改 BoardConfig 文件,在 LICHEE_SPL_BOARD_MK 中新增 cfg_lz4_parall_decomp 方式,启用 LZ4 加速解压功能。

LZ4 加速解压

常见配置问题

修改快启后打包失败

打包失败

原因:通常是因为修改了压缩格式导致的问题。默认使用 gzip 压缩,而快启使用 lz4 压缩,两种压缩格式的压缩率不同,导致解压后的文件大小变化,需要更大的分区空间。

解决方案

  • 需要扩大分区表中的分区大小
  • 推荐使用 auto_update_partition 自动化脚本进行分区扩容,操作更简单高效

修改快启后启动卡在 OpenSBI

卡在 OpenSBI

原因:一般是踩内存导致问题,由于快启系统排布非常紧凑,内核过大就容易踩到内存,可以向上找日志,看启动的内核大小,按默认布局不建议内核超过 0x60000,这里 0x7e6fe2 已经踩内存了

看内核大小

启动秒崩溃,无打印无显示

原因:极有可能是没有按照文档要求配置内核快启参数。例如,cmdline 参数不完整,或者内存配置过小(如只配置了 64MB)。

解决方案

  • 请参考【配置内核快启参数】章节,正确配置 bootargs 和内存参数
  • 确保 bootargs 包含完整的启动参数
  • 确保内存配置与实际硬件一致(如 128MB 内存应配置为 0x08000000
  • 确保没有踩内存,因为内存过大踩到了设备树的内存

修改设备树的加载地址,放到其他没有冲突的地址即可,请参考【快启核心配置选项】修改配置

修改设备树地址

启动秒崩溃,打印 "Unable to handle kernel paging request"

启动马上崩溃,需要注意的是快启是否存在踩内存的情况,此时应该是在初始化系统基础资源,需要检查是否开启了这两个库

CONFIG_CRYPTO_ARC4
CONFIG_CRYPTO_USER_API_HASH

这两个库不兼容快启流程,需要关闭

启动崩溃

启动后 U-Boot 没有打印输出

原因:这是正常现象,因为快启系统对 U-Boot 进行了裁剪,移除了打印功能以提高启动速度。

解决方案:无需处理,这是快启模式的预期行为。

启动后一直在 Waiting for root device

这是由于没有配置启用 SPI、MMC 控制器,请参考【配置内核快启参数】配置设备树

Waiting for root device

如果已经配置了,可能是因为没有同步 mbr_offset 配置,先检查一下内核是否有 sunxipart: failed to parse sunxi_gpt! 的打印,如果有则是需要同步 mbr_offset

sunxipart: failed to parse sunxi_gpt!