Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Writing >= 16MB addresses not working (ESF-106) #92

Open
higaski opened this issue Dec 19, 2023 · 46 comments
Open

Writing >= 16MB addresses not working (ESF-106) #92

higaski opened this issue Dec 19, 2023 · 46 comments
Labels
Type: Feature Request Feature Request for esp-serial-flasher

Comments

@higaski
Copy link
Contributor

higaski commented Dec 19, 2023

Port

USER_DEFINED

Target chip

ESP32-S3

Hardware Configuration

Custom ESP32-S3 board connected via USB CDC

Log output

Found 2 serial ports
Connecting to ttyACM0
Found esp32s3
Flash will be erased from 0x0 to 0x5fff
Flash size detection failed, falling back to default
Writing at 0x400... (4%)
Writing at 0xc00... (14%)
Writing at 0x1400... (23%)
Writing at 0x1c00... (33%)
Writing at 0x2400... (42%)
Writing at 0x2c00... (52%)
Writing at 0x3400... (61%)
Writing at 0x3c00... (71%)
Writing at 0x4400... (80%)
Writing at 0x4c00... (90%)
Flash will be erased from 0x10000 to 0x164fff
Flash size detection failed, falling back to default
Writing at 0x10400... (0%)
Writing at 0x32400... (10%)
Writing at 0x54400... (20%)
Writing at 0x76400... (30%)
Writing at 0x98400... (40%)
Writing at 0xba400... (50%)
Writing at 0xdc400... (60%)
Writing at 0xfe400... (70%)
Writing at 0x120400... (80%)
Writing at 0x142800... (90%)
Writing at 0x1644e0... (100%)
Flash will be erased from 0x1010000 to 0x1ffffff
Flash size detection failed, falling back to default
Error: 
COMMAND_FAILED


Erasing flash failed (ESP_LOADER_ERROR_INVALID_RESPONSE)
Cannot connect to target (ESP_LOADER_ERROR_INVALID_RESPONSE)

More Information

I've written a small native CLI/GUI application much like the Espressif Flash Download Tool to make downloading multiple binaries easier. So far I've tested this app with the hello_world example on various Espressif demo boards. Uploading the example (consisting of bootloader, app and partition table) works flawlessly.

Thinking that my app works I've moved on to trying to flash my current project on a custom ESP32-S3 board. The projects flash files are

"flash_files" : {
    "0x0" : "bootloader/bootloader.bin",
    "0x10000" : "WULF.bin",
    "0x8000" : "partition_table/partition-table.bin",
    "0xa000" : "ota_data_initial.bin",
    "0x1010000" : "storage.bin",
    "0x810000" : "nvs.bin"
}

As you can probably guess some of those binaries are bigger than the hello_world example

# ESP-IDF Partition Table
# Name,   Type, SubType, Offset,  Size, Flags
phy_init, data, phy,     ,        4K,
otadata,  data, ota,     ,        8K,
ota_0,    app,  ota_0,   ,        4M,
ota_1,    app,  ota_1,   ,        4M,
nvs,      data, nvs,     ,        8M,
storage,  data, spiffs,  ,        16320K,

Uploading those bigger binaries does not work. I'm getting the following output from the library (see full log above)

Error: 
COMMAND_FAILED

I assume that for some reason the library can't handle certain memory region or binary sizes (yet)?
This might also be related to #23?
Any suggestions? Is this a known issue?

@github-actions github-actions bot changed the title Writing above certain memory region not working Writing above certain memory region not working (ESF-106) Dec 19, 2023
@DNedic
Copy link
Collaborator

DNedic commented Dec 19, 2023

Hello @higaski , we do not know of any limitation that would cause flashing some memory regions to fail. Can you please provide either a log with SERIAL_FLASHER_DEBUG_TRACE set or a logic analyzer trace to help us narrow down the issue?

@higaski
Copy link
Contributor Author

higaski commented Dec 19, 2023

How should SERIAL_FLASHER_DEBUG_TRACE help in this case? This define seems to be used in the ports code only, nowhere in the actual lib. I've implemented loader_port_debug_print() though, shouldn't this be sufficient? I think the log I've added already contains the debug outputs (e.g. the one about flash size).

Also none of your examples writes larger binaries at higher adresses. Could you maybe add one?

@DNedic
Copy link
Collaborator

DNedic commented Dec 19, 2023

