Partition Table Syntax Version 3.0

This document describes the design, usage, and migration guide for the partition table v3 (in short ptab v3) format in the SiFli SDK.

Overview

ptab v3 is the next-generation partition table format in the SiFli SDK and uses YAML. Compared with the v1/v2 JSON formats, it offers several advantages:

  • Clearer semantics: uses type/subtype instead of the more complex tags mechanism

  • Abstract storage regions: references logical storage regions via the region field, decoupling layout from chip topology

  • Unified execution address: specifies execution/copy destination clearly via exec: {region, offset}

  • Automatic macro generation: generates C macro definitions from name fields

  • Improved validation: built-in validators check partition correctness

Unlike ptab v1/v2, ptab v3 is closely integrated with the build system and directly generates ftab.bin, ptab.h, and jinja2-based link script fragments.

File format

Basic structure

The YAML example below shows the fully expanded form to illustrate the semantics for each partition type. In real projects, ptab.yaml can omit partitions that the build system can deterministically infer; only partitions that differ from defaults need to be explicitly declared.

version: 3
chip: SF32LB525UC6

memory:
  - mpi: mpi2
    type: nand
    size: 16777216 # 16MB

partitions:
  # Flash Table (ftab)
  - name: flash_table
    type: ftab
    region: mpi2
    offset: 0
    size: 32KB

  # Calibration data
  - name: calibration
    type: data
    subtype: calibration
    region: mpi2
    offset: 0x8000
    size: 8KB

  # Bootloader (stored in Flash, executed in RAM)
  - name: bootloader
    type: bootloader
    region: mpi2
    offset: 0x80000
    size: 64KB
    exec:
      region: hpsys_ram
      offset: 0x20000
    core: HCPU

  # Main application
  - name: hcpu_flash_code
    type: app
    subtype: factory
    region: mpi2
    offset: 0xA0000
    size: 4MB
    exec:
      region: mpi1
      offset: 0
    core: HCPU

  # DFU application
  - name: dfu_flash_code
    type: app
    subtype: dfu
    region: mpi2
    offset: 0x4A0000
    size: 512KB
    exec:
      region: mpi1
      offset: 0
    core: HCPU

  # DFU info region
  - name: dfu_info_region
    type: data
    subtype: raw
    region: mpi2
    offset: 0x520000
    size: 128KB

  # DFU download region
  - name: dfu_download_region
    type: data
    subtype: raw
    region: mpi2
    offset: 0x780000
    size: 1152KB

  # Filesystem region
  - name: fs_region
    type: data
    subtype: filesystem
    region: mpi2
    offset: 0x8A0000
    size: 4MB

  # KVDB for DFU
  - name: dfu
    type: data
    subtype: flashdb_kv
    region: mpi2
    offset: 0xCA0000
    size: 16KB

  # KVDB for BLE
  - name: ble
    type: data
    subtype: flashdb_kv
    region: mpi2
    offset: 0xCA4000
    size: 16KB

  # PSRAM data region
  - name: psram_data
    type: data
    subtype: ram
    region: mpi1
    offset: 0x400000
    size: 4MB

  # HCPU RAM data (shared with bootloader exec)
  - name: hcpu_ram_data
    type: data
    subtype: ram
    region: hpsys_ram
    offset: 0
    size: 128KB

  # Bootloader RAM data
  - name: bootloader_ram_data
    type: data
    subtype: ram
    region: hpsys_ram
    offset: 0x40000
    size: 64KB

  # LPSYS RAM
  - name: lpsys_ram
    type: data
    subtype: ram
    region: lpsys_ram
    offset: 0
    size: 24KB

Top-level fields

Field

Type

Required

Description

version

int

yes

Must be 3

chip

string

yes

Chip model, e.g. SF32LB525UC6, SF32LB52JUD6

memory

list

no

Storage region definitions

partitions

list

yes

Partition list

Memory definitions

memory defines external storage devices such as NAND or NOR.

Field

Type

Required

Description

name

string

yes

MPI or SDMMC interface name, e.g. mpi2, sdmmc1

type

string

yes

Storage type: nand, nor, sd

size

string

yes

Size; supports 0x prefix and KB/MB suffix

block_size

string

no

