RISC-V生态全景解析(十四):YoC组件介绍系列四: PARTITION组件

简介: 芯片开放社区(OCC)面向开发者推出RISC-V系列内容,通过多角度、全方位解读RISC-V,系统性梳理总结相关理论知识,构建RISC-V知识图谱,促进开发者对RISC-V生态全貌的了解。

编辑语:

芯片开放社区(OCC)面向开发者推出RISC-V系列内容,通过多角度、全方位解读RISC-V,系统性梳理总结相关理论知识,构建RISC-V知识图谱,促进开发者对RISC-V生态全貌的了解。


YoC基础软件平台具有丰富的IoT组件,可有效支持RISC-V生态应用开发。前几期内容中,我们已经陆续介绍了YoC的CSI组件AT组件AV(多媒体)组件。本期内容,我们将为大家介绍YoC的PARTITION组件,从分区表介绍、配置与接口、配置示例三方面带大家详细了解该组件。


01 概述

PARTITION组件是一个分区管理的组件。基于分区表(MTB)的分区信息来统一管理Flash分区,对分区进行统一的读写、擦除、以及验签的操作。


下面就来介绍下分区表的定义以及组件提供的一些API接口。


02 分区表介绍

分区表简称为MTB(manifest table)。保存系统镜像的基本信息以及签名值。MTB分为两类。

名称

说明

BMTB

bootloader manifest table,记录bootloader镜像的信息,给bootrom使用

IMTB

images manifest table,记录除bootloader以外的其他镜像的信息,给bootloader使用


其中IMTB是必须的,而BMTB则取决于芯片bootrom的设计,是否需要这张BMTB表,使用BMTB的优势是可以灵活的配置boot的地址信息,避免固化在bootrom里。这2张表本身就是以分区的形式存储在Flash中的,在定义分区的时候要预留出来。分区名字也是固定为"bmtb"和"imtb"。

截屏2021-11-22 下午9.29.29.png


分区的信息存储在一个叫config.yaml的文件中,一般放在工程的board或者solution目录下,在打包镜像的时候通过工具自动生成bmtb/imtb两个镜像。


一个典型的分区表如下:

mtb_version: 4
chip: pangu        # cb2201 / cb6501 / pangu
diff:
  fota_version: 0
  ram_buf: 50         #DEC     KB   ( max ram need)
  flash_buf: 16       #DEC     KB   ( buffer size)
  flash_sector: 4096  #DEC     byte ( flash sector)
  diff_mode: 010      #BIN
  double_control: 1   #DEC (1--use 2 sector for diff restore,0--1 sector)
flash:
  base_address: 0x8000000       # the base address of flash
  run_base_address: 0x18000000  # the run address, maybe sdram address
  sector: 4096                  # Bytes
  size: 16777216                # Bytes, $(sector count) * sector
partitions:
  - { name: bmtb,   address: 0x8000000, size: 0x001000 }
  - { name: boot,   address: 0x8001000, size: 0x020000 }
  - { name: tee,    address: 0x8021000, load_addr: 0x18000000, size: 0x010000 }
  - { name: imtb,   address: 0x8031000, size: 0x002000 }
  - { name: prim,   address: 0x8033000, load_addr: 0x18010000, size: 0x300000, verify: true, update: FULL}
  - { name: kv,     address: 0x8633000, size: 0x004000 }
  - { name: lpm,    address: 0x8637000, size: 0x020000 }
  - { name: misc,   address: 0x8657000, size: 0x400000 }


下面介绍下各个字段的意思。


2.1 一级字段说明

字段

说明

mtb_version

MTB格式版本号,默认填4即可

chip

芯片类型

diff

用于差分升级相关的配置参数

flash

flash信息相关参数

partitions

分区表相关参数


2.2 diff字段说明

字段

是否必选

说明

ram_buf

差分还原时所需的ram空间,单位KB;

大于2.3倍flash缓存大小;建议配置为设备系统最大可用内存,以提高差分效率;

大致计算公式:

ram_buf = 2.2 * <flash_buf> + 2 * <flash_sector> + 1024B;

flash_buf

差分还原时所需的flash缓存空间,最小4KB,单位KB;

大于扇区大小,且为扇区大小整数倍;

flash_sector

flash扇区大小,单位byte;