I apologize, I have assumed you have implemented debug tracing in the same way as it is implemented in other ports. In that case either copy over the tracing from other ports to your port and enable it, or provide a logic analyzer trace.

Also none of your examples writes larger binaries at higher adresses. Could you maybe add one?

Thanks for the suggestion, we will explore the idea!

@higaski
Copy link
Contributor Author

higaski commented Dec 19, 2023

Oh I'm sorry now I got it. I thought the macro enables loader_port_debug_print, but it actually enables transfer_debug_print.

I'll provide logs tomorrow.

@DNedic
Copy link
Collaborator

DNedic commented Dec 19, 2023

Unification of logging/tracing is something we are looking into for the future, but it requires quite extensive changes.

@higaski
Copy link
Contributor Author

higaski commented Dec 20, 2023

I've added the logging. Here is a log of me trying to write the storage.bin file mentioned above

--- WRITE ---
c0 00 08 24 00 00 00 00 00 07 07 12 20 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 c0 
--- READ ---
45 53 50 2d 52 4f 4d 3a 65 73 70 33 32 73 33 2d 32 30 32 31 30 33 32 37 0d 0a 42 75 69 6c 64 3a 4d 61 72 20 32 37 20 32 30 32 31 0d 0a 72 73 74 3a 30 78 31 20 28 50 4f 57 45 52 4f 4e 29 2c 62 6f 6f 74 3a 30 78 31 30 20 28 44 4f 57 4e 4c 4f 41 44 28 55 53 42 2f 55 41 52 54 30 29 29 0d 0a 77 61 69 74 69 6e 67 20 66 6f 72 20 64 6f 77 6e 6c 6f 61 64 0d 0a 
--- WRITE ---
c0 00 08 24 00 00 00 00 00 07 07 12 20 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 c0 
--- READ ---
c0 01 08 04 00 07 07 12 20 00 00 00 00 c0 c0 01 08 04 00 07 07 12 20 00 00 00 00 c0 c0 01 08 04 00 07 07 12 20 00 00 00 00 c0 c0 01 08 04 00 07 07 12 20 00 00 00 00 c0 c0 01 08 04 00 07 07 12 20 00 00 00 00 c0 c0 01 08 04 00 07 07 12 20 00 00 00 00 c0 c0 01 08 04 00 07 07 12 20 00 00 00 00 c0 c0 01 08 04 00 07 07 12 20 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 00 10 00 40 c0 
--- READ ---
c0 01 0a 04 00 09 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 48 70 00 60 c0 
--- READ ---
c0 01 0a 04 00 12 f4 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 4c 70 00 60 c0 
--- READ ---
c0 01 0a 04 00 00 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0d 08 00 00 00 00 00 00 00 00 00 00 00 00 00 c0 
--- READ ---
c0 01 0d 04 00 00 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 18 20 00 60 c0 
--- READ ---
c0 01 0a 04 00 00 00 00 80 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 20 20 00 60 c0 
--- READ ---
c0 01 0a 04 00 00 00 00 70 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 28 20 00 60 17 00 00 00 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 04 00 00 00 00 70 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 18 20 00 60 00 00 00 90 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 04 00 00 00 00 70 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 20 20 00 60 9f 00 00 70 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 04 00 00 00 00 70 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 58 20 00 60 00 00 00 00 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 04 00 00 00 00 70 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 00 20 00 60 00 00 04 00 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 04 00 00 00 00 70 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 00 20 00 60 c0 
--- READ ---
c0 01 0a 04 00 00 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 58 20 00 60 c0 
--- READ ---
c0 01 0a 04 00 c2 80 39 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 18 20 00 60 00 00 00 80 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 04 00 c2 80 39 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 20 20 00 60 00 00 00 70 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 04 00 c2 80 39 00 00 00 00 00 c0 
--- WRITE ---
c0 00 02 14 00 00 00 00 00 00 00 ff 00 db dc 3f 00 00 00 04 00 00 00 00 01 01 00 00 00 00 c0 
--- READ ---
c0 01 02 04 00 c2 80 39 00 01 06 00 00 c0 

I'm getting shut down in line 121 of check_response

static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value, void *resp, uint32_t resp_size)
{
esp_loader_error_t err;
common_response_t *response = (common_response_t *)resp;
do {
err = SLIP_receive_packet(resp, resp_size);
if (err != ESP_LOADER_SUCCESS) {
return err;
}
} while ((response->direction != READ_DIRECTION) || (response->command != cmd));
response_status_t *status = (response_status_t *)((uint8_t *)resp + resp_size - sizeof(response_status_t));
if (status->failed) {
log_loader_internal_error(status->error);
return ESP_LOADER_ERROR_INVALID_RESPONSE;
}
if (reg_value != NULL) {
*reg_value = response->value;
}
return ESP_LOADER_SUCCESS;
}

