sw: Fix RAM boot detection

Up until now, docs said that RAM boot happens, when foboot finds
`0x17ab0f23` in first 56 bytes of loaded binary.

That wasn't the case, it was checking only first 12 bytes.
`for` loop did at most `(max_check/4)-1` iterations, which is equal to 15,
because `max_check` has the value of `rx_buffer` size from usb-dev.c.

15 times 4 byte words results in 60 checked bytes, but there was also
division by 4 when accessing items of `dfu_buffer`, which reduced number
of checks to 3.

I also corrected the docs from 56 checked bytes to 60.
This commit is contained in:
Michal Sieron 2022-03-17 16:22:51 +01:00
parent 882ce04da8
commit 21b5f12825
2 changed files with 5 additions and 5 deletions

View File

@ -49,7 +49,7 @@ The timeout must be given in the third (4-byte little-endian) word of the progra
During development, it may be inconvenient to load a program onto SPI flash. Or maybe you want to run something that doesn't modify the contents of SPI. This is possible with `RAM boot`.
If the DFU bootloader encounters the magic number `0x17ab0f23` within the first 56 bytes, then it will enable *RAM boot* mode. In this mode, the SPI flash won't be erased, and the program will be loaded to RAM.
If the DFU bootloader encounters the magic number `0x17ab0f23` within the first 60 bytes, then it will enable *RAM boot* mode. In this mode, the SPI flash won't be erased, and the program will be loaded to RAM.
Note that the value following the magic number indicates the offset where the program will be loaded to. This should be somewhere in RAM. `0x10002000` is a good value, and is guaranteed to not interfere with Foboot itself.

View File

@ -177,12 +177,12 @@ bool dfu_download(unsigned blockNum, unsigned blockLength,
// Check to see if we're writing to RAM instead of SPI flash
if ((blockNum == 0) && (packetOffset == 0) && (packetLength > 0)) {
unsigned int i = 0;
unsigned int max_check = packetLength;
unsigned int max_check = packetLength / 4;
if (max_check > sizeof(dfu_buffer))
max_check = sizeof(dfu_buffer);
for (i = 0; i < (max_check/4)-1; i++) {
if (dfu_buffer[i/4] == RAM_BOOT_SENTINAL) {
ram_mode = dfu_buffer[(i/4)+1];
for (i = 0; i < max_check-1; i++) {
if (dfu_buffer[i] == RAM_BOOT_SENTINAL) {
ram_mode = dfu_buffer[i+1];
break;
}
}