diff_mode

差分模式,二进制字符串,默认使用10模式即可;

value verify  auto_config

00  disable  disable

01  disable  enable

10  enable  disable

11  enable  enable

double_control

是否使用2个flash_sector作为差分控制区域;

此字段不填或者0:1个sector,1:2个sector;

如果在Flash空间上没有特别的紧张,建议使用2个sector作为差分控制区域;


2.3 flash字段说明

字段

是否必选

说明

base_address

flash的起始绝对地址

run_base_address

镜像的运行地址,不填则为flash起始地址

sector

flash每个sector的尺寸,单位byte

size

flash总的大小,单位byte


2.4 partitions字段说明

字段

是否必选

说明

name

分区名字,最长8个字节

address

分区起始地址

load_addr

分区加载地址,如果没有此字段,则默认使用address为加载地址

size

分区大小,单位byte

update

分区升级类型[DIFFFULLNONE],不填则默认为NONE;针对boot分区的升级需要谨慎,因为本身升级的功能在boot里面。

verify

是否要对分区进行签名

file

指定分区对应的镜像文件名字,不填则表示文件名与分区名相同


2.5 常用分区说明

分区

说明

imtb

分区表信息,包含所有分区位置及安全信息

tee

安全执行镜像

boot

bootloader

prim

应用镜像

kv

用户数据区域

misc

升级备份区

lpm

低功耗信息保存区


2.6 注意事项

  • bmtb分区名字固定,大小为1个sector大小,非必选分区。

  • imtb分区名字固定,大小为2个sector大小,必选分区。最好放在比较靠前的地址区域,可以减少查表的时间。
  • tee、prim、boot、kv分区名字固定,不建议修改,大小根据用户自己实际情况来配置,sector对齐。
  • misc分区名字固定,全量和差分升级时所需要的备份分区,大小根据实际情况来配置,sector对齐。
  • 其他分区大小也是sector对齐,名字用户可以自定义。


03 配置与接口介绍

介绍partition组件的一些参数配置和常用API接口。


3.1 参数配置

以下宏定义在PARTITION组件的yoc/partition.h文件中,用户可以在应用方案的package.yaml中的def_config字段中进行重新定义。

宏配置

说明

CONFIG_MAX_PARTITION_NUM

分区个数配置。

定义最大的分区个数,如果用户没有自定义,那么默认为12个分区大小。如果ram资源比较紧张,而分区又没有达到12个,那么可以把这个宏改成实际分区个数。每减少一个分区,分别可以节省40个字节的data段size,和调用partition_init的任务最多40个字节的栈空间。

CONFIG_PARITION_NO_VERIFY

分区校验配置。

是否开启分区校验功能,默认值为1,为不开启校验。

安全的方案需要配置成0。

CONFIG_NOT_SUPORRT_SASC

安全区域设置配置。配置分区的访问权限。

是否支持设置安全区域,默认值为1,不支持设置安全区域。

如果芯片支持,可以在board组件中配置为0,开启此功能。


3.2 接口介绍

API接口定义在yoc/partition.h文件中。提供了包括分区初始化、打开、关闭、读写、Verify等操作。


整个系统中需要调用partition_init初始化一次,后面才能对分区进行一些操作。

接口

说明

partition_init

分区初始化

partition_open

打开分区

partition_close

关闭分区

partition_info_get

获取分区信息

partition_read

读取分区数据

partition_write

往分区写数据

partition_erase

擦除分区数据

partition_verify

校验分区

partition_all_verify

校验所有分区

partition_get_digest

获取分区数字摘要信息

partition_set_region_safe

设置安全区域,调用此接口可以把分区配置成只在安全环境下可读写。


3.3 Flash操作接口适配

在yoc/partition_flash.h文件中,定义了一个partition_flash_ops_t结构体,有自定义Flash操作接口的用户可以实现这个结构体的操作接口,并通过partition_flash_register接口进行注册。


注意:系统默认带有一套基于设备驱动框架的Flash接口。如果是无操作系统的应用,则需要用户自己实现一套接口,并注册。


以下为在BOOT方案中实现Flash接口的一个例子:


