ducalex / retro-go

Retro emulation for the ODROID-GO and other ESP32 devices
GNU General Public License v2.0
568 stars 130 forks source link

xtensa-esp32-elf/bin/ld: region `iram0_0_seg' overflowed by 16152 bytes #48

Closed mtojek closed 6 months ago

mtojek commented 2 years ago

Unfortunately I can't build the release 1.34 on my ESP32-WROVER 4MB:

$ RG_TOOL_TARGET=mtojek-go ./rg_tool.py build-img launcher retro-run
...
/Users/mtojek/.espressif/tools/xtensa-esp32-elf/esp-2021r2-patch3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: retro-run.elf section `.iram0.text' will not fit in region `iram0_0_seg'
/Users/mtojek/.espressif/tools/xtensa-esp32-elf/esp-2021r2-patch3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: IRAM0 segment data does not fit.
/Users/mtojek/.espressif/tools/xtensa-esp32-elf/esp-2021r2-patch3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: region `iram0_0_seg' overflowed by 16152 bytes
collect2: error: ld returned 1 exit status
make[3]: *** [retro-run.elf] Error 1
make[2]: *** [CMakeFiles/retro-run.elf.dir/all] Error 2
make[1]: *** [CMakeFiles/app.dir/rule] Error 2
make: *** [app] Error 2
make failed with exit code 2
Traceback (most recent call last):
  File "./rg_tool.py", line 333, in <module>
    build_app(app, args.target, command == "profile", args.with_networking)
  File "./rg_tool.py", line 208, in build_app
    subprocess.run("idf.py app", shell=True, check=True, cwd=os.path.join(os.getcwd(), app))
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 512, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command 'idf.py app' returned non-zero exit status 2.

Is there an option to select only NES emulator and Doom :)?

KD-MM2 commented 2 years ago

Hey hey hey, wait. Do you read the README yet? it's clearly written here: https://github.com/ducalex/retro-go#build-everything-and-generate-fw

mtojek commented 2 years ago

I'm afraid that you misunderstood the problem, Cao. Before "retro-run" was introduced, I was able to select emulators like NES, GBC, etc. and Doom. With "retro-run" I can't select single emulators but the whole bundle.

KD-MM2 commented 2 years ago

Please provide your sdkconfig

mtojek commented 2 years ago

Why exactly do you need the sdkconfig? The bug seems to be related with the new bundling scheme, which wasn't present in older revisions.

BTW I was able to prepare .img if I comment out the entire GBC component.

ducalex commented 2 years ago

There is no way to build individually gbc, nes, pce, handy, or gw anymore because it largely doesn't make much sense (combined they're less than 1MB). But the IRAM overflow is interesting and is absolutely a bug that needs fixing.

Can you tell me which esp-idf version you're using? Your sdkconfig could influence this too (if you have IRAM wifi optimization enabled for example), can you confirm you're using retro-go's provided config?

Edit: I might introduce flags to enable/disable individual emulators later on, but for now I'd really prefer if we could fix that IRAM issue.

mtojek commented 2 years ago

There is no way to build individually gbc, nes, pce, handy, or gw anymore because it largely doesn't make much sense (combined they're less than 1MB).

Hi @ducalex. I agree with that statement, but I'm not sure if the IRAM overflow can be easily fixed.

Can you tell me which esp-idf version you're using?

Nothing changed on my end since l started building retro-go. It's 4.4.2.

can you confirm you're using retro-go's provided config?

I guess so. Here is the branch.

ducalex commented 2 years ago

Hi @ducalex. I agree with that statement, but I'm not sure if the IRAM overflow can be easily fixed.

In your case it is easy to fix, you can remove the IRAM_ATTR in gnuboy/cpu.c, it should take care of it. GB will just run a bit slower but you don't seem to want it anyway.

I wasn't able to replicate your issue on 4.4.2 (using current retro-go dev I get 82% IRAM usage) but I'll try building your branch later.

mtojek commented 2 years ago

I wasn't able to replicate your issue on 4.4.2 (using current retro-go dev I get 82% IRAM usage) but I'll try building your branch later.

That's odd. Could you please check also against v4.4.1? Maybe there is something messed up in my workspace.

ducalex commented 2 years ago

The biggest differences when building your branch vs mine on 4.4.1:

Your branch:

            Archive File DRAM .data .rtc.data DRAM .bss .rtc_noinit IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata & .appdesc flash_total
     libesp_hw_support.a        201        16        88           0       14415           0        14720       17468     16656          0       48756
             libc_nano.a       1685         0        38           0       15160           0        16883       26622      1283          0       44750

My branch

            Archive File DRAM .data .rtc.data DRAM .bss .rtc_noinit IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata & .appdesc flash_total
     libesp_hw_support.a        149        16        84           0        8779           0         9028        5038       471          0       14453
             libc_nano.a          4         0         4           0           0           0            8       18261      1193          0       19458

My guess is that you use functions that I do not and it causes extra stuff to get linked in.

KD-MM2 commented 2 years ago

ducalex's repo with 'dev' branch, with

CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"

and no other changes.

build log:

kaotd@Caos-MacBook-Pro ducalex_retro-go % python3 rg_tool.py build-fw launcher retro-run
=== Step: Building ===

Building app 'launcher'
Executing action: app
Running ninja in directory /Users/kaotd/esp/esp-idf/ducalex_retro-go/launcher/build
Executing "ninja app"...
ninja: no work to do.

App build complete. To flash, run this command:
/Users/kaotd/.espressif/python_env/idf4.3_py3.10_env/bin/python ../../components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32  write_flash 0x10000 build/launcher.bin
or run 'idf.py -p (PORT) app-flash'

Patching esp_image_header_t to skip sha256 on boot...  size=768656 done!

Building app 'retro-run'
Executing action: app
Running ninja in directory /Users/kaotd/esp/esp-idf/ducalex_retro-go/retro-run/build
Executing "ninja app"...
ninja: no work to do.

App build complete. To flash, run this command:
/Users/kaotd/.espressif/python_env/idf4.3_py3.10_env/bin/python ../../components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32  write_flash 0x10000 build/retro-run.bin
or run 'idf.py -p (PORT) app-flash'

Patching esp_image_header_t to skip sha256 on boot...  size=605680 done!

=== Step: Packing ===

Building firmware with: launcher retro-run

Running: tools/mkfw.py retro-go_1.35.1-17-g9cb43-dirty_odroid-go.fw 'Retro-Go 1.35.1-17-g9cb43-dirty' assets/icon.raw 0 0 786432 launcher launcher/build/launcher.bin 0 0 655360 retro-run retro-run/build/retro-run.bin
[0]: type=0, subtype=16, size=786432 (97% used), label=launcher
[1]: type=0, subtype=17, size=655360 (92% used), label=retro-run

Total size: 1.375 MB

File 'retro-go_1.35.1-17-g9cb43-dirty_odroid-go.fw' successfully created.

All done!
kaotd@Caos-MacBook-Pro ducalex_retro-go % python3 rg_tool.py build-img launcher retro-run
=== Step: Building ===

Building app 'launcher'
Executing action: app
Running ninja in directory /Users/kaotd/esp/esp-idf/ducalex_retro-go/launcher/build
Executing "ninja app"...
ninja: no work to do.

App build complete. To flash, run this command:
/Users/kaotd/.espressif/python_env/idf4.3_py3.10_env/bin/python ../../components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32  write_flash 0x10000 build/launcher.bin
or run 'idf.py -p (PORT) app-flash'

Patching esp_image_header_t to skip sha256 on boot...  size=768656 done!

Building app 'retro-run'
Executing action: app
Running ninja in directory /Users/kaotd/esp/esp-idf/ducalex_retro-go/retro-run/build
Executing "ninja app"...
ninja: no work to do.

App build complete. To flash, run this command:
/Users/kaotd/.espressif/python_env/idf4.3_py3.10_env/bin/python ../../components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32  write_flash 0x10000 build/retro-run.bin
or run 'idf.py -p (PORT) app-flash'

Patching esp_image_header_t to skip sha256 on boot...  size=605680 done!

=== Step: Packing ===

Building image with: launcher retro-run

Saved image 'retro-go_1.35.1-17-g9cb43-dirty_odroid-go.img' (1507328 bytes)

All done!

PLUS: this make the build fails with your branch: CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 and revert it back to 32768 then the build completed. with ducalex's branch, compile done even with 16384. As ducalex said

you use functions that I do not and it causes extra stuff to get linked in

mtojek commented 2 years ago

@ducalex It looks like there are some differences in sdkconfig: diff. Wild guess, compiler optimizations?

ducalex commented 2 years ago

I can see why you'd want to keep the stack smashing protection and c++ exceptions but CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y isn't terribly helpful (imho) and is probably the thing that affects code size the most.

Please let me know if you find the flag responsible, I could configure our IRAM_ATTR attributes to be disabled when that flag is active. Or at least add a warning in base.sdkconfig.

ducalex commented 2 years ago

Also this is probably part of the issue: CONFIG_SPIRAM_CACHE_WORKAROUND=y because it will force newlib nano to be linked whereas retro-go uses the one in the esp32's ROM.

Edit: instead of enabling the workaround in sdkconfig you could try enabling it just for our code: https://github.com/ducalex/retro-go/commit/0320a731f103d1b448882e163b24686a0be5566c which might be a good enough compromise. This is what I was already doing for DOOM.

mtojek commented 2 years ago

With CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=n and CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y I got:

/Users/mtojek/.espressif/tools/xtensa-esp32-elf/esp-2021r2-patch3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: IRAM0 segment data does not fit.
/Users/mtojek/.espressif/tools/xtensa-esp32-elf/esp-2021r2-patch3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: region `iram0_0_seg' overflowed by 3792 bytes
collect2: error: ld returned 1 exit status
make[3]: *** [retro-run.elf] Error 1

EDIT:

With CONFIG_SPIRAM_CACHE_WORKAROUND=n the problem is gone. I hope that it won't affect other apps...

ducalex commented 6 months ago

This issue is almost 2 years old so I'm going to close it because you seem to have resolve your issue.

I might add a note in the building documentation about avoiding certain things to prevent IRAM explosion (nano newlib, no cache workaround, etc).

If you feel differently for any reason, please feel free to re-open or create an new issue!