Here is the call stack at this point

libflasher.so!check_response(command_t cmd, uint32_t * reg_value, void * resp, uint32_t resp_size)
libflasher.so!send_cmd(const void * cmd_data, uint32_t size, uint32_t * reg_value)
libflasher.so!loader_flash_begin_cmd(uint32_t offset, uint32_t erase_size, uint32_t block_size, uint32_t blocks_to_write, _Bool encryption)
libflasher.so!esp_loader_flash_start(uint32_t offset, uint32_t image_size, uint32_t block_size)

This is the command being sent
flash_begin_cmd

@DNedic
Copy link
Collaborator

DNedic commented Dec 20, 2023

Thanks for the data, after looking into this in the ROM, I don't see any reason it would fail, however it is possible that the default hardcoded params used by loader_spi_parameters() are incorrect for the specific flash chip: https://github.com/espressif/esp-serial-flasher/blob/master/src/protocol_common.c#L280

Can you compare the parameters of the flash chip used on your board to these?

@higaski
Copy link
Contributor Author

higaski commented Dec 20, 2023

I'm using a ESP32-S3-WROOM-2-N32R8V module. Do they come with different flash chips?
I've just looked at the datasheet and couldn't find any specifics on the flash. Where can I find that info?

I don't think that this is the issue though. Flashing generally seems to work. I can write the hello_world example just fine. I assume that this also wouldn't work if the flash parameters would be wrong?

/edit
Oh I see, it falls back to some default flash size which is most likely smaller than 32MB...?
Why does detect_flash_size fail though?

@DNedic
Copy link
Collaborator

DNedic commented Dec 20, 2023

Good spot, it seems that is the reason loader_spi_parameters() sends wrong info. I will investigate this, in the meantime, try manually setting the parameters for your flash chip and trying to flash that way.

@higaski
Copy link
Contributor Author

higaski commented Dec 20, 2023

I've manually set the flash size to 32MB, but this doesn't cut it. I can now flash the project, but it's giving me an "invalid header" error after reboot.

Is there anything else beside flash size I might need to set?

@DNedic
Copy link
Collaborator

DNedic commented Dec 20, 2023

Did you successfully manage to flash the same exact binaries with esptool or other flashing tools we provide and get the app to work?

@higaski
Copy link
Contributor Author

higaski commented Dec 20, 2023

Flashing with the idf.py frontend works yes.

@DNedic
Copy link
Collaborator

DNedic commented Dec 20, 2023

Have you enabled the MD5 checks? Also, can you read back the contents of the flash flashed with esp-serial-flasher using esptool, and contents of the flash written with esptool so we can see the difference?

@higaski
Copy link
Contributor Author

higaski commented Dec 20, 2023

I haven't gotten MD5 to work yet. Even on examples which work it keeps telling me that my MD5 checks fail. Haven't looked into this further.

For the esptool, yes, I'll try that tomorrow.

@higaski
Copy link
Contributor Author

higaski commented Dec 21, 2023

Out of curiosity I've started flashing the hello_world example at various addresses. I've used the following partition table and gradually increased the location of the app binary.

# ESP-IDF Partition Table
# Name,   Type, SubType, Offset,    Size,   Flags
nvs,      data, nvs,     0x9000,    0x6000,
phy_init, data, phy,     0xf000,    0x1000,
factory,  app,  factory, 0x******,  1M,

This works up to 0xF00000 and stops working at 0x1000000.
So everything above 16MB currently does not work.

I'll read out the written binaries later that day to see where exactly it fails.

@higaski
Copy link
Contributor Author

higaski commented Dec 21, 2023

Ok, so I've investigated further and used esptool to read out the binaries after flashing. From my observations everything works fine as long as one writes <16MB. Above that address things get... weird.

So for example, if I flash the following files

"flash_files" : {
    "0x0" : "bootloader/bootloader.bin",
    "0x1000000" : "hello_world.bin",
    "0x8000" : "partition_table/partition-table.bin"
}