NAND erase block size: 128KB (default) or 256KB; only allowed on NAND memory and consumed when NAND is the boot storage

For SD/MMC (eMMC/SD card) define the storage in memory and reference it in partitions via region.

Field

Type

Required

Description

sdmmc

string

yes

SDMMC storage name, e.g. sdmmc1

size

string

yes

Storage size; supports 0x prefix and KB/MB suffix

Partition fields

Field

Type

Required

Description

name

string

yes

Partition name, used for generating C macros

type

string

yes

Partition type

subtype

string

no

Partition subtype

region

string

yes

Storage region (logical name)

offset

int/string

yes

Region offset; supports 0x and KB/MB suffixes

size

int/string

yes

Partition size

exec

dict

no

Execution address definition

core

string

no

Running core: HCPU or LCPU

attrs

dict

no

Custom attributes

exec field

exec specifies where code should be executed from if XIP is not possible (copy-to-execute).

Field

Type

Required

Description

region

string

yes

Execution region (logical name)

offset

int/string

yes

Execution region offset; supports 0x and KB/MB suffixes

Example: if the main program is stored in NAND and must be copied to PSRAM for execution:

- name: hcpu_flash_code
  type: app
  subtype: factory
  region: mpi2
  offset: 0xA0000
  size: 4MB
  exec:
    region: mpi1
    offset: 0
  core: HCPU

Partition type definitions

type values

Value

Meaning

ftab

Flash Table (the partition table itself)

bootloader

Bootloader

app

Application

data

Data partition

subtype values

When type=app:

Value

Meaning

factory

Factory (primary) application

dfu

DFU upgrade application (runs independently)

When type=data:

Value

Meaning

flashdb_kv

FlashDB KV database (generates KVDB_* macros and participates in FAL_PART_TABLE)

filesystem

Filesystem (generates FS_REGION_* macros and participates in FAL_PART_TABLE)

littlefs

LittleFS (for future uses)

fat / fatfs

FAT filesystem (for future uses)

ram

RAM data area (can be omitted for default hpsys_ram/lpsys_ram)

calibration

Calibration data

raw

Raw data area for application-managed storage

int_res

Internal resources: linked into the final ELF and sliced by section names

Default partition inference

The ptab v3 parser will auto-fill certain system default partitions. This lets board-level ptab.yaml omit defaults and only declare differences.

  • SF32LB52

    • When boot storage is NOR/NAND/SDMMC, flash_table and bootloader are inferred from the HCPU factory app storage region.

    • When boot storage is NAND, a factory_data partition (alias FACTORY_DATA) is reserved by default: offset = 2 * block_size, size = block_size. If memory.block_size is not explicitly set, NAND block size defaults to 128KB; if explicitly set to 256KB the defaults follow accordingly.

    • When boot storage is SDMMC, mbr (alias MBR, offset=0x0, size=0x1000) and factory_data (alias FACTORY_DATA, offset=0x41000, size=0x20000) are reserved.

    • If RAM layout is unchanged, hcpu_ram_data, bootloader_ram_data, and lpsys_ram can be omitted.

  • SF32LB57

    • flash_table and bootloader are inferred from the HCPU factory app storage region. Boot storage can be NOR (mpi2 or mpi3), NAND (mpi3 only), or SD (sdmmc1 or sdmmc2).

    • NOR: flash_table is at offset=0x0, size=0x8000; bootloader is at offset=0x10000, size=0x10000, with exec on hpsys_ram at offset=0x20000. AUTO_FLASH_MAC_ADDRESS is not injected.

    • NAND: flash_table is at offset=0x0, size=0x8000 (the ftab partition only covers the live table, not a whole erase block); factory_data (alias FACTORY_DATA) is at offset = 2 * block_size, size = block_size; bootloader is at offset = 4 * block_size, size=0x10000. block_size follows the block_size field of the boot memory entry; 128KB is used when it is not set. AUTO_FLASH_MAC_ADDRESS is injected with the SBUS base address of the boot region (mpi3 → 0x64000000, mpi2 → 0x62000000).

    • SD (sdmmc1 / sdmmc2): mbr (alias MBR, offset=0x0, size=0x1000), flash_table (offset=0x1000, size=0x8000), factory_data (offset=0x41000, size=0x20000), and bootloader (offset=0x61000, size=0x10000) are reserved. AUTO_FLASH_MAC_ADDRESS is not injected.

    • The default bootloader size is 64KB.

    • If RAM layout is unchanged, hcpu_ram_data (hpsys_ram offset=0, size=0x6FC00) and bootloader_ram_data (hpsys_ram offset=0x40000, size=0x10000) can be omitted.

    • SF32LB57 does provide LPSYS RAM, but ptab v3 does not generate lpsys_ram by default because the default build does not enable LCPU; an explicitly declared lpsys_ram partition is preserved.

    • acpu and acpu_ram_data are not injected by default. They are generated into the board ptab.yaml by new-board when with_acpu=true.

  • SF32LB56 / SF32LB58

    • flash_table and bootloader located on internal mpi5 can be omitted.

  • psram_data / psram_data2

    • On-chip SiP PSRAM windows are generated automatically from the SiliconSchema and exec reserved regions and need not be declared in board YAML.

Notes:

  • Defaults only apply when a partition is missing; explicitly declared partitions always take precedence.

  • If a project customizes RAM layout (e.g. shrinks hcpu_ram_data to match a linker script), that partition must be kept.

  • Project-level ptab.overlay.yaml can still override defaults; overlay sees the filled-default set before applying overrides.

Regions (region)

Supported region names

Region

Description

External storage

Defined in memory, e.g. mpi1, mpi2, sdmmc1

hpsys_ram

HPSYS RAM

lpsys_ram

LPSYS RAM (not generated by default on SF32LB57)

Address resolution

Each region maps to two addresses:

  • SBUS address (storage address): used for DMA and flashing; also valid as an execution address

  • CBUS address (XIP address): execute-in-place view of NOR/PSRAM

For PSRAM, 0x10xxxxxx is only the HCPU-side alias of the memory mapped at SBUS 0x60xxxxxx. An ACPU image cannot fetch through that alias, so its execution address always uses the SBUS view of the region, which is also the flash table xip_base and the 2nd bootloader’s copy target.

Address mapping comes from tools/SiliconSchema/common/mpi/<chip>/mpi.yaml.

Macro generation rules

Basic macros

Each partition automatically generates the following macros (where <NAME> is the partition name uppercased):

#define <NAME>_START_ADDR    (0x...)  // SBUS address
#define <NAME>_SIZE          (0x...)  // partition size
#define <NAME>_OFFSET        (0x...)  // region offset

If the partition region maps to a known storage type, an additional macro is generated:

#define <NAME>_MEM_TYPE      HAL_MEM_TYPE_...

Possible memory type constants:

  • HAL_MEM_TYPE_NOR_FLASH

  • HAL_MEM_TYPE_NAND_FLASH

  • HAL_MEM_TYPE_SDMMC_STORAGE

  • HAL_MEM_TYPE_PSRAM

For on-chip RAM regions that have no HAL memory type, <NAME>_MEM_TYPE is omitted.

Special macros

CODE_START partitions:

When type=app and subtype=factory, the generator will emit:

#define CODE_START_ADDR  (0x...)
#define CODE_SIZE        (0x...)

CODE_START_ADDR corresponds to the execution address specified by exec. If exec is absent, the storage region is used and resolved with the same rule. ACPU images always use the SBUS view; HCPU/LCPU use the SBUS view for RAM/NAND and default to the CBUS/XIP view for NOR/PSRAM. For ACPU, ACPU_CODE_REGION<N>_EXEC_START_ADDR therefore always equals ACPU_CODE_REGION<N>_EXEC_SBUS_START_ADDR.

If macros such as HCPU_FLASH_CODE or FLASH_BOOT_LOADER are generated from execution-address compatibility rules and also include _MEM_TYPE, the _MEM_TYPE follows the final execution region rather than the storage region. If the execution region is on-chip RAM, the _MEM_TYPE will not be generated.

Filesystem partitions:

When type=data and subtype is one of filesystem/littlefs/fat/fatfs/flashdb, the following macros are emitted:

#define FS_REGION_START_ADDR  (0x...)
#define FS_REGION_SIZE        (0x...)
#define FS_REGION_OFFSET      (0x...)
#define FS_REGION_MEM_TYPE    HAL_MEM_TYPE_...