#include <drv/spiflash.h>
#include <yoc/partition_flash.h>
static csi_spiflash_t spiflash_hd;
static csi_spiflash_info_t spiflash_info;
static int _boot_flash_info_get(void *handle, partition_flash_info_t *info)
{
    if (info != NULL) {
        csi_error_t ret = csi_spiflash_get_flash_info(&spiflash_hd, &spiflash_info);
        if (ret != CSI_OK) {
            return -1;
        }
        info->start_addr = spiflash_info.xip_addr;
        info->sector_size = spiflash_info.sector_size;
        info->sector_count = spiflash_info.flash_size / spiflash_info.sector_size;
        return 0;
    }
    return -1;
}
static int _boot_flash_read(void *handle, uint32_t addr, void *data, size_t data_len)
{
    int ret = csi_spiflash_read(&spiflash_hd, addr - spiflash_info.xip_addr, data, data_len);
    if (ret < 0) {
        return -1;
    }
    return 0;
}
static int _boot_flash_write(void *handle, uint32_t addr, void *data, size_t data_len)
{
    int ret = csi_spiflash_program(&spiflash_hd, addr - spiflash_info.xip_addr, data, data_len);
    if ( ret < 0) {
        return -1;
    }
    return 0; 
}
static int _boot_flash_erase(void *handle, uint32_t addr, size_t len)
{
    csi_error_t ret;
    if (len % spiflash_info.sector_size) {
        len = (len / spiflash_info.sector_size + 1) * spiflash_info.sector_size;
    }
    ret = csi_spiflash_erase(&spiflash_hd, addr, len);
    if (ret) {
        return ret;
    }
    return 0;
}
static const partition_flash_ops_t g_flash_ops = {
    .open = NULL,
    .close = NULL,
    .info_get = _boot_flash_info_get,
    .read = _boot_flash_read,
    .write = _boot_flash_write,
    .erase = _boot_flash_erase
};
int boot_flash_init(void)
{
    csi_spiflash_qspi_init(&spiflash_hd, 0, NULL);
    partition_flash_register((void *)&g_flash_ops);
    return 0;
}


04 配置示例

下面介绍几种方案的配置。主要是BOOT、TEE、APP三种类型的方案。其中BOOT、TEE是无操作系统的,APP是带操作系统的。


4.1 BOOT方案

BOOT方案只涉及到package.yaml的配置。


4.1.1 非安全方案


def_config:
  CONFIG_PARITION_NO_VERIFY: 1
  CONFIG_NOT_SUPORRT_SASC: 1


4.1.2 安全方案


def_config:
  CONFIG_PARITION_NO_VERIFY: 0
  CONFIG_NOT_SUPORRT_SASC: 0


4.2 TEE方案

TEE方案只涉及到package.yaml的配置。

def_config:
  CONFIG_PARITION_NO_VERIFY: 0
  CONFIG_NOT_SUPORRT_SASC: 0


4.3 APP方案

APP方案涉及到package.yaml和config.yaml的配置。


4.3.1 非安全方案

非安全的方案不会对分区进行验签,没有TEE。


  • config.yaml分区配置表中partitions字段的配置
partitions:
  - { name: bmtb,   address: 0x8000000, size: 0x001000 }
  - { name: boot,   address: 0x8001000, size: 0x020000 }
  - { name: imtb,   address: 0x8031000, size: 0x002000 }
  - { name: prim,   address: 0x8033000, load_addr: 0x18010000, size: 0x300000, update: FULL}
  - { name: kv,     address: 0x8633000, size: 0x004000 }
  - { name: lpm,    address: 0x8637000, size: 0x020000 }
  - { name: misc,   address: 0x8657000, size: 0x400000 }


  • 应用方案的package.yaml文件
def_config:
  CONFIG_PARITION_NO_VERIFY: 1
  CONFIG_NOT_SUPORRT_SASC: 1



4.3.2 安全方案

安全方案需要对分区进行验签,需要有TEE的系统。当然还需要有OTP或者eFuse来保证验签公钥的安全可靠性。


  • config.yaml分区配置表中partitions字段的配置
