Discussion:
[srobo-devel] Bootloader progress
Jeremy Morse
2015-09-05 21:59:25 UTC
Permalink
Hi,

One significant problem with the firmware last year is that we skipped
implementing integrity checking due to time pressure, which led to much
suckage later down the line. Essentially, if a bad flash occurred, then
the bootloader would get stuck entering the firmware and crashing.

The solution to this is to crc the firmware image and bake it into the
firmware, then have the bootloader check it before jumping in. This is
now implemented (see the latest power-v4-fw revision). It requires the
bootloader knowing how much flash there is to crc; also due to the
Special way in which the stm32 crc works I've used the Boost library crc
functionality rather than any command line tools. The boot record on a
firmware image now looks like this:

struct {
uint32_t intr_vector_table;
uint32_t entry_addr;
uint32_t crc32;
} foobar;

Of which the crc is read as all-zeros in the crc verification process.
crc.cpp / 'crctool' in the bootloader repo will calculate a crc on a
binary file, and when given the -w option will write in the crc to the
relevant location. For the stm32 / host-pc crcs to agree, I've munged
the linker script to zero-pad the firmware image to fill any spare flash
with zeros.

This leads me on to the binaries that currently get built. They are:
* dfu-bootloader/usb_dfu.elf: An elf image of the bootloader, i.e.
the first 0x2000 bytes of the flash
image
* pbv4_noboot.bin A 24kb binary blob containing the
firmware to flash on via dfu-util,
including crc
* pbv4.elf Combined image of the two above

The last elf file is now a problem, because if you flash it onto a board
it'll boot to the bootloader, but will then fail the fw crc check and
require dfu flashing. This is misleading. We should probably move away
from the highly baked scenario I previously cooked up, and just compile
the power board firmware without any knowledge of the bootloader, just a
modified base address.

One can now flash an all-zeros firmware file to the power board, and
then re-flash it with the correct version, all in software.

~

The only highly dodgy part of all of this is the watchdog, which I've
re-enabled on the power board. The process of writing to flash takes a
long period, and DFU writes in 1kb pages, so I've had to put a
watchdog-reset in the middle of the write-to-flash loop to avoid
spurious resets. This is a bit patch-it-and-see-what-happens, so some
more eyeballs on whether there could be problems elsewhere would be nice.

~

We should move the servo board over to this too; I have no time though.

--
Thanks,
Jeremy
--
You received this message because you are subscribed to the Google Groups "Student Robotics Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to srobo-devel+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Rich Barlow
2015-10-20 22:37:57 UTC
Permalink
Hi Jeremy,

Thank you for implementing this. I witnessed Rob flashing a power board
willy nilly last week with no bricking. I'm looking to get this onto the
Post by Jeremy Morse
The solution to this is to crc the firmware image and bake it into the
firmware, then have the bootloader check it before jumping in. This is
now implemented (see the latest power-v4-fw revision). It requires the
bootloader knowing how much flash there is to crc; also due to the
Special way in which the stm32 crc works I've used the Boost library crc
functionality rather than any command line tools. The boot record on a
struct {
uint32_t intr_vector_table;
uint32_t entry_addr;
uint32_t crc32;
} foobar;
I can't actually see a struct like this anywhere in the power board
source. The closest I can see is at the end of main.c where there's an
array of uint32_ts placed at the start of the 'application' flash by the
linker script. Presumably the CRC does come after this and we're
currently OK because the vector table is 512 byte aligned, meaning that
there's 504 bytes free between the boot record and the vector table?
Post by Jeremy Morse
The only highly dodgy part of all of this is the watchdog, which I've
re-enabled on the power board. The process of writing to flash takes a
long period, and DFU writes in 1kb pages, so I've had to put a
watchdog-reset in the middle of the write-to-flash loop to avoid
spurious resets.
Any idea if this will be an issue on the servo board where we don't
currently use the watchdog?

Rich
--
You received this message because you are subscribed to the Google Groups "Student Robotics Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to srobo-devel+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jeremy Morse
2015-10-20 22:45:54 UTC
Permalink
Hi,
Post by Rich Barlow
Thank you for implementing this. I witnessed Rob flashing a power board
willy nilly last week with no bricking. I'm looking to get this onto the
Fab,
Post by Rich Barlow
Post by Jeremy Morse
struct {
uint32_t intr_vector_table;
uint32_t entry_addr;
uint32_t crc32;
} foobar;
I can't actually see a struct like this anywhere in the power board
source. The closest I can see is at the end of main.c where there's an
array of uint32_ts placed at the start of the 'application' flash by the
linker script. Presumably the CRC does come after this and we're
currently OK because the vector table is 512 byte aligned, meaning that
there's 504 bytes free between the boot record and the vector table?
Yep, that's how it is. In hindsight, this could all be made more
explicit. At the very least adding comments to this effect in the linker
script are probably necessary, as changes there are most likely to cause
breakage.
Post by Rich Barlow
Any idea if this will be an issue on the servo board where we don't
currently use the watchdog?
I haven't tested it. My understanding from the stm32f1 manual [0] is
that register protection is in operation, and that the IWDG won't
actually start unless a special value (0xCCCC) is written to a
particular register. Resetting the counter should have no effect unless
the watchdog is already started, which doesn't happen on the servo board.

Clearly this requires testing, of course.

--
Thanks,
Jeremy
--
You received this message because you are subscribed to the Google Groups "Student Robotics Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to srobo-devel+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jeremy Morse
2015-10-20 22:47:35 UTC
Permalink
[0]
http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf

--
Thanks,
Jeremy
--
You received this message because you are subscribed to the Google Groups "Student Robotics Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to srobo-devel+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...