im-tomu / toboot

Bootloader for the EFM32HG Tomu Board
https://tomu.im/
GNU General Public License v3.0
72 stars 28 forks source link

Cannot boot after flashing #44

Open lealanko-rt opened 5 years ago

lealanko-rt commented 5 years ago

The bootloader cannot boot an application immediately after the bootloader has been flashed and reset. This is a (minor) inconvenience when developing the bootloader.

The problem is that flashing leaves the contents of RAM in an unspecified state with the reset cause SYSREQRST. The bootloader only initializes the boot token when the reset cause is PORST and otherwise assumes that it has valid contents. So what happens is that after flashing the bootloader happily checks the value of boot_count field of the boot token, and this field most probably contains some large value left by the flashing. Hence the application boot is aborted due to BOOT_FAILED_TOO_MANY_TIMES.

To solve this, the bootloader should somehow verify that the boot token contents are valid without depending on the reset cause. Perhaps use some (non-zero) magic value in the magic field of the boot token even when not forcing bootloader entry?

xobs commented 5 years ago

Are you seeing expected behavior?

Toboot entry is forced after updating: https://github.com/im-tomu/tomu-bootloader/blob/master/booster/main.c#L74

The boot_count value out o be 0, which is why the BOOT_FAILED_TOO_MANY_TIMES code is surprising. What is the order of operations that you're doing?

lealanko-rt commented 5 years ago

Sorry, I wasn't clear. I meant the situation when reflashing the bootloader itself using an external programmer.

What I'm doing is that I have both the bootloader and an application already in flash, and then I use OpenOCD and J-Link to flash a new version of the bootloader through the SWD pins, without touching the application. After I reset run in OpenOCD, I expect the bootloader to run and boot the application.

However, the process of reflashing the bootloader through SWD seems to scramble some of the RAM, at least the boot token. I expect the RAM is used as a buffer during flashing, or something. So what happens is that the bootloader looks at the reset cause, and sees that it is not PORST, and therefore expects the boot token to be valid, even though it contains some random fluff after the flashing. (I don't have the exact memory values available right now.)

Everything works fine after power-toggling the device, so it's just an inconvenience for toboot developers.

xobs commented 5 years ago

Since it's generally a 32-bit machine, what if we only consider the boot_count to be valid if board_model is correctly set? Most processes (such as OpenOCD) will overwrite entire words, so those would invalidate the boot_count value as well.

lealanko-rt commented 5 years ago

I feel using an eight-bit number for this purpose is a bit hazardous. And I doubt anything would scramble the second word in RAM while leaving the first one (magic number) intact. So I still think just having a special value in the magic field should be enough.