Files
retroSoC/publications/datasheets/sections/boot-bundle-format.typ
T
maksyuki 422f48d0cd feat: refactor and enhance documentation for Linux runtime, boot acceptance, and NPU integration
- Updated fault reference documentation to clarify Linux termination behavior and NPU-P6 requirements.
- Enhanced Linux runtime section with emphasis on platform setup and kernel handoff processes.
- Revised overview section to include detailed descriptions of NPU capabilities and memory configurations.
- Improved product use documentation to specify Linux rootfs behavior and acceptance checkpoints.
- Clarified reset summary to differentiate between Linux and smoke/NPU-P6 acceptance processes.
- Updated software section to reflect changes in Linux image loading and readiness protocols.
- Modified build scripts to support RV64 architecture and ensure proper ELF requirements.
- Enhanced NPU compiler to support cycle counting for RV64 and RV32 architectures.
- Added tests to validate new configurations and ensure compliance with updated publication contracts.
2026-10-01 12:41:05 +08:00

97 lines
5.9 KiB
Typst

#import "../style.typ": *
#change-start("v05-emphasis-boot-bundle-format","Selected body emphasis: boot bundle format")
#import "../diagram-packages.typ": binary-figures, storage-figures
#let bundle = data.system_reference.software.bundle_reference
#let hex(value) = code("0x"+upper(str(value,base:16)))
=== HP Boot Bundle Binary Format <boot-bundle-format>
The supplied V2 format is a typed workload bundle, serialized as *little-endian 32-bit words*.
Linux uses four artifacts; smoke and RT-Thread use one executable descriptor at
0x38000000 with the remaining three descriptor slots zero. Workload values are 1, 2 and 3
respectively. V1 bundles must be rebuilt.
The format version is #bundle.version; it is independent of the datasheet's v0.5 revision.
The bundle starts at Flash offset #hex(bundle.bundle_offset), after the LP firmware area.
Its fixed header is #bundle.fixed_header_bytes bytes, each descriptor is #bundle.entry_bytes
bytes and the complete header including #bundle.entry_count descriptors is #bundle.header_bytes bytes.
The following offsets are relative to the beginning of the named structure. The descriptor
array starts immediately after the fixed header, so descriptor n begins at
#code(str(bundle.fixed_header_bytes)+" + n * "+str(bundle.entry_bytes)), for n = 0…#(bundle.entry_count - 1).
All listed fields occupy four bytes. Use the *explicit serialization, not an arbitrary host
structure layout*. The existing load addresses and maximum allocations remain in the preceding
image-layout table.
#binary-figures("software-boot","software")
#ds-table("bundle-fixed-header",[HP boot bundle fixed-header fields],
([Byte offset],[Field],[Bytes],[Meaning]),
bundle.header_fields.map(f=>(hex(f.offset),code(f.name),str(f.bytes),f.meaning)),
widths:(0.55fr,1.05fr,0.35fr,2.55fr))
#ds-table("bundle-entry-fields",[HP boot bundle descriptor fields],
([Byte offset],[Field],[Bytes],[Meaning]),
bundle.entry_fields.map(f=>(hex(f.offset),code(f.name),str(f.bytes),f.meaning)),
widths:(0.55fr,1.05fr,0.35fr,2.55fr))
flash_offset is absolute from the start of the Flash image. total_size is relative to the
bundle start and reaches the aligned end of the generated image. size is only the actual
payload length. Do not add BUNDLE_OFFSET a second time to a descriptor's flash_offset or include
alignment padding in a payload CRC. The four maximum allocations are individual bounds; their
sum is not a promise that all maximum-sized artifacts fit in the #(bundle.flash_capacity)-byte Flash image.
The header CRC covers the full header and all descriptors with header_crc32 replaced by zero.
Payload CRCs cover exactly each entry's size bytes. The current CRC matches CRC-32/ISO-HDLC:
reflected polynomial 0xEDB88320, initial state and final XOR 0xFFFFFFFF. The loader computes
the header check after clearing the CRC word in its local copy. Existing DMA/copy and readback
qualifications remain those of the loader sequence; CRC provides neither origin authentication
nor a rollback policy.
==== Generator output and loader acceptance
The packager produces a deterministic layout. The loader checks a subset of that layout's
properties. The distinction below records the implementation; it does not add acceptance rules
or invite reliance on unvalidated encodings. Use the canonical packager output for normal images.
#for rule in bundle.rules {
block(breakable:false)[
#minor-title(rule.topic)
#ds-table("bundle-rule-"+rule.topic.replace(" ","-").replace("/","-"),[#rule.topic: generated output versus loader check],
([Layer],[Behavior]),
(([Packager],rule.producer),([Loader],rule.loader),([Interpretation],rule.consequence)),
widths:(0.7fr,3.8fr))
]
}
The generated and accepted payload boundary is #bundle.payload_alignment bytes. The loader
requires flags=1, a known workload, its exact entry count/types/load addresses, and zero unused
descriptors. It rejects overlapping or out-of-bounds payloads. Padding bytes are not validated.
#source-note("app/apps/hp_boot/hp_boot_bundle.h",title:"Handwritten bundle fields, types and allocation bounds")
#source-note("scripts/package_hp_boot.py",title:"Actual byte serialization, alignment, padding and CRC generation")
#source-note("app/apps/hp_boot/hp_boot_bundle.c",title:"Actual header/entry acceptance")
#source-note("app/apps/hp_boot/main.c",title:"Copy checks and workload-specific terminal handshakes")
==== Synthetic serialization example
This example is generated by the existing packager from non-executable synthetic payloads.
The LP area contains 64 bytes (the ASCII pair LP repeated 32 times). The four named artifacts
contain repeated byte values 0x01, 0x02, 0x03 and 0x04, with lengths 32, 33, 34 and 35 bytes.
These filenames identify the format slots only; the contents are not OpenSBI, a valid DTB,
a Linux kernel or an initramfs. This example is not a boot or programming result.
#ds-table("bundle-example-header",[Synthetic example header values],
([Field],[Value]),
bundle.header_fields.map(f=>(code(f.name),hex(bundle.example.header.at(f.name)))),widths:(1.2fr,3.3fr))
#ds-table("bundle-example-payloads",[Synthetic example descriptor locations and payload CRCs],
([Artifact],[Descriptor offset],[Flash offset],[Payload bytes],[Payload CRC32]),
bundle.example.entries.map(e=>(code(e.name),hex(e.descriptor_offset),hex(e.flash_offset),str(e.size),hex(e.crc32))),
widths:(1.1fr,0.85fr,0.9fr,0.65fr,1fr))
The generated image occupies #bundle.example.image_bytes bytes, of which
#bundle.example.header.total_size bytes lie at or after the bundle start. Unused bytes are
filled with 0xFF; this includes the gap after LP firmware, gaps before payloads and final
alignment padding. The package manifest's image SHA-256 covers that complete generated image.
The example values are recalculated from the actual packager rather than maintained by hand.
#source-note("tests/test_hp_boot_bundle.py",title:"Existing package layout/CRC test boundary")
#storage-figures("software-boot",section:"software")
#change-end("v05-emphasis-boot-bundle-format")