partitions:
  - { name: bmtb,   address: 0x8000000, size: 0x001000 }
  - { name: boot,   address: 0x8001000, size: 0x020000 }
  - { name: tee,    address: 0x8021000, load_addr: 0x18000000, size: 0x010000, verify: true }
  - { name: imtb,   address: 0x8031000, size: 0x002000 }
  - { name: prim,   address: 0x8033000, load_addr: 0x18010000, size: 0x300000, verify: true, update: FULL}
  - { name: kv,     address: 0x8633000, size: 0x004000 }
  - { name: lpm,    address: 0x8637000, size: 0x020000 }
  - { name: misc,   address: 0x8657000, size: 0x400000 }


跟非安全方案相比较,主要是多了TEE系统分区,然后对tee和prim分区进行验签配置。对需要验签的分区加上verify: true,打包工具会把这个字段保存到imtb表中,由bootloader去判断这个分区是否需要验签。


  • 应用方案的package.yaml文件
def_config:
  CONFIG_PARITION_NO_VERIFY: 0
  CONFIG_NOT_SUPORRT_SASC: 0


05 下期预告

PARTITION组件是一个轻量级的分区管理组件。用户可以根据宏进行灵活的配置,打开或者关闭某些功能。是一个适用于RTOS系统或者裸系统的功能组件。下期内容,我们将为大家介绍YoC的KV组件,欢迎大家持续关注RISC-V系列内容。



相关文章
|
2月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
187 2
|
1月前
|
前端开发 JavaScript 开发者
揭秘前端高手的秘密武器:深度解析递归组件与动态组件的奥妙,让你代码效率翻倍!
【10月更文挑战第23天】在Web开发中,组件化已成为主流。本文深入探讨了递归组件与动态组件的概念、应用及实现方式。递归组件通过在组件内部调用自身,适用于处理层级结构数据,如菜单和树形控件。动态组件则根据数据变化动态切换组件显示,适用于不同业务逻辑下的组件展示。通过示例,展示了这两种组件的实现方法及其在实际开发中的应用价值。
35 1
|
2月前
|
存储 JavaScript 前端开发
Vue3权限控制全攻略:路由与组件层面的用户角色与权限管理方法深度解析
Vue3权限控制全攻略:路由与组件层面的用户角色与权限管理方法深度解析
146 2
|
2月前
|
机器学习/深度学习 编解码 算法
深入解析MaxFrame:关键技术组件及其对视频体验的影响
【10月更文挑战第12天】随着流媒体服务和高清视频内容的普及,用户对于视频质量的要求越来越高。为了满足这些需求,许多技术被开发出来以提升视频播放的质量。其中,MaxFrame是一种旨在通过一系列先进的图像处理算法来优化视频帧的技术。本文将深入探讨构成MaxFrame的核心组件,包括运动估计、超分辨率重建以及时间插值算法,并讨论这些技术如何协同工作以改善视频播放效果。
43 1
|
28天前
|
机器学习/深度学习 自然语言处理 数据管理
GraphRAG核心组件解析:图结构与检索增强生成
【10月更文挑战第28天】在当今数据科学领域,自然语言处理(NLP)和图数据管理技术的发展日新月异。GraphRAG(Graph Retrieval-Augmented Generation)作为一种结合了图结构和检索增强生成的创新方法,已经在多个应用场景中展现出巨大的潜力。作为一名数据科学家,我对GraphRAG的核心组件进行了深入研究,并在此分享我的理解和实践经验。
52 0
|
2月前
|
测试技术 数据库 Android开发
深入解析Android架构组件——Jetpack的使用与实践
本文旨在探讨谷歌推出的Android架构组件——Jetpack,在现代Android开发中的应用。Jetpack作为一系列库和工具的集合,旨在帮助开发者更轻松地编写出健壮、可维护且性能优异的应用。通过详细解析各个组件如Lifecycle、ViewModel、LiveData等,我们将了解其原理和使用场景,并结合实例展示如何在实际项目中应用这些组件,提升开发效率和应用质量。
48 6
|
3月前
|
存储 开发框架 数据可视化
深入解析Android应用开发中的四大核心组件
本文将探讨Android开发中的四大核心组件——Activity、Service、BroadcastReceiver和ContentProvider。我们将深入了解每个组件的定义、作用、使用方法及它们之间的交互方式,以帮助开发者更好地理解和应用这些组件,提升Android应用开发的能力和效率。
211 5
|
16天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
45 2
|
2月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
70 0
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
57 0

推荐镜像

更多