DirectXIP on a single fixed execution address via Realtek Ameba RSIP — how should the app entry hand-off look? #116773
minyuan-xue
started this conversation in
RFC
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
TL;DR
Ameba SoCs (
rtl8721dx/rtl8721f) have a flash-side hardware block calledRSIP ("Runtime Secure Image Protection"). Per region, it independently supports
address remap (pointing a fixed logical/virtual window at an arbitrary physical flash
offset) and OTF AES decryption keyed on that logical address, using a key in OTP. I'm
using the remap side here to run a single application build from either slot.
Together these let me run DirectXIP from a single application build linked at one fixed
logical address, with RSIP remapping whichever slot MCUboot picks onto that window — no
per-slot build, no position-independent code.
Most of this reuses existing generic MCUboot/Zephyr mechanisms as-is. Two pieces touch
generic code, and those are what I'd like feedback on:
do_boot()jump inboot/zephyr/main.cneeds a vendor#ifdef, because theentry address is a fixed logical address, not
flash_base + br_image_off.boot_fetch_active_slot()and friends), gated on RAM-loadonly upstream, gets generalized behind a new hidden Kconfig symbol so fixed-remap
DirectXIP can reuse it. RAM-load behavior is unchanged, but it's a refactor of three
generic files.
Details and questions below.
Goal
Run
BOOT_DIRECT_XIP(and..._WITH_REVERT) such that:that slot's physical offset before the jump;
This is Ameba-specific only in that "DirectXIP ⇒ one fixed-address build" is true because
RSIP's remap exists. A generic DirectXIP target instead links a distinct per-slot variant
and resolves the address at compile time.
What maps cleanly onto existing mechanisms
1. Winning slot, bootloader → SoC remap code.
boot_go()already records the running slot in shared data (BLINFO_RUNNING_SLOTTLV) oncethe retention backend is enabled. I default that backend on for Ameba DirectXIP:
2. Programming RSIP before the jump.
The SoC's
boot_prepare()re-points RSIP at the winning slot. I call it from the existing,payload-less
mcuboot_status_change(BOOTABLE_IMAGE_FOUND)hook, readingBLINFO_RUNNING_SLOTback out inside the SoC hook — so nothing vendor-specific lands ingeneric
main.cfor this part.3. Telling the app-side DFU stack the slot is runtime-resolved.
Upstream already does this for RAM load:
boot_fetch_active_slot()reads the same TLV, andimg_mgmt/flash_img/ the MCUboot DFU shim take a runtime path instead of thecompile-time
zephyr,code-partition— but gated directly onCONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD[_WITH_REVERT], duplicated across three files.Fixed-remap DirectXIP has the same need, so instead of adding
|| MCUBOOT_AMEBA_...at eachsite, I named the concept:
The three sites switch from
#if defined(...RAM_LOAD...)to#if defined(CONFIG_MCUBOOT_RUNTIME_ACTIVE_SLOT). RAM-load behavior is unchangedbyte-for-byte — this is the larger of the two generic-code changes, so I'd especially like a
read on it (see the questions below).
Apart from that refactor, nothing vendor-specific lands in generic sources: it's all in the
SoC directory plus two Ameba-conditioned Kconfig
defaults.The one part I can't do cleanly:
do_boot()'s entrydo_boot()computes the jump target asflash_base + rsp->br_image_off + hdr_size. That'swrong here: I must enter at the fixed logical address RSIP was just pointed at, and once
OTF decryption is on, the vector table is only decodable there — the physical
br_image_offis exactly what I don't want.do_boot()isstaticwith several arch-specific#ifbranches and no override hook, so mychange adds one more:
Structurally this is the same kind of "entry address computed differently on this platform"
case as
MCUBOOT_RAM_LOAD— but it's still a vendor symbol in generic code, which I'd ratheravoid if there's a cleaner path.
Questions for the community
Is a vendor
#ifdefbranch indo_boot()acceptable here, given it's structurallythe same kind of case as
MCUBOOT_RAM_LOAD? If so, would a more generic name thanCONFIG_MCUBOOT_AMEBA_FIXED_XIP_ADDRbe preferred (e.g. aCONFIG_BOOT_XIP_FIXED_ADDRESS/ "remapped DirectXIP" concept other flash-remap SoCs could reuse)?
Is there an existing extension point I've overlooked for overriding the final jump
target?
boot_go_hook()looked promising at first glance, but it runs beforeboot_go()'s own slot-selection/validation logic: returning success from it skipsboot_go()entirely and requires the hook to have already filled inrspitself. There'sno way to let MCUboot's normal selection run first and only override the entry address
afterward — using it here would mean reimplementing
boot_go()'s selection logic insidethe hook rather than reacting to its result.
do_boot()itself isstaticandnon-overridable. A weak
do_boot()or aboot_jump_hook(rsp)— invoked after slotselection, right before the jump — would let this live entirely in the SoC layer. Is there
appetite for adding one?
Is generalizing
boot_fetch_active_slot()behindMCUBOOT_RUNTIME_ACTIVE_SLOTtheright move? My change replaces the three
...MODE_RAM_LOAD...guards with one hiddensymbol meaning "running slot is runtime-resolved," defaulted
yfor RAM load (no behaviorchange) and selectable by fixed-remap DirectXIP platforms. Welcome abstraction, or would
maintainers prefer plain
|| <ameba symbol>at each site instead?Does the blinfo/retention approach for "winning slot → SoC remap" match the intended
use of shared data, or is there a more idiomatic channel for a bootloader-internal
pre-jump consumer (as opposed to the app-side blinfo reader it's normally used for)?
Defaulting
BOOT_SHARE_BACKEND_RETENTIONinside the genericBOOT_SHARE_BACKENDchoice — I added
default BOOT_SHARE_BACKEND_RETENTION if SOC_FAMILY_REALTEK_AMEBA && BOOT_DIRECT_XIPthere rather than in a board/SoC Kconfig fragment on purpose: achoice's conditional default has to live inside the choice block, and the choice plusits members are declared only in
boot/zephyr/Kconfig. Our SoC Kconfig is also parsed inthe application image's tree, where those symbols don't exist, so referencing them there —
or reopening the choice in a board
Kconfig.defconfigthat both images parse — isinvalid. This mirrors the existing
default MCUBOOT_BOOTLOADER_MODE_SWAP_USING_MOVE if SOC_FAMILY_ESPRESSIF_ESP32inmodules/Kconfig.mcuboot, so I followed that precedent. Shout if you'd prefer it drivensome other way.
Status
This works end-to-end on the AmebaDplus EVB (
rtl872xda_evb): DirectXIP v0→v1→v2 upgradeover MCUmgr is validated. I'm preparing a PR, but would rather settle the two generic-code
questions (the
do_boot()branch and theMCUBOOT_RUNTIME_ACTIVE_SLOTrefactor) here first.Happy to reshape the approach based on feedback.
All reactions