[PATCH 6/7] docs: firmware: document the FW_DYNAMIC_APPEND firmware type

Zong Li zong.li at sifive.com
Mon Jul 6 20:39:53 PDT 2026


Add docs/firmware/fw_dynamic_append.md describing the new firmware
type: how it differs from FW_DYNAMIC, why struct fw_dynamic_info is
appended before .bss (so it stays inside the flat .bin), the version 3
structure layout with the new boot_dtb field, that the previous stage
patches every field at runtime, the boot register setup performed by
fw_base.S, and how to build it.

Signed-off-by: Zong Li <zong.li at sifive.com>
---
 docs/firmware/fw_dynamic_append.md | 110 +++++++++++++++++++++++++++++
 1 file changed, 110 insertions(+)
 create mode 100644 docs/firmware/fw_dynamic_append.md

diff --git a/docs/firmware/fw_dynamic_append.md b/docs/firmware/fw_dynamic_append.md
new file mode 100644
index 00000000..25e951d9
--- /dev/null
+++ b/docs/firmware/fw_dynamic_append.md
@@ -0,0 +1,110 @@
+OpenSBI Firmware with Appended Dynamic Information (FW_DYNAMIC_APPEND)
+=====================================================================
+
+OpenSBI **firmware with appended dynamic info (FW_DYNAMIC_APPEND)** is a
+variant of the FW_DYNAMIC firmware. Like FW_DYNAMIC, it gets information
+about the next booting stage (e.g. a bootloader or an OS) and runtime
+OpenSBI library options from a *struct fw_dynamic_info*.
+
+The difference is *how* that structure is delivered:
+
+* For *FW_DYNAMIC*, the previous booting stage creates a struct fw_dynamic_info
+  in memory and passes its address to OpenSBI via the *a2* register.
+* For *FW_DYNAMIC_APPEND*, the struct fw_dynamic_info is *appended into the
+  OpenSBI binary itself*. It is laid out immediately before the *.bss* section so
+  that it is the last byte-content of the flat binary (`.bin`) image. The
+  previous booting stage locates the structure at the tail of the image, patches
+  its fields at runtime, and then jumps to the OpenSBI entry point *without*
+  having to set up the a0/a1/a2 registers.
+
+A FW_DYNAMIC_APPEND firmware is useful when the previous booting stage cannot
+easily allocate a separate struct fw_dynamic_info and pass its pointer in a2,
+but can load the OpenSBI image and patch a few words at a known offset (the en
+of the file) before jumping to it. For example, the previous boot stage runs on
+a dedicated hart. Therefore, it cannot set up CSRs of another hart that runs
+OpenSBI. This scenario will occurs in server systems with secure boot.
+
+Why the structure is placed before .bss
+---------------------------------------
+
+The flat `.bin` image is produced with `objcopy -O binary`. The *.bss* section
+has type NOBITS and is therefore *not* stored in the file. It does not count
+towards the binary file size. If the appended struct fw_dynamic_info were placed
+after *.bss*, it would not be part of the `.bin` file and the previous booting
+stage would compute the wrong address for it.
+
+By placing the structure right before *.bss*, it becomes the last PROGBITS
+content and sits exactly at the tail of the `.bin` file:
+
+```
+ .text | .rodata | .rela.dyn | .data | .fw_dynamic_info | .bss (NOBITS, dropped)
+ <------------------- .bin file size -------------------><--- not in file --->
+                                       ^ struct fw_dynamic_info (image tail)
+```
+
+The previous booting stage can therefore find the structure at:
+
+```
+    struct_addr = load_address + binary_file_size - sizeof(struct fw_dynamic_info)
+```
+
+The structure layout
+---------------------
+
+FW_DYNAMIC_APPEND uses struct fw_dynamic_info version 3, which adds a *boot_dtb*
+field after *boot_hart*:
+
+| Field      | Notes                                   |
+|------------|-----------------------------------------|
+| magic      | 'OSBI' (0x4942534f), patched at runtime |
+| version    | 3, patched at runtime                   |
+| next_addr  | next stage entry, patched at runtime    |
+| next_mode  | next stage privilege mode               |
+| options    | OpenSBI library options                 |
+| boot_hart  | preferred boot HART id (-1 = lottery)   |
+| boot_dtb   | DTB address, patched at runtime         |
+
+In the OpenSBI image the structure is reserved as all zeros. It is a placeholder
+only. The previous booting stage is responsible for patching *every* field,
+before jumping to OpenSBI. Because the reserved block is a PROGBITS section that
+is KEEP() in the linker script, the zero bytes are still emitted at the tail of
+the `.bin` (unlike a NOBITS/.bss reservation, which would be dropped).
+
+Boot register setup
+-------------------
+
+Because the previous booting stage does not pass a0/a1/a2, the OpenSBI cold-boot
+entry path (in firmware/fw_base.S, guarded by FW_DYNAMIC_APPEND) synthesizes the
+expected boot state:
+
+* all general purpose registers are cleared to a known state,
+* *a0* is loaded with the current *mhartid*,
+* *a2* is pointed at the appended struct fw_dynamic_info, and
+* *a1* is loaded with the *boot_dtb* field from that structure, but only when
+  the appended structure reports version >= FW_DYNAMIC_INFO_VERSION_3 (the
+  version that introduced *boot_dtb*). For an older layout that lacks the
+  field, *a1* is left at 0 rather than reading past the end of the structure.
+
+From this point the boot flow is identical to FW_DYNAMIC. Only the cold-boot path
+is affected, secondary HARTs enter through the warm-boot path unchanged.
+
+FW_DYNAMIC_APPEND Compilation
+-----------------------------
+
+A platform can enable FW_DYNAMIC_APPEND firmware using any of the following
+methods:
+
+1. Specifying *FW_DYNAMIC_APPEND=y* on the top level make command line.
+2. Specifying *FW_DYNAMIC_APPEND=y* in the target platform *objects.mk*
+   configuration file.
+
+For example:
+
+```
+make PLATFORM=<platform_subdir> FW_DYNAMIC_APPEND=y
+```
+
+The compiled FW_DYNAMIC_APPEND firmware ELF file is named *fw_dynamic_append.elf*.
+Its expanded image file is *fw_dynamic_append.bin*. Both files are created in the
+platform specific build directory under the
+*build/platform/<platform_subdir>/firmware* directory.
-- 
2.43.7




More information about the opensbi mailing list