Edit online

SPINAND OTA 参数配置

SPINAND OTA 参数配置主要分为主系统配置, Recovery 系统配置, 以 nand 为例进行说明

系统名称 配置文件
主系统 d211_demo100_nand_defconfig
Recovery 系统 d211_ota_defconfig
主系统配置涉及到的文件如下:
1. target/d211/demo100_nand/image_cfg.json //分区配置和烧录
2. target/d211/common/env.txt //U-Boot 环境变量
3. target/d211/demo100_nand/rootfs_overlay/etc/fw_env.config
4. target/d211/demo100_nand/rootfs_overlay/etc/swupdate_main
5. target/d211/demo100_nand/swupdate/sw-description
6. target/d211/demo100_nand/swupdate/sw-images.cfg
7. target/configs/d211_demo100_nand_defconfig
Recovery 系统配置涉及到的文件如下:
  • target/d211/ota/rootfs_overlay/etc/fw_env.config
  • target/d211/ota/rootfs_overlay/etc/init.d/S91swupdate_ota
  • target/target/configs/d211_ota_defconfig

Recovery 系统配置

  1. SWUpdate 包配置

    Recovery 系统配置文件路径为 target/configs/d211_ota_defconfig

    1. 进入到 Recovery 系统 SDK 生产环境
      lunch ota
      
    2. 在 Luban 根目录下执行命令
      make m
      
    3. 进入 SDK 功能配置, 按如下选择:
      Third-party packages  --->
          -*- libubootenv  --->
          -*- libconfig  --->
          -*- libcurl  --->
          [*] swupdate  --->
      
          [*] mtd, jffs2 and ubi/ubifs tools  --->        //SPINAND 平台需要
      
  2. 配置 RootFS 为 initramfs
    1. 默认切换 RootFS 配置为 initramfs, 执行命令
      make m
      
    2. 配置如下:

      Filesystem images  --->
      RootFS images  --->
          -*- cpio the root filesystem (for use as an initial RAM filesystem)
              Compression method (gzip)  --->
      [*] initial RAM filesystem linked into linux kernel
      
    3. 默认将 initramfs 编译进 Kernel, 执行命令

      make km
      

      配置如下:

      General setup  --->
      [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
      [*]   Support initial ramdisk/ramfs compressed using gzip
      

主系统配置

SWUpdate 包配置:
  1. 进入主系统 SDK 生产环境
    lunch d211_demo100_nand
    
  2. 在 Luban 根目录下执行配置命令
    make m
    
  3. 进入 SDK 功能配置, 按如下配置选择:
    Third-party packages  --->
        -*- libubootenv  --->
        -*- libconfig  --->
        -*- libcurl  --->
        [*] swupdate  --->
    
        [*] mtd, jffs2 and ubi/ubifs tools  --->        //SPINAND 平台需要
    
  4. 查看 SWUpdate 库相关配置如下:
    [*]   use prebuilt binary instead of building from source
    (package/third-party/swupdate/luban_swupdate.config) swupdate configuration file
    [*]   swupdate webserver
  5. 查看 SWUpdate 相关配置, 需要先关闭 SWUpdate 预编译功能:

    [ ]   use prebuilt binary instead of building from source
  6. 执行命令查看 SWUpdate 相关配置

    make swupdate-menuconfig
    

    SWUpdate 包重要配置信息解析:

    文件 说明
    CONFIG_UBOOT=y 支持 U-Boot
    CONFIG_DOWNLOAD=y 使能通过 libcurl 的方式下载程序
    CONFIG_DOWNLOAD_SSL=y 在使用 libcurl 时使能 ssl 校验
    CONFIG_WEBSERVER=y 编译 web 服务器, 设备端作为服务器使用
    CONFIG_HASH_VERIFY=y 解析升级包时使能 sha256 校验
    CONFIG_BOOTLOADERHANDLER=y 在升级过程中允许修改 Boot 环境变量
    CONFIG_CFI=y 允许给 flash 烧录程序
    CONFIG_RAW=y 默认烧录方式, 给 eMMC 使用
    CONFIG_SHELLSCRIPTHANDLER=y 支持 shell 脚本升级
    CONFIG_UBIVOL=y 支持 UBI 分区升级
    CONFIG_UBIBLACKLIST=”0 1” 执行 ubiattach 时跳过的分区号
    1. 执行 ubiattach 时跳过的分区号, 与实际不匹配, 执行 ubiattach 时会报错信息, 不影响正常升级过程

    2. 如果需要重新配置 SWUpdate 参数, 必须关掉 SWUpdate 预编译功能, 修改的 SWUpdate 配置才能够生效

增加 Recovery 分区并烧录程序

增加 recovery 分区, 烧录 Recovery 系统镜像。在 json 修改如下:
"kernel":   { "size": "12m" },
+ "recovery": { "size": "10m" },          //在 kernel 分区后面增加 recovery 分区

"kernel": {
        "file": "kernel.itb",
        "attr": ["mtd", "required"],      //在 kernel 镜像烧录配置后面添加 recovery 镜像烧录配置
        "part": ["kernel"]
},
+ "recovery": {
+    "file": "recovery.itb",              //将 itb 镜像文件烧录到 recovery 分区里面
+    "attr": ["mtd", "required"],
+    "part": ["recovery"]
+ },

"kernel.itb": {
        "its": "kernel.its"               //在 kernel 镜像生成方法后面增加 recovery 镜像生成方法

},
+ "recovery.itb": {
+    "its": "recovery.its"                //配置 itb 文件通过 recovery.its 指导编译完成
+ },
  1. 在 image 目录中检查 recovery.itb 文件是否生成

  2. 通过升级信息判断 itb 是否烧录到 recovery 分区

U-Boot 环境变量配置

  1. 通过环境变量 partition 决定从 kernel 分区还是 recovery 分区引导启动

    在 d211/common/env.txt 修改如下:

    + set_commonargs_recovery=setenv bootargs earlycon=${earlycon} earlyprintk console=${console} rdinit=/linuxrc
    + //从 Recovery 系统启动, 引导 initramfs 启动
    
    + set_nand_bootargs_recovery=run set_nand_mtdargs; \      //设置环境变量 set_nand_bootargs_recovery
    +    run set_commonargs_recovery; \
    +    setenv bootargs ${bootargs} mtdparts=${MTD}
    
    + ubi_rootfs_mtd=10       //适配环境变量 ubi_rootfs_mtd, 保证主系统能够正常启动
    + boot_partition=kernel   //初始化环境变量 partition 从 kernel 分区启动
    
    + run set_nand_bootargs_recovery; \
    + loadknl mtd recovery ${knl_addr}; \
    + bootm ${knl_addr};      //nand_boot 环境变量增加从 recovery 分区引导启动
    

    手动配置环境变量 partition 并保存, 重启测试 Boot 是否能够引导 Recovery 系统启动, 判断配置文件是否生效

  2. 分区表配置增加 env 备份分区

    添加 env 备份分区, 保障 env 数据掉电安全, 在 json 配置修改如下:

    "env":      { "size": "256k" },
    + "env_r":    { "size": "256k" },         //在 env 分区后面增加 env_r 分区
    
    "env": {
        "file": "env.bin",
        "attr": ["mtd", "required"],
    -    "part": ["env"]
    +    "part": ["env","env_r"]             //将 bin 文件同时烧录到 env、env_r 分区
    },
    

    通过升级串口打印信息可以判断 bin 文件是否烧录到 env_r 分区, 判断配置是否生效

  3. U-Boot 使能 env redundant 配置

    执行 um 使能 env redundant 机制:

    Environment  --->
        [*] Enable redundant environment support
        (0x220000) Redundant environment offset
    
    1. 当升级过程中掉电时, 其中一份环境变量如果被破坏, 另外一份环境变量还能够继续引导启动

    2. 客户可以手动擦除其中一份环境变量, 测试系统能否正常启动, 写入保存环境变量后, 被擦除的环境变量是否能够恢复

    3. CONFIG_ENV_OFFSET_REDUND 为 r 分区的偏移值, 需要与分区表匹配

    当使能了 redundant 机制, 编译后烧录程序, 可能会出现以下错误信息:
    Loading Environment from RAM... *** Warning - bad CRC, using default environment
    主要原因是,U-Boot 解析的方法发生了改变, 解析数据格式增加了一个字节, 判断那一份 env 数据最新, 具体可以通过 redundant 宏查看对应的程序。 解决问题办法, 在 json 修改如下:
            "uboot_env": {
                    "env.bin": {
                            "file": "env.txt",
                            "size": "0x4000",
    +                       "redundant": "enable",
                    },
            },

    不使能 env 备份区域,”redundant” 设置为 “disable” 或者不设置

  4. fw_env.config 配置

    OTA 升级过程中, 主系统和 Recovery 系统都使用到 SWUpdate 命令, SWUpdate 依赖 Boot 环境变量, 需要在 Linux 中配置 U-Boot 环境变量索引路径。

    fw_printenv/fw_setenv 命令默认索引路径为:

    /etc/fw_env.config
    因为使用到了 env_r 备份分区, fw_env.config 需要包含 env, env_r 分区信息, SPINAND 的默认的配置信息如下:
    /dev/mtd4               0x0000          0x4000          0x20000
    /dev/mtd5               0x0000          0x4000          0x20000
    
    1. /dev/mtd4 表示 env 分区的设备号, /dev/mtd5 表示 r 分区的设备号

    2. 第二列表示 Device offset

    3. 第三列表示 Env. size

    4. 第四列表示块擦除大小

    Recovery 系统 SDK 生产环境默认存在 config 文件, 具体路径如下:

    target/d211/ota/rootfs_overlay/etc/fw_env.config

    主系统 SDK 生产环境默认存在 config 文件, 具体路径如下:

    fw_env.config 在主系统的路径如下:

    target/d211/<board>/rootfs_overlay/etc/fw_env.config
    1. 客户 env、env_r 分区信息如果修改, 以上两个 config 文件需要同时更新

    2. 在 Linux 环境下执行 fw_printenv/fw_setenv 命令, 测试能够正常打印 Boot 环境变量信息

  5. 配置 ota 分区烧录 OTA 升级包
    在 target/d211/demo100_nand/image_cfg.json 文件修改
    "ubisystem": {
        "size": "-",
        "ubi": { // Volume in UBI device
        +    "ota":   { "size": "48m" },                //ubisystem 分区上增加 ota 分区
            "user":   { "size": "-" },
        },
    },
    
    "rootfs": {
            "file": "rootfs*.ubifs",
            "attr": ["ubi", "required"],
            "part": ["ubiroot:rootfs"]                  //在根文件系统烧录之后增加 ota 分区烧录
    },
    + "ota":   { "size": "48m" },
        +               "ota": {
        +                       "file": "ota*.ubifs",
        +                       "attr": ["ubi", "optional"],
        +                       "part": ["ubisystem:ota"]               //将 ota*.ubifs 文件烧录到 ota 分区里面
        +               },
  6. 主系统配置生成 ota*.ubifs 目标文件
    1. 将 OTA 升级包下载到 ota 分区里面, 方便测试 OTA 本地升级功能

      ota 分区如下所示:

      ../../images/part1.png

    2. 进入主系统 SDK 生产环境
      lunch d211_demo100_nand
      
    3. 在 Luban 根目录下执行配置命令
      make m
      

      配置如下:

      [*] UserFS 1  --->
           (ota) Name
           FS Type (UBIFS)  --->
           (1x3000000) ubifs size(Should be aligned to MB)
           (target/$(LUBAN_CHIP_NAME)/$(LUBAN_BOARD_NAME)/ota) Overlay directory
      
    4. 将 target/$(LUBAN_CHIP_NAME)/$(LUBAN_BOARD_NAME)/ota 目录里的内容生成 ubifs 镜像文件, 之后整个文件烧录到 ota 分区里面。
  7. 启动脚本配置
    主系统和 Recovery 系统默认启动脚本 S90swupdate, 路径如下:
    package/third-party/swupdate/S90swupdate

    S90swupdate 后台执行 progress 命令, 可以接受 SWUpdate 传递的升级信息, 并打印到调试串口, 客户也可以重定向到显示屏上。

    主系统自动挂载 ota 分区脚本路径如下:

    target/d211/<board>/rootfs_overlay/init.d/S91swupdate_main

    主要内容如下:

    ubiattach dev/ubi_ctrl -m $mtd_num          //识别 ota 分区
    mount -t ubifs /dev/$ubi_param /mnt/ota     //挂载 ota 分区到 mnt/ota 目录下
    

    Recovery 系统启动脚本路径如下:

    target/d211/<board>/rootfs_overlay/init.d/S91swupdate_ota

    主要内容如下:

    ubiattach dev/ubi_ctrl -m $mtd_num          //识别 ota 分区
    mount -t ubifs /dev/$ubi_param /mnt/ota     //挂载 ota 分区到 mnt/ota 目录下
    ./usr/lib/swupdate/swupdate_cmd.sh          //执行 OTA 升级程序
    

    该脚本的主要功能是挂载好对应的升级分区, 并执行 Recovery 系统 OTA 升级程序

    主系统和 Recovery 系统挂载设备节点不同