FlashDB KV partitions:

When type=data and subtype=flashdb_kv, KVDB macros are generated (where <NAME> is the uppercase partition name, which also becomes the FlashDB database name and FAL partition name, e.g. dfu, ble):

#define KVDB_<NAME>_REGION_START_ADDR  (0x...)
#define KVDB_<NAME>_REGION_OFFSET  (0x...)
#define KVDB_<NAME>_REGION_SIZE    (0x...)
#define KVDB_<NAME>_REGION_MEM_TYPE HAL_MEM_TYPE_...

FAL_PART_TABLE:

ptab.h will auto-generate FAL_PART_TABLE containing the following partitions:

  • type=data, subtype=flashdb_kv

  • type=data, subtype=filesystem

  • type=app where subtype != ex

Excluded from auto-inclusion:

  • type=ftab

  • type=bootloader

  • type=data where subtype is raw/ram/calibration/int_res

  • type=app where subtype=ex

FAL partition names use the partition name directly and do not map legacy names like main, dfu_code, or fs_root.

Example generation:

#define FAL_PART_TABLE \\
{ \\
    {FAL_PART_MAGIC_WORD, "hcpu_flash_code", NOR_FLASH5_DEV_NAME, 0x00020000, 0x00200000, 0}, \\
    {FAL_PART_MAGIC_WORD, "dfu_flash_code", NOR_FLASH5_DEV_NAME, 0x00220000, 0x00080000, 0}, \\
    {FAL_PART_MAGIC_WORD, "fs_region", NOR_FLASH5_DEV_NAME, 0x00600000, 0x00100000, 0}, \\
    {FAL_PART_MAGIC_WORD, "<name>", NOR_FLASHx_DEV_NAME, <offset>, <size>, 0}, \\
    ... \\
}

Device names are determined by the storage region, not by exec:

  • mpi1..mpi5 → NOR_FLASH1_DEV_NAME … NOR_FLASH5_DEV_NAME

  • sdmmc1 → SDMMC1_DEV_NAME

  • sdmmc2 → SDMMC2_DEV_NAME

Build system integration

Auto-detection

The build system detects ptab format in this order:

  1. Look for ptab.yaml (v3)

  2. If absent, fall back to ptab.json (v1/v2)

Search priority:

  1. $BSP_ROOT/<board>/

  2. $BSP_ROOT/<chip>/

  3. $BSP_ROOT/

  4. customer/boards/<board>/

Project-level partition overlays

If a project only needs small adjustments, use ptab.overlay.yaml rather than copying the full board ptab.yaml.

Overlay filenames supported:

  • <project>/<chip>/ptab.overlay.yaml

  • <project>/<board>/ptab.overlay.yaml

Notes:

  • <chip> uses CHIP.lower() from board rtconfig.py, e.g. sf32lb52x

  • <board> uses the full board name including core suffix, e.g. sf32lb52-lcd_n16r8_hcpu

  • Board overlay has higher priority than chip overlay

Overlay files should only contain a top-level partitions field. Example:

partitions:
  - op: override
    name: fs_region
    size: 5MB

  - op: add
    name: log_region
    type: data
    subtype: raw
    region: mpi2
    offset: 0x00F00000
    size: 64KB

op is optional but recommended for clarity. Meaning:

  • op: override modifies an existing partition

  • op: add adds a new partition

  • If op is omitted: existing name → override, missing name → add

Restrictions:

  • Overlay supports only partition-level changes; it cannot change memory, chip, or version

  • Overlay cannot delete partitions

  • Overlay applies only to board-level ptab.yaml (v3); it cannot be layered over ptab.json

  • If the board still uses ptab.json (v1/v2) and no full ptab.yaml is found in the project, the build system will ignore ptab.overlay.yaml, emit a warning, and continue with legacy PTAB behavior

  • If a project provides a full ptab.yaml / ptab.json, it must not also use ptab.overlay.yaml

When processing overlays the build system prints a summary via rich and writes ptab.effective.yaml in the build directory for inspection.

Note:

If an overlay is ignored because the board uses ptab.json, ptab.effective.yaml will not be generated. That warning means the build falls back to v1/v2 behavior, not that the overlay has been applied.

Generated artifacts

Artifact

Description

ptab.h

C header with partition macros

ftab.bin

Binary Flash Table used by the bootloader

link_copy.lds / link_copy.sct

GCC / Keil link scripts

ptab.effective.yaml

Final effective PTAB YAML when overlay is applied

ptab v3 and custom_mem_map.h

Projects using ptab v3 do not need to maintain board-level custom_mem_map.h. Prefer using the generated ptab.h as the source of partition macros.

Migration steps to ptab v3:

  1. Convert board ptab.json to ptab.yaml.

  2. Remove board-level custom_mem_map.h (e.g. customer/boards/<board>/{hcpu,lcpu,acpu}/custom_mem_map.h).

  3. Clean any existing build_xxx directories and rebuild.

Notes:

  • Do not manually define FAL_PART_TABLE in board headers; ptab.h auto-generates it based on flashdb_kv/filesystem/app(subtype != ex) partitions.

  • If the board custom_mem_map.h is not removed, the build may still generate build_xxx/custom_mem_map.h, leading to FAL_PART_TABLE redefined warnings.

  • Deleting board headers while leaving old build_xxx/custom_mem_map.h files may also trigger legacy warnings; clean build directories to avoid this.

app/ex resource partition artifacts (ptab v3 + GCC/Keil)

ptab v3 uses type: app with subtype: ex to describe resource partitions. The build system generates linker script fragments per resource partition: GCC assigns each resource partition a MEMORY region and emits an output section .<name> (lowercase), Keil produces LR_<NAME> / ER_<NAME> areas. Both toolchains normalize artifact names under output/.

GCC default collection rule:

.<name> : { *(.<NAME>*) } > <NAME>

If a partition declares sections, the build will also collect the specified input sections or object + section selectors in addition to the default rule.

Output files under each build directory’s output/:

  • Code image (ELF-exported code excluding all .<resource_name> sections):

    • Single final binary: build_xxx/output/main.bin, build_xxx/output/main.hex

    • When code image + one or more app/ex resource images are present: build_xxx/output/main.app.bin, build_xxx/output/main.app.hex

    • Project-named variants: build_xxx/<proj>/output/<proj>.bin or .../<proj>.app.bin

  • Resource images (one file per app/ex partition):

    • Filenames use the partition name verbatim (not uppercased)

    • Examples:

      • build_xxx/output/main.hcpu_flash2_img.bin

      • build_xxx/output/main.hcpu_flash2_font.bin

    • Corresponding .hex files are also produced

If a resource partition has no corresponding input section or the section is empty, the build skips generating that partition’s main.<partition_name>.bin/.hex without error.

Avoid naming app/ex partitions app to prevent filename collisions on case-insensitive filesystems.

Multiple ACPU code images (ptab v3 + GCC/Keil)

One ACPU project may need several code images out of a single ELF when their execution regions are not contiguous. Declare every image after the first as its own type: app, subtype: factory, core: ACPU partition that names the ELF output section holding its code:

- name: acpu2                  # must differ from any project (env) name
  type: app
  subtype: factory             # same kind as the first image: registered in the flash
                               # table and copied into its execution region
  core: ACPU
  region: mpi4
  offset: 0x00E7C000           # storage region -> flash table base / download address
  size: 0x00100000
  exec:
    region: psram1             # execution region -> flash table xip_base / link address
    offset: 0x00400000
  sections:
    - section: .rom2           # ELF output section holding this image's code
  aliases:
    - ACPU_CODE_LOAD_REGION2   # optional legacy alias; must match .rom<N> if present

The .rom<N> section name (N >= 2) is the explicit binding between the partition and its image: it selects the ELF content, names the link script section and sets the artifact suffix, using the same naming as the v1/v2 multi-image flow and the embedded LCPU flow. The first image keeps its code in the code artifact and must not declare a .rom<N> section; validate_ptab_v3.py enforces exactly one such first image and distinct N. Both the link script and the ACPU_CODE_REGION<N>_* macros take N from the .rom<N> section, so the alias is optional and, if present, must match that N.

The ACPU link.jinja2 / link.sct.jinja2 templates emit one extra memory region per image (GCC ACPU_ROM<N>, holding the .rom<N> output section) or one load/execution region per image (Keil LR_IROM<N> / ER_IROM<N>), linked at the SBUS view of the partition exec address. Each extra image is then downloaded to its partition region/offset and copied into its execution region by the 2nd bootloader; the copy is skipped when both addresses are identical (execute in place). The flash table stores the partition size as the image length, so the execution region must be able to hold size bytes. The first ACPU image follows the same rule; HCPU/LCPU images keep executing in place from the CBUS/XIP view of NOR/PSRAM.

Artifacts under the ACPU project’s output/ directory:

  • Code image (first ACPU image): build_xxx/acpu/output/acpu.ER_IROM1.bin

  • Extra images: build_xxx/acpu/output/acpu.ER_IROM2.bin (and the .hex twins)

Up to three extra images are supported in total: they share the extended flash table slots DFU_FLASH_HCPU_EXT2 / DFU_FLASH_LCPU_EXT1 / DFU_FLASH_LCPU_EXT2 (flash ids 11/12/13) with every other extra type: app partition, and they are assigned in image order.

Notes:

  • Currently supported for SF32LB58X only: the other chips have no Jinja2 ACPU template and their bootloaders do not walk all extended flash table slots yet.

  • The project must build the ACPU image (an ACPU child project); images provided through AddCustomImg are not covered.

ftab.bin generation

In v3, ftab.bin is generated directly by a Python script rather than building an ftab subproject:

Generating build_xxx/ftab.bin ...
Generated ftab.bin: build_xxx/ftab.bin (11280 bytes)

validate_ptab_v3.py

Validate a ptab v3 file for correctness:

python tools/build/validate_ptab_v3.py customer/boards/<board>/ptab.yaml

Validation checks include:

  • Partition name format

  • Type/subtype validity

  • Region name validity

  • Partition overlap detection

  • bootloader partition uniqueness

sdk.py ptab-export

To inspect the final effective PTAB YAML for a project run:

sdk.py ptab-export --board=<board_name>

Common usage:

sdk.py ptab-export --board=sf32lb52-lcd_n16r8_hcpu
sdk.py ptab-export --board=sf32lb52-lcd_n16r8_hcpu --output /tmp/ptab.effective.yaml
sdk.py ptab-export --strict

Notes:

  • By default, the final YAML is printed to stdout.

  • --output writes the effective YAML to a file

  • --strict treats warnings as failures

  • This command uses the same PTAB parsing and overlay merge logic as the build

FAQ

Q: How do I add custom macros?

Use the attrs field:

- name: my_partition
  type: data
  subtype: flashdb_kv
  region: mpi2
  offset: 0x100000
  size: 64KB
  attrs:
    MY_CUSTOM_MACRO: 0x12345678

This generates:

#define MY_CUSTOM_MACRO  (0x12345678)

Q: How do ptab v1/v2 tags map to v3?

v1/v2 tags

v3 mapping

FLASH_TABLE

type: ftab

FLASH_BOOT_LOADER

type: bootloader

FS_REGION

type: data, subtype: filesystem

KVDB_*

type: data, subtype: flashdb_kv

app_img

type: app

app_exec

use exec: {region, offset} when XIP is not possible or a fixed exec address is required

Change history

Version

Date

Notes

v3.5

2026-10

Added SF32LB57 default partition inference for NOR/NAND/SD boot storage, the NAND AUTO_FLASH_MAC_ADDRESS base address, and the absence of a default lpsys_ram; noted that acpu / acpu_ram_data are generated by new-board when with_acpu=true

v3.4

2026-04

FAL_PART_TABLE automatically includes flashdb_kv, filesystem and app(subtype != ex) partitions, and adds mpi5 / sdmmc mapping rules

v3.3

2026-03

Added default partition inference rules; allowed omission of default flash_table / bootloader / some RAM partitions

v3.2

2026-03

Added project-level ptab.overlay.yaml, sdk.py ptab-export, and ptab.effective.yaml export

v3.1

2026-03

Clarified relationship between ptab v3 and custom_mem_map.h, and FAL_PART_TABLE redefined warning reasons and fixes

v3.0

2024-12

Initial release; YAML format; removed ftab subproject