Kaben123 commented on PR #19950:
URL: https://github.com/apache/nuttx/pull/19950#issuecomment-5420174725
## CI analysis: `xtensa-03` (`esp32s3-devkit:usbmsc`) — root cause
reproduced locally
I reproduced the `xtensa-03` failure locally inside the official NuttX CI
Docker image (`ghcr.io/apache/nuttx/apache-nuttx-ci-linux`, esptool v5.2.0) and
traced it to a deterministic, PR-independent-looking, but size-triggered issue
in `esptool`'s `--ram-only-header` image layout. **It is not a flash-size
overflow, and it is not in the fs/inode code.**
### What actually fails
NuttX itself compiles and links fine — the `nuttx` ELF is produced
successfully. The failure happens afterwards, when `esptool elf2image
--ram-only-header` converts the ELF into the flash image:
```
File ".../esptool/bin_image.py", line 887, in save
assert (f.tell() + 8 + self.ROM_LOADER.BOOTLOADER_FLASH_OFFSET) % (
AssertionError
```
This is `esptool`'s MMU-page (IROM_ALIGN = 64 KB) alignment assertion in the
`ram_only_header` path, not a capacity check.
### Controlled comparison (same image, same esptool v5.2.0)
| ELF | `elf2image --ram-only-header` | `elf2image` (no `--ram-only-header`)
|
|-----|:---:|:---:|
| **master** | ✅ success | ✅ success |
| **this PR** | ❌ AssertionError | ✅ success |
So the same esptool that fails on this PR's ELF succeeds on master's ELF,
and the same PR ELF succeeds once `--ram-only-header` is dropped. The trigger
is the combination of `--ram-only-header` (enabled by
`CONFIG_ESPRESSIF_SIMPLE_BOOT`, via `tools/esp32s3/Config.mk`) and the exact
size of the flash-mapped segment.
### Why the size matters
```
.flash.text size:
master : 0x1ff13 (130835 B)
this PR : 0x1fff7 (131063 B) (+228 B)
```
This PR's fs/inode path-resolution code adds ~228 bytes of `.text`, pushing
`.flash.text` right up against the `0x20000` (2 × 64 KB IROM_ALIGN) boundary.
In esptool's `--ram-only-header` padding logic this makes the per-segment
alignment congruence `(f.tell() + 8 + BOOTLOADER_FLASH_OFFSET) % IROM_ALIGN ==
segment.addr % IROM_ALIGN` unsatisfiable, so the assertion fires. master's
slightly smaller `.flash.text` still lands in a satisfiable range, which is why
master passes and re-runs of this PR keep failing (the ELF is deterministic).
### Conclusion
- Not flash overflow; the ELF builds and links cleanly.
- Not caused by the fs/inode logic — that code is correct; it only changes
code size.
- The defect is in esptool v5.2.0's `--ram-only-header` layout, exposed here
because this PR's size increase lands `.flash.text` on an IROM_ALIGN boundary
for the `esp32s3-devkit:usbmsc` (SIMPLE_BOOT) config.
Could an esp32s3 maintainer advise on the preferred path — e.g. an esptool
version bump on CI, or an upstream fix for the `--ram-only-header` alignment
padding? Happy to file an esptool issue with this reproduction if that helps.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]