in that very order the only correct binary after flashing is partition-table.bin.
hello_world.bin is all 0xFF, so clearly there has nothing been written there.
And strangely bootloader.bin also isn't correct anymore. I suspect that the library writes binaries above 16MB to 0x0 again...

For example, the very beginning of the read out location of where the bootloader should actually be contains the string "hello_world" which is the name of the app:
bootloader bin

binaries.zip
log.txt

@higaski higaski changed the title Writing above certain memory region not working (ESF-106) Writing >= 16MB addresses not working (ESF-106) Dec 21, 2023
@DNedic
Copy link
Collaborator

DNedic commented Dec 21, 2023

Thanks for the data, I will investigate this further.

@DNedic
Copy link
Collaborator

DNedic commented Dec 21, 2023

Hello @higaski , it appears the flasher stub used by esptool and other flashing tools we provide has special logic for chips of 16MB or more in size. It will take me some time probably to investigate how we can adapt esp-serial-flasher to do the same and test it.

@higaski
Copy link
Contributor Author

higaski commented Dec 22, 2023

Does this mean that the esptool --no-stub option currently doesn't work either?
I don't want to be clever, but it seems as if all the "32mb flash workarounds" you have put into various places are now coming back to bite you. 😝

@higaski
Copy link
Contributor Author

higaski commented Jan 18, 2024

Any updates on this? Can you please give me a time frame for when this will be addressed?

@DNedic
Copy link
Collaborator

DNedic commented Jan 18, 2024

Hello @higaski , thank you for the interest however we don't have an ETA for this yet.

@higaski
Copy link
Contributor Author

higaski commented Jan 18, 2024

Too bad because I'm sitting on a done programming application here just waiting for that fix. 😁

Screenshot_20240118_132219

Really hope you guys find time for it at some point.

@higaski
Copy link
Contributor Author

higaski commented Jan 18, 2024

Does this mean that the esptool --no-stub option currently doesn't work either? I don't want to be clever, but it seems as if all the "32mb flash workarounds" you have put into various places are now coming back to bite you. 😝

Just for reference and other people coming here: It doesn't.

@DNedic
Copy link
Collaborator

DNedic commented Jan 18, 2024

Does this mean that the esptool --no-stub option currently doesn't work either? I don't want to be clever, but it seems as if all the "32mb flash workarounds" you have put into various places are now coming back to bite you. 😝

Just for reference and other people coming here: It doesn't.

Sorry for the late confirmation, but yes it doesn't and as far as I know can't. So we need to add stub support before going forward with this.

If you can't wait, and want to contribute to help with this we are welcome to help you through the process.

@higaski
Copy link
Contributor Author

higaski commented Jan 19, 2024

I've peeked at the esptool source for a little while and this seems like a daunting task now...

I assume the following steps would be necessary:

  1. Fix flash detection
  2. Upload stub for detected processor after flash detection
  3. Jump to stub(?)
  4. Proceed with flashing binaries

@DNedic
Copy link
Collaborator

DNedic commented Jan 19, 2024

I've peeked at the esptool source for a little while and this seems like a daunting task now...

I assume the following steps would be necessary:

  1. Fix flash detection
  2. Upload stub for detected processor after flash detection
  3. Jump to stub(?)
  4. Proceed with flashing binaries

Can you elaborate on Fix flash detection? We've made flash detection match the one in esptool, are you still getting issues?

Yes, for stub use, it is uploaded to RAM, then jumped to and then there are differences in behavior that have to be accounted for in flashing code.

@dobairoland
Copy link
Collaborator

I think this could be done even without a flasher stub. In the case of esptool, the reason for being not supported is because flasher stub is used by default so adding support without flasher stub wasn't a priority (and not because it wasn't possible).

@higaski
Copy link
Contributor Author

higaski commented Jan 19, 2024

Can you elaborate on Fix flash detection? We've made flash detection match the one in esptool, are you still getting issues?

I'm sorry my bad. Yes, flash detection works now, my 32MB flash is recognized correctly.

@higaski
Copy link
Contributor Author

higaski commented Mar 11, 2024

What would have to be done to finally support >16MB? Are there any necessary changes to the ESP32 bootloader?

/edit
This post here suggests that support for >16MB will never be implemented for the ROM bootloader.

@igrr
Copy link
Member

igrr commented Mar 18, 2024

@higaski Continuing the discussion at espressif/esp-idf#8365 (comment), here are some pointers about the flasher stub.

The stub source code is available in https://github.com/espressif/esptool/tree/master/flasher_stub. I think you probably don't need to build the stub from source in this particular case, and it is simpler to get the compiled stubs from https://github.com/espressif/esptool/tree/master/esptool/targets/stub_flasher. Each of the JSON files contains base64-encoded .text and .data segments, as well as their load addresses. There is also the entry point address. The flasher tool needs to upload the .text and .data segments to the correct addresses, then instruct the ROM loader to jump to the entry point.

I think what might help you is to run esptool.py read_mac with the --trace option and see the commands sent by esptool.py between Uploading stub... and Stub running... messages.

Another implementation of uploading the stub can be found in esptool-js project, in case it helps: https://github.com/espressif/esptool-js/blob/7ed57e18642088675bec01b8e34ba196d5e135af/src/esploader.ts#L1142-L1188.

@DNedic
Copy link
Collaborator

DNedic commented Mar 20, 2024

@higaski Keep in mind that the behavior of the stub is not identical to the behavior of the ROM, this is why it is going to take a bit of work for us to add the stub support. For all differences you can check the esptool source code.

@higaski
Copy link
Contributor Author

higaski commented Mar 20, 2024

Are you already working on it? Because I've just forked the current master... 😃

@DNedic
Copy link
Collaborator

DNedic commented Mar 20, 2024

Not at the moment, no. We will not add it until Q3 at least due to other feature work in esp-serial-flasher. Either way we welcome all contributions!

@higaski
Copy link
Contributor Author

higaski commented Mar 20, 2024

Do I have to worry about the *beta versions of the stub too or is that something internal to Espressif?

Currently esp-serial-flasher has an enumeration for supported targets

typedef enum {
    ESP8266_CHIP = 0,
    ESP32_CHIP   = 1,
    ESP32S2_CHIP = 2,
    ESP32C3_CHIP = 3,
    ESP32S3_CHIP = 4,
    ESP32C2_CHIP = 5,
    ESP32_RESERVED0_CHIP = 6, // Reserved for future use
    ESP32H2_CHIP = 7,
    ESP32C6_CHIP = 8,
    ESP_MAX_CHIP = 9,
    ESP_UNKNOWN_CHIP = 9
} target_chip_t;

And that enum does not contain any "*beta" versions.

@igrr
Copy link
Member

igrr commented Mar 20, 2024

If you only need to support the chips which are mass-produced, then you don't have to worry about the -beta ones. Those are engineering samples used internally in Espressif for a limited amount of time (until the final version of the chip gets produced) and sometimes delivered to a limited number of customers.

@higaski
Copy link
Contributor Author

higaski commented Mar 23, 2024

Why does the code send a FLASH_BEGIN command with all 0's for the ESP8266?

if (s_target == ESP8266_CHIP) {
err = loader_flash_begin_cmd(0, 0, 0, 0, s_target);
} else {

Is this for the "erase size bug" mentioned in the docs?

And... more questions. I think I can now successfully upload the stub loader but I get shut down right after when the loader tries to read the SPI config.

RETURN_ON_ERROR( loader_read_spi_config(s_target, &spi_config) );
loader_port_start_timer(DEFAULT_TIMEOUT);
err = loader_spi_attach_cmd(spi_config);

Here's the log at this point

--- WRITE ---
c0 00 06 08 00 00 00 00 00 00 00 00 00 50 8a 37 40 c0  # Done with stub, jump to addr
--- READ ---
c0 01 06 04 00 09 00 00 00 00 00 00 00 c0   # Done with stub response?
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 48 70 00 60 c0 
--- READ ---
c0 4f 48 41 49 c0 c0 01 0a 02 00 12 f4 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 18 20 00 60 c0 
--- READ ---
c0 01 0a 02 00 00 00 00 80 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 20 20 00 60 c0 
--- READ ---
c0 01 0a 02 00 00 00 00 70 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 28 20 00 60 17 00 00 00 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 18 20 00 60 00 00 00 90 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 20 20 00 60 9f 00 00 70 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 58 20 00 60 00 00 00 00 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 00 20 00 60 00 00 04 00 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 00 20 00 60 c0 
--- READ ---
c0 01 0a 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 58 20 00 60 c0 
--- READ ---
c0 01 0a 02 00 c2 80 39 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 18 20 00 60 00 00 00 80 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 20 20 00 60 00 00 00 70 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0b 18 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 01 00 00 10 00 00 00 01 00 00 ff ff 00 00 c0 
--- READ ---
c0 01 0b 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 02 14 00 00 00 00 00 10 54 00 00 16 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00 c0 
--- READ ---
c0 01 02 02 00 00 00 00 00 01 00 c0  # Error here?

Does the last response contain an error? And if so, which one?

@higaski
Copy link
Contributor Author

higaski commented Mar 26, 2024

Ok, one step further. I've simply forgotten to read the "OHAI" sequence from the stub loader...

It's still not working though. The log also looks the same apart from the OHAI sequence?

--- READ ---
c0 01 07 04 00 09 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 06 08 00 00 00 00 00 00 00 00 00 50 8a 37 40 c0 
--- READ ---
c0 01 06 04 00 09 00 00 00 00 00 00 00 c0 c0 4f 48 41 49 c0 # OHAI
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 48 70 00 60 c0 
--- READ ---
c0 01 0a 02 00 12 f4 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 4c 70 00 60 c0 
--- READ ---
c0 01 0a 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0d 08 00 00 00 00 00 00 00 00 00 00 00 00 00 c0 
--- READ ---
c0 01 0d 02 00 00 00 00 00 01 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 18 20 00 60 c0 
--- READ ---
c0 01 0a 02 00 00 00 00 80 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 20 20 00 60 c0 
--- READ ---
c0 01 0a 02 00 00 00 00 70 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 28 20 00 60 17 00 00 00 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 18 20 00 60 00 00 00 90 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 20 20 00 60 9f 00 00 70 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 58 20 00 60 00 00 00 00 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 00 20 00 60 00 00 04 00 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 00 20 00 60 c0 
--- READ ---
c0 01 0a 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 58 20 00 60 c0 
--- READ ---
c0 01 0a 02 00 c2 80 39 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 18 20 00 60 00 00 00 80 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 09 10 00 00 00 00 00 20 20 00 60 00 00 00 70 ff ff ff ff 00 00 00 00 c0 
--- READ ---
c0 01 09 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0b 18 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 01 00 00 10 00 00 00 01 00 00 ff ff 00 00 c0 
--- READ ---
c0 01 0b 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 02 14 00 00 00 00 00 10 54 00 00 16 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00 c0 
--- READ ---
c0 01 02 02 00 00 00 00 00 01 00 c0 

@higaski
Copy link
Contributor Author

higaski commented Mar 27, 2024

And again... one step further. I just noticed that the documentation says that the SPI_ATTACH sends 4 additional bytes for the ROM bootloader... so I also accounted for that.

esp_loader_error_t loader_spi_attach_cmd(uint32_t config)
{
    spi_attach_command_t attach_cmd = {
        .common = {
            .direction = WRITE_DIRECTION,
            .command = SPI_ATTACH,
            .size = CMD_SIZE(attach_cmd),
            .checksum = 0
        },
        .configuration = config,
        .zero = 0
    };

#if STUB_ENABLED
    uint32_t const attach_cmd_size = esp_no_stub ? sizeof(attach_cmd) : sizeof(attach_cmd) - sizeof(attach_cmd.zero);
#else
    uint32_t const attach_cmd_size = sizeof(attach_cmd);
#endif

    return send_cmd(&attach_cmd, attach_cmd_size, NULL);
}

The response of this command still tells me that it fails...

static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value, void *resp, uint32_t resp_size)
{
    esp_loader_error_t err;
    common_response_t *response = (common_response_t *)resp;

    do {
        err = SLIP_receive_packet(resp, resp_size);
        if (err != ESP_LOADER_SUCCESS) {
            return err;
        }
    } while ((response->direction != READ_DIRECTION) || (response->command != cmd));

    response_status_t *status = (response_status_t *)((uint8_t *)resp + resp_size - sizeof(response_status_t));

    if (status->failed) {
        log_loader_internal_error(status->error); // FAILS HERE
        return ESP_LOADER_ERROR_INVALID_RESPONSE;
    }

    if (reg_value != NULL) {
        *reg_value = response->value;
    }

    return ESP_LOADER_SUCCESS;
}

If I ignore the SPI_ATTACH for now (something the docs says is optional) and continue with esp_loader_flash_start I also receive an error, this time from loader_flash_begin_cmd. Again check_response fails when checking the status bytes.

I'm starting to believe that the check_reponse function needs to be adapted to the stub loader, but I can't figure out how.

Some help would be appreciated...

@DNedic
Copy link
Collaborator

DNedic commented Mar 27, 2024

Hello @higaski , nice to hear that you are progressing, for more info you can take a look at esptool/loader.py and do a search for IS_STUB, there you can see the differences in behavior between the stub and the ROM.

@higaski
Copy link
Contributor Author

higaski commented Mar 27, 2024

Yes that's how I've found the difference between the original ROM SPI_ATTACH and the stub version in the first place. There does not seem to be any difference in reading the response between ROM and stub loader. Problem is the stub flasher does not send any meaningful error codes, all I get is the status member being set to 1... no further details.

I have an S3 DevKitC here. Should the SPI_ATTACH command with value 0 (=Default SPI flash interface) work out of the box? I don't understand why it keeps failing. Here is what gets send

--- WRITE ---
c0 00 0a 04 00 00 00 00 00 48 70 00 60 c0   // read efuse_word_addr(efuse_base, 18)
--- READ ---
c0 01 0a 02 00 12 f4 00 00 00 00 c0 
--- WRITE ---
c0 00 0a 04 00 00 00 00 00 4c 70 00 60 c0  // read efuse_word_addr(efuse_base, 19)
--- READ ---
c0 01 0a 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 0d 08 00 00 00 00 00 00 00 00 00 c0  // SPI_ATTACH
--- READ ---
c0 01 0d 02 00 00 00 00 00 01 00 c0  // Fails

/edit
And, as mentioned before. If I ignore SPI_ATTACH and continue with SPI_SET_PARAMS and then FLASH_BEGIN it fails as well.

--- WRITE ---
c0 00 0b 18 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 01 00 00 10 00 00 00 01 00 00 ff ff 00 00 c0  // loader_spi_parameters(flash_size)
--- READ ---
c0 01 0b 02 00 00 00 00 00 00 00 c0 
--- WRITE ---
c0 00 02 14 00 00 00 00 00 10 54 00 00 16 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00 c0 // loader_flash_begin_cmd
--- READ ---
c0 01 02 02 00 00 00 00 00 01 00 c0  // Fails

/edit
Ok, encryption is not supported by the stub loader. It get's passed to the FLASH_BEGIN command though because the S3 ROM loader apparently supports it.

loader_flash_begin_cmd(offset, erase_size, block_size, blocks_to_write, encryption_in_cmd);

Once I change that the stub works on my S3... 🥳
At least as long as I don't send an SPI_ATTACH prior. Any insight why SPI_ATTACH causes trouble?

@vtthanh83
Copy link

Hello @igrr @DNedic,

I am using ESP32-S3_WROOM-2 with 32MB. My project needs to activate secure bootloader flash encryption, this requires --no-stub option when flashing with esptool (v4.7.0) and I have exactly the same problem where flash content gets corrupted whenever flashing beyond 16MB address.

Can I check if we have any workaround to flash beyond 16MB with flash encryption enable?

@DNedic
Copy link
Collaborator

DNedic commented Jun 13, 2024

Hello @vtthanh83 , for esptool help it might be better to open an issue in the esptool repository. We don't yet have flash encryption support in esp-serial-flasher, however it will probably be added at some point in the future.

@dobairoland
Copy link
Collaborator

Linking esp-rs/esp-flasher-stub#56 which will add support here.

@ESP32DE
Copy link

ESP32DE commented Aug 11, 2024

@dobairoland ... ESP32-S3-SK , 32MB GD Qflash ( 32MB OctalPSRAM )
Have you already been able to test it on this one? >16MB
JFYI there is also 32MB octal version
( depends on the manufacturer as well as the difference Quad/Octal technology )
grafik

@DNedic DNedic added the Type: Feature Request Feature Request for esp-serial-flasher label Sep 25, 2024
@higaski
Copy link
Contributor Author

higaski commented Nov 4, 2024

@DNedic
Could you give me a quick summery of the current state of 32MB flash support?
Does the original esptool currently support 32MB?
Does the espflash tool yet?

/edit
According to this comment flashing should work above 16MB, but I think there are still some limitations to it. I had almost forgotten about it again, but here I've mentioned that you can't flash app partitions >16MB... it's all very confusing.

@DNedic
Copy link
Collaborator

DNedic commented Nov 4, 2024

Hi @higaski , 32MB chips is supported when using esptool with an ESP32-S3, it should also work with esp-serial-flasher provided you use the legacy flasher stub.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Feature Request Feature Request for esp-serial-flasher
Projects
None yet
Development

No branches or pull requests

7 participants