raburton / rboot

An open source bootloader for the ESP8266
https://richard.burtons.org/tag/rboot/?order=ASC
MIT License
301 stars 72 forks source link

GPIO boot fails #2

Closed riban-bw closed 8 years ago

riban-bw commented 8 years ago

GPIO ROM selection fails to boot a ROM when the following conditions are met:

Boot mode = MODE_GPIO_ROM MODE_GPIO_ROM = 0 romToBoot != 0 GPIO16 = 0

I have three ROMS:

ROM[0] @ 0x002000 ROM[1] @ 0x100000 ROM[2] @ 0x200000

With GPIO16 = 1, I can boot in to any of these ROMs. The code for each is based on the rBoot example code. I can switch between any ROM. If romToBoot = 0 then I can set GPIO16 = 0 and boot in to ROM[0] but with romToBoot set to 1 or 2, GPIO boot fails. Serial output is presented (at 74880 BAUD) thus:

Booting GPIO-selected. Booting rom 0.

which shows the rBoot code is detecting the correct ROM to boot. No further serial output occurs.

I have tried using BOOT_NO_ASM with same result.

raburton commented 8 years ago

I shall have a look...

raburton commented 8 years ago

Tested here, 3 rom config with address as specified above, on a nodemcu dev board v0.9. Works fine. You can boot to rom0 from rom0/rom1/rom2 with the gpio 16 button held down. Of course I do notice one small issue, the sample project reports the running rom in a message on boot, and this doesn't say rom0, it says whichever rom it is configured to boot from if the gpio wasn't pressed (bear that in mind if you are considering using this value in the gpio rom).

rBoot v1.2.1 - richardaburton@gmail.com
Flash Size:   32 Mbit
Flash Mode:   QIO
Flash Speed:  40 MHz
rBoot Option: Big flash

Booting GPIO-selected.
Booting rom 0.
don't use rtc mem data
sd&

rBoot Sample Project

Currently running rom 1.
type "help" and press <enter> for help...
riban-bw commented 8 years ago

Any chance of a copy of of your GPIO test project? This has been baffling me for a couple of days before I figured out the conditions that triggered it. My project consistently behaves as I described. Cheers!

raburton commented 8 years ago

This is quickly hacked together example to test your scenario. I've modified rBoot to enable big flash support, create a default config based on your layout above and 2 second boot delay for connecting your terminal. The sample has been modified to use big flash, 3 switch commands added (switch0, switch1 & switch2) to switch between active roms and linker script modified to suit your flash layout. Just flash rom0.bin to 0x02000 and rom1.rom to 0x100000 & 0x200000. I haven't updated the sample app to support the 3 way ota, but you don't need that to test the gpio boot. https://dl.dropboxusercontent.com/u/5500141/riban.zip

riban-bw commented 8 years ago

Hi! I had to do a bit of tweaking to make this compile, notably that I needed to create libmain2.a which I didn't need to do with the Sming implementation. (Is that still required when using Sming provided rBoot?) Anyway, I am getting similar behaviour. I can boot / switch to any of the three ROMs but when I boot with GPIO16 low, it will only work if ROM0 is preselected. Without ROM0 preselected I get:

Fatal exception (0): epc1=0x4021183b, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

I am using an ESP-12 module.

raburton commented 8 years ago

That's different to before then, because it just stopped previously. The Sming makefile creates libmain2 for you automatically, I didn't know you were using Sming. You were definitely using big flash mode?

So you can boot any of the roms by switching to them manually fine, but only when you boot by gpio do you get this error? That doesn't make a lot of sense, because it's clearly starting the rom ok so I would expect whatever is causing this exception to occur however the rom is started. Once the rom is running there is no difference at all to the rom as to how it was selected. If you'd been getting this error when the rom was started by either method I'd have said that big flash was properly remapping the flash, but if it works on manual rom selection that can't be the case.

riban-bw commented 8 years ago

Quite!!!

Different behaviour may be due to not using Sming. BOOT_BIG_FLASH is enabled.

Manually booting each ROM works so the memory mapping is working fine. It is only when booting with GPIO 16 low that the problem occurs - odd!

I have just flashed the ESP-12 using Arduino framework to prove that booting with GPIO16 low does not adversely affect the run-time code - it doesn't.

I agree this is odd behaviour. I am guessing that the ROM is not started at the correct address for some reason when GPIO boot is triggered but I can't figure out why that would occur and it is odd that you see different behaviour. All serial output supports the second stage loader working fine, I added more debug code which shows the behaviour to appear identical throughout stage 2. I have only just found stage 2a and am looking at that now but for some reason, ets_printf does not work in rboot-stage2a so I am struggling to debug this. (Any clues?)

raburton commented 8 years ago

I'd be reasonably confident that stage2a isn't the problem, it does nothing gpio related and all the checking is done before getting there (as once stage 2a is running we are past the point of no return). If it is called with the same address when started from gpio as from normal mode then I'm pretty sure the problem isn't in rBoot itself.

Just had a thought! Memory mapping uses the same logic as displaying the the currently booted rom at startup in the sample. It reads which rom should have started, not which actually has been in the case of GPIO boot. So it will be mapping the wrong mb! But that really doesn't explain why it worked fine for me! Anyway, I'm sure that must be the issue.

Try adding updateConfig = TRUE; to the gpio boot code in rboot.c (in the block with the "Booting GPIO-selected." message). This will set the current rom in the config to the gpio rom, and so it should then be able to memory map the right mb. The gpio rom will then need to be responsible for switching back to a different rom for next boot.

riban-bw commented 8 years ago

Updating the rBoot config with currentROM = gpioROM works. I was thinking along these lines but can't see where you do the memory mapping. (Maybe I've been staring at this screen too long!) I had some inconsistent results when I first tried this but I went back to my original (Sming) code and it works. Should this patch be applied to your source code? Will you push it upstream to Sming?

Cheers!

raburton commented 8 years ago

Memory mapping is handled by appcode/rboot-bigflash.c which is compiled in the app (not rBoot itself), plus some black magic in the Makefile. I'll sort a patch out, the change in behaviour will need documenting as well, although I don't think many people use the gpio feature. I'll make sure it goes into Sming as well. Thanks for helping track this down.