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

hw/xtensa/esp32.c: Using the largest flash size by default. (QEMU-103) #68

Closed
wants to merge 1 commit into from

Conversation

listout
Copy link

@listout listout commented Feb 23, 2023

In commit 0152246 4MB (or gd25q32) was being hardcoded, as a result we could not use larger image size could not be used. This PR should fix it, by using the largest available (gd25q64).

Fixes: #66
Signed-off-by: listout listout@protonmail.com

@github-actions github-actions bot changed the title hw/xtensa/esp32.c: Using the largest flash size by default. hw/xtensa/esp32.c: Using the largest flash size by default. (QEMU-103) Feb 23, 2023
@listout
Copy link
Author

listout commented Feb 23, 2023

I might have butchered the commit message, please re-edit it as needed/suitable.

@igrr
Copy link
Member

igrr commented Feb 24, 2023

I've tried this patch, unfortunately for the existing 4 MB binaries QEMU now fails with a "failed to read the initial flash content" error.

I think something like this could help select the flash model automatically based on the binary image size:

From 4270b197ca40333ca3dc0ace16b838724d1761ed Mon Sep 17 00:00:00 2001
From: Ivan Grokhotkov <ivan@espressif.com>
Date: Fri, 24 Feb 2023 21:41:38 +0100
Subject: [PATCH] hw: esp32: select flash model automatically based on the
 binary size

---
 hw/xtensa/esp32.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/hw/xtensa/esp32.c b/hw/xtensa/esp32.c
index cfe1be70de..df849dcd08 100644
--- a/hw/xtensa/esp32.c
+++ b/hw/xtensa/esp32.c
@@ -669,7 +669,19 @@ static void esp32_machine_init_spi_flash(Esp32SocState *ss, BlockBackend* blk)
     /* "main" flash chip is attached to SPI1, CS0 */
     DeviceState *spi_master = DEVICE(&ss->spi[1]);
     BusState* spi_bus = qdev_get_child_bus(spi_master, "spi");
-    DeviceState *flash_dev = qdev_new("gd25q64");
+
+    /* select the flash chip based on the image size */
+    int64_t image_size = blk_getlength(blk);
+    const char* flash_chip_model = NULL;
+    switch (image_size) {
+        case 2 * 1024 * 1024: flash_chip_model = "w25x16"; break;
+        case 4 * 1024 * 1024: flash_chip_model = "gd25q32"; break;
+        case 8 * 1024 * 1024: flash_chip_model = "gd25q64"; break;
+        case 16 * 1024 * 1024: flash_chip_model = "is25lp128"; break;
+        default: error_report("Error: only 2, 4, 8, 16 MB flash images are supported"); return;
+    }
+
+    DeviceState *flash_dev = qdev_new(flash_chip_model);
     qdev_prop_set_drive(flash_dev, "drive", blk);
     qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
     qdev_connect_gpio_out_named(spi_master, SSI_GPIO_CS, 0,
-- 
2.37.1

(these 4 flash models seem to be supported by esp-idf)

In commit
0152246
4MB (or gd25q32) was being hardcoded, as a result we could not use
larger image size (> 4Mb). This PR should fix it, by using the largest
available (gd25q64).

Fixes: espressif#66
Fixes: espressif#17
Signed-off-by: listout <listout@protonmail.com>
@listout
Copy link
Author

listout commented Mar 4, 2023

@igrr I've updated the PR per your suggestion.

@igrr
Copy link
Member

igrr commented Apr 13, 2023

Cherry-picked as 65eec41, thanks @listout!

@AntonGue
Copy link

AntonGue commented Sep 21, 2023

@igrr I have a similar issue, I hope you or someone can help.
I saw that the spi_flash size is now selectable, but I don't know how to do that. I've spend hours trying to figure it out, but with no success.
I even tried to hard code the line:

flash_chip_model = "gd25q64";

right after the switch case, but instead of the 8 MB flash size, that I need, I only get the error:

qemu-system-xtensa -nographic -M esp32 -m 4 -drive file=flash.bin,if=mtd,format=raw Adding SPI flash device qemu-system-xtensa: device requires 8388608 bytes, block backend provides 4194304 bytes

And adding ,size=8M after the raw part, didn't help either, it only tells me, i can use 4M at max.

@igrr
Copy link
Member

igrr commented Sep 21, 2023

@AntonGue What is the size of flash.bin in this case?

@AntonGue
Copy link

@igrr the one I was testing with was only 2 MB, but I need to use one with 8 MB

@igrr
Copy link
Member

igrr commented Sep 21, 2023

I think if you make sure that flash.bin size is 8MB, then QEMU will automatically select the flash chip model with 8MB size. You don't need to add CLI arguments or change the source code in this case.

@AntonGue
Copy link

I've tried that too, but I only get this error:
E (7237) spi_flash: Detected size(4096k) smaller than the size in the binary image header(8192k). Probe failed.

Did I maybe make a mistake when installing qemu?
../configure --target-list=xtensa-softmmu --without-default-features --enable-slirp --enable-gcrypt

@igrr
Copy link
Member

igrr commented Sep 21, 2023

Hmm, that's odd, with a 8MB binary file it works for me... Which QEMU commit are your running?

@lcgamboa
Copy link

Apparently, you are using a flash.bin with the wrong size. Have you used the commands described in the documentation?
Have you used esptool.py to create the flash.bin file ? (as in the lines below?)

cd build
esptool.py --chip esp32 merge_bin --fill-flash-size 8MB -o flash.bin @flash_args

@AntonGue
Copy link

Wait, the binary itself is only 4 MB even though I set Flash size (8 MB) inside the idf.py menuconfig, is that weird? maybe my flash building script is broken?

I'm using the latest commit, and just used git clone https://github.com/espressif/qemu.git to try it from scratch again.

@igrr
Copy link
Member

igrr commented Sep 21, 2023

Wait, the binary itself is only 4 MB even though I set Flash size (8 MB) inside the idf.py menuconfig, is that weird? maybe my flash building script is broken?

Creation of flash.bin is not done by IDF — you must be using a command similar to the one posted by @lcgamboa above, somewhere. IDF generates an application binary file with size equal just to the application size, not flash size.

You need to adjust the command which creates the merged binary, to create an 8MB file instead.

@AntonGue
Copy link

Thank you both, that seems to have been the problem, now it works.

I've tried to build the flash.bin with a script, that I found online, because I didn't know esptool.py is used for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Done Issue is done internally
Projects
None yet
5 participants