Skip to content

build_mp: a GIGA build picks its M4 boot padding from 4 KB, not four sizes - #379

Merged
bdbarnett merged 1 commit into
mainfrom
giga-m4-pad-search
Nov 10, 2026
Merged

bdbarnett merged 1 commit into
mainfrom
giga-m4-pad-search

Conversation

@bdbarnett

Copy link
Copy Markdown
Contributor

On a GIGA whose BCM4 option bit is set, the M4 core starts from whatever bytes the firmware has at 0x08100000. A build refuses an image whose bytes there point at memory, and pads the code before that address until they don't. It tried 16, 32, 48 and 64 bytes of padding, which move the address only 24 to 72 bytes through the code. When the address lands in a literal pool of flash addresses, every size is refused and the build fails. That's what happened to the DISPLAY_SHIELD build with audiodsp 6d08b07 (#375): its 1,456 more bytes of code before the address put the end of mp_builtin_help, a pool of pointers into flash, under it.

Now the padding function is always compiled, so the build can find it in the linked image. Growing the pad by a multiple of .text's largest alignment (8 bytes) moves everything after it by exactly that much, so the build reads every padding from 0 to 4,096 bytes, in 16-byte steps, off the image it already linked. It relinks once with the smallest one whose bytes pass, checks them, and tries the next only when the relink didn't put there what the image said (up to four times). Windows 16 bytes apart over 4 KB can't all sit in one literal pool, so a growing image no longer trips this.

I built --port stm32 --board ARDUINO_GIGA --variant DISPLAY_SHIELD --modules displayif,lvgl,audiodsp,audioif,ulab,usbhost from a clean build directory with audiodsp 6d08b07. Before, it failed with "none of 16, 32, 48, 64 bytes of padding moved it clear". With this change it overflowed 1,280 KB, took the M4's flash as before, and printed m4 pad: 96 bytes after one relink; the bytes at 0x08100000 are stack 0xf7e84809, reset 0x3501f82c, HardFault 0xbf18429d. Read off that image, the smallest passing padding over 4 KB of growth either way is never more than 224 bytes. tests/test_build_mp.py passes, and a planted sign error in the window arithmetic fails three of its tests.

The Release firmware workflow, which builds the GIGA, doesn't run on a change to build_mp.py alone, so this branch's CI doesn't build it; #375 carries this commit to show the GIGA job passing with 6d08b07. The image wasn't flashed: what it puts at 0x08100000 passes the same rule every earlier image was held to, and the firmware's place in flash doesn't change.

…sizes

On a GIGA whose BCM4 option bit is set, the M4 starts from the bytes at
0x08100000, so a build refuses an image whose bytes there point at memory
and pads the code before that address until they don't. It tried 16, 32,
48 and 64 bytes, which move the address only 24 to 72 bytes through the
code. An image whose address landed in a literal pool of flash addresses
(the end of mp_builtin_help here) was refused at every size, and the build
failed: audiodsp 6d08b07 grew the code before the address by 1,456 bytes
and put it there.

Now the padding function is always compiled, so the build knows where it
is, and every padding from 0 to 4,096 bytes in 16-byte steps is read off
the image already linked: growing the pad by a multiple of .text's largest
alignment (8) moves everything after it by exactly that much. The build
relinks once with the smallest padding whose bytes pass, checks them, and
tries again (up to four times) only if the relink didn't put there what
the image said. Windows 16 bytes apart over 4 KB can't all sit in one
literal pool.

The GIGA DISPLAY_SHIELD build with audiodsp 6d08b07, which failed with
"none of 16, 32, 48, 64 bytes of padding moved it clear", now prints
"m4 pad: 96 bytes" after one relink, and the bytes at 0x08100000 are
stack 0xf7e84809, reset 0x3501f82c, HardFault 0xbf18429d. Over 4 KB of
growth either way from that image, the smallest padding that passes is
never more than 224 bytes. tests/test_build_mp.py passes (97 tests).
@bdbarnett
bdbarnett merged commit 92897eb into main Nov 10, 2026
28 checks passed
@bdbarnett
bdbarnett deleted the giga-m4-pad-search branch November 10, 2026 05:13
bdbarnett added a commit that referenced this pull request Nov 10, 2026
#375)

Moves audiodsp to audiodsp#399. In size-optimised firmware, the classic ESP32's for one, the reverb tank now compiles for speed: 4.7 to 4.0 ms per 48 kHz block at 160 MHz, with output identical to the bit. With the AUDIO_KIT variant at 240 MHz (#374) the seven-note soundmodule run from apps#44 plays with its Reverb and no dropouts. The GIGA build passes with an 80-byte M4 pad (#379).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant