Skip to content

attachFlash hardcodes 4 MB, breaking writes past 4 MB on chips with larger flash #41

@dsbaars

Description

@dsbaars

Summary

Flasher.attachFlash (pkg/espflasher/flasher.go#L907-L913) calls spiSetParams(4*1024*1024, ...) with the flash size hardcoded to 4 MB, regardless of what FlasherOptions.FlashSize is set to or what detectFlashSize() finds on the chip. The stub uses this value as a write bound — any write past 4 MB is rejected with status 0xC4 (RESPONSE_FAILED_SPI_OP), even on chips with 8 MB or larger flash.

Reproduction

ESP32-S3 with 8 MB flash. Use FlashImages to write two parts:

  • App image at 0x010000 (~1.6 MB) — succeeds
  • LittleFS / storage image at 0x6F0000 (within the 8 MB chip but past the hardcoded 4 MB bound) — fails immediately on the first compressed block:
Writing 839680 bytes at 0x006F0000...
Compressed 839680 bytes to 253336 (30%)
Flash begin: 253336 bytes at 0x006F0000 (16 compressed blocks)
flash at 0x006F0000: flash block 1 of 16: command 0x11 failed: status=0xC4 error=0x00 (unknown error)

The same images flash successfully via esptool.py and esptool-js, both of which pass the actual chip size to SPI_SET_PARAMS. esptool's cmds.py#L1852 calls esp.flash_set_parameters(flash_size_bytes(flash_size)) with a comment noting "the flash chip should be configured with the real size".

Why this happens

The 4 MB written into config.flash_size (esp-flasher-stub command_handler.c#L592) is consulted by the stub's flash-write path; an over-bound write returns RESPONSE_FAILED_SPI_OP = 0xC400, surfaced to the host as status=0xC4. The library's detectFlashSize() runs after attachFlash() in FlashImages and only updates the value used to patch image headers — it never re-pushes the corrected size to the stub.

Suggested fix

  1. Add a helper to convert the existing 1MB/2MB/4MB/.../128MB size strings to bytes.
  2. Make attachFlash derive the bytes from f.opts.FlashSize (falling back to 4 MB only if unset/keep/unrecognised).
  3. After detectFlashSize() runs in FlashImages, re-push the SPI params so the stub gets the real chip size before any writes.

I have a working patch verified on ESP32-S3 / 8 MB hardware that previously failed at 0x6F0000 and now flashes through to MD5 verify. Happy to send a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions