Repository navigation
build_mp: a GIGA build picks its M4 boot padding from 4 KB, not four sizes - #379
Merged
Merged
Conversation
…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
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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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,usbhostfrom 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 printedm4 pad: 96 bytesafter 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.pypasses, 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.pyalone, 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.