<p>Hoernchen has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/simtrace2/+/26463">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">firmware: add crc stub to all dfu apps to ensure reliable loading<br><br>DFU flashing of apps sometimes aborts, and although rare this leads to<br>broken devices if no boot button or serial/jtag access exists, because<br>the bootloader will keep trying to start a half-flashed app that then<br>crashes at some point.<br><br>The easiest fix that works with existing bootloaders is to prepend a<br>small 512 byte stub that calculcates the crc and compares it with the<br>crc calculated at build time, and then either starts the actual app, or<br>sets the dfu flag and resets. This ensures we either have a working,<br>running app, or end up in the bootloader, ready to flash again.<br><br>For obvious reasons this only applies to dfu apps, and not to flash<br>targets like the actual bootloader itself.<br><br>Change-Id: Id6df0486c8b779889d21800dc2441b3aa9af8a5f<br>---<br>M firmware/Makefile<br>M firmware/apps/blupdate/main.c<br>M firmware/libboard/common/resources/sam3s4/dfu.ld<br>M firmware/libboard/common/resources/sam3s4/flash.ld<br>A firmware/libcommon/source/crcstub.c<br>A firmware/misc/crctool<br>A firmware/misc/crctool.c<br>7 files changed, 215 insertions(+), 8 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/simtrace2 refs/changes/63/26463/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/firmware/Makefile b/firmware/Makefile</span><br><span>index c30dc9a..8464a3b 100644</span><br><span>--- a/firmware/Makefile</span><br><span>+++ b/firmware/Makefile</span><br><span>@@ -117,7 +117,7 @@</span><br><span> C_LIBUSB_RT = dfu.c dfu_runtime.c</span><br><span> C_LIBUSB_DFU = dfu.c dfu_desc.c dfu_driver.c</span><br><span> C_LIBCOMMON = string.c stdio.c fputs.c usb_buf.c ringbuffer.c pseudo_talloc.c host_communication.c \</span><br><span style="color: hsl(0, 100%, 40%);">- main_common.c stack_check.c</span><br><span style="color: hsl(120, 100%, 40%);">+ main_common.c stack_check.c crcstub.c</span><br><span> </span><br><span> C_BOARD = $(notdir $(wildcard libboard/common/source/*.c))</span><br><span> C_BOARD += $(notdir $(wildcard libboard/$(BOARD)/source/*.c))</span><br><span>@@ -235,11 +235,14 @@</span><br><span> usbstring/usbstring: usbstring/usbstring.c</span><br><span> gcc $^ -o $@</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+misc/crctool: misc/crctool.c</span><br><span style="color: hsl(120, 100%, 40%);">+ gcc $^ -o $@</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> .PHONY: apps/$(APP)/usb_strings.txt.patched</span><br><span> apps/$(APP)/usb_strings.txt.patched: apps/$(APP)/usb_strings.txt</span><br><span> sed "s/PRODUCT_STRING/$(shell cat libboard/$(BOARD)/product_string.txt)/" $< > $@</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-apps/$(APP)/usb_strings_generated.h: apps/$(APP)/usb_strings.txt.patched usbstring/usbstring</span><br><span style="color: hsl(120, 100%, 40%);">+apps/$(APP)/usb_strings_generated.h: apps/$(APP)/usb_strings.txt.patched usbstring/usbstring misc/crctool</span><br><span> cat $< | usbstring/usbstring > $@</span><br><span> </span><br><span> define RULES</span><br><span>@@ -281,6 +284,8 @@</span><br><span> $(SILENT)$(OBJCOPY) --update-section .blupdate=bin/$(BOARD)-dfu-flash-padded.bin bin/$(BOARD)-blupdate-dfu.elf</span><br><span> $(SILENT)$(OBJCOPY) -O binary bin/$(BOARD)-blupdate-dfu.elf bin/$(BOARD)-blupdate-dfu.bin</span><br><span> endif</span><br><span style="color: hsl(120, 100%, 40%);">+ $(info updating app with crc..)</span><br><span style="color: hsl(120, 100%, 40%);">+ misc/crctool 512 bin/$(BOARD)-$(APP)-dfu.bin</span><br><span> flash: build_flash</span><br><span> #alternate way of embedding: obj file</span><br><span> #ifeq ($(APP), dfu)</span><br><span>diff --git a/firmware/apps/blupdate/main.c b/firmware/apps/blupdate/main.c</span><br><span>index 330d040..3c8e67d 100644</span><br><span>--- a/firmware/apps/blupdate/main.c</span><br><span>+++ b/firmware/apps/blupdate/main.c</span><br><span>@@ -93,8 +93,14 @@</span><br><span> flash_cmd(EFC_FCMD_EA, 0);</span><br><span> #endif</span><br><span> flash_wait_ready();</span><br><span style="color: hsl(0, 100%, 40%);">- for (;;)</span><br><span style="color: hsl(0, 100%, 40%);">- NVIC_SystemReset();</span><br><span style="color: hsl(120, 100%, 40%);">+ for (;;) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* no functon call, since NVIC_SystemReset() might not be inlined! */</span><br><span style="color: hsl(120, 100%, 40%);">+ SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |</span><br><span style="color: hsl(120, 100%, 40%);">+ SCB_AIRCR_SYSRESETREQ_Msk);</span><br><span style="color: hsl(120, 100%, 40%);">+ __DSB();</span><br><span style="color: hsl(120, 100%, 40%);">+ while (1)</span><br><span style="color: hsl(120, 100%, 40%);">+ ;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> </span><br><span> #define MAX_USB_ITER BOARD_MCK / 72 // This should be around a second</span><br><span>diff --git a/firmware/libboard/common/resources/sam3s4/dfu.ld b/firmware/libboard/common/resources/sam3s4/dfu.ld</span><br><span>index 7d896c6..86e6622 100644</span><br><span>--- a/firmware/libboard/common/resources/sam3s4/dfu.ld</span><br><span>+++ b/firmware/libboard/common/resources/sam3s4/dfu.ld</span><br><span>@@ -39,7 +39,8 @@</span><br><span> MEMORY</span><br><span> {</span><br><span> /* reserve the first 16k (= 0x4000) for the DFU bootloader */</span><br><span style="color: hsl(0, 100%, 40%);">- rom (rx) : ORIGIN = 0x00400000 + 16K, LENGTH = 256K - 16K /* flash, 256K */</span><br><span style="color: hsl(120, 100%, 40%);">+ crcstub (rx) : ORIGIN = 0x00400000 + 16K, LENGTH = 512 /* crcstub part */</span><br><span style="color: hsl(120, 100%, 40%);">+ rom (rx) : ORIGIN = 0x00400000 + 16K + 512, LENGTH = 256K - 16K - 512 /* flash, 256K */</span><br><span> /* note: dfudata will be at the start */</span><br><span> ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K /* SRAM, 48K */</span><br><span> }</span><br><span>@@ -47,9 +48,17 @@</span><br><span> /* Section Definitions */ </span><br><span> SECTIONS </span><br><span> { </span><br><span style="color: hsl(0, 100%, 40%);">- .text : </span><br><span style="color: hsl(0, 100%, 40%);">- { </span><br><span style="color: hsl(120, 100%, 40%);">+ .crcstub :</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span> . = ALIGN(4);</span><br><span style="color: hsl(120, 100%, 40%);">+ KEEP(*(.crcstub_table))</span><br><span style="color: hsl(120, 100%, 40%);">+ KEEP(*(.crcstub_code))</span><br><span style="color: hsl(120, 100%, 40%);">+ } > crcstub = 0xff</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ .text :</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ . = ALIGN(512);</span><br><span> _sfixed = .;</span><br><span> KEEP(*(.vectors .vectors.*))</span><br><span> *(.text .text.* .gnu.linkonce.t.*) </span><br><span>@@ -94,7 +103,7 @@</span><br><span> </span><br><span> . = ALIGN(4);</span><br><span> _efixed = .; /* End of text section */</span><br><span style="color: hsl(0, 100%, 40%);">- } > rom</span><br><span style="color: hsl(120, 100%, 40%);">+ } > rom = 0xff</span><br><span> </span><br><span> /DISCARD/ :</span><br><span> {</span><br><span>diff --git a/firmware/libboard/common/resources/sam3s4/flash.ld b/firmware/libboard/common/resources/sam3s4/flash.ld</span><br><span>index 50631c6..b1de154 100644</span><br><span>--- a/firmware/libboard/common/resources/sam3s4/flash.ld</span><br><span>+++ b/firmware/libboard/common/resources/sam3s4/flash.ld</span><br><span>@@ -97,6 +97,8 @@</span><br><span> /DISCARD/ :</span><br><span> {</span><br><span> *(.ARM.exidx)</span><br><span style="color: hsl(120, 100%, 40%);">+ *(.crcstub_table)</span><br><span style="color: hsl(120, 100%, 40%);">+ *(.crcstub_code)</span><br><span> }</span><br><span> </span><br><span> . = ALIGN(4); </span><br><span>diff --git a/firmware/libcommon/source/crcstub.c b/firmware/libcommon/source/crcstub.c</span><br><span>new file mode 100644</span><br><span>index 0000000..b13661b</span><br><span>--- /dev/null</span><br><span>+++ b/firmware/libcommon/source/crcstub.c</span><br><span>@@ -0,0 +1,90 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* SIMtrace 2 firmware crc stub</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom -s.f.m.c. GmbH, Author: Eric Wild <ewild@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * as published by the Free Software Foundation; either version 2</span><br><span style="color: hsl(120, 100%, 40%);">+ * of the License, or (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program; if not, write to the Free Software</span><br><span style="color: hsl(120, 100%, 40%);">+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "board.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "core_cm3.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "usb/device/dfu/dfu.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+* This file is a bit special, everything has to go to specific sections, and no globals are available.</span><br><span style="color: hsl(120, 100%, 40%);">+* No external functions may be called, unless inlining is enforced!</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void crc_check_stub();</span><br><span style="color: hsl(120, 100%, 40%);">+__attribute__((section(".crcstub_table"))) volatile uint32_t crcstub_dummy_table[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ (uint32_t)0xdeadc0de, /* deliberately choose invalid value so unpatched image will not be started */</span><br><span style="color: hsl(120, 100%, 40%);">+ (uint32_t)crc_check_stub, /* must be valid flash addr */</span><br><span style="color: hsl(120, 100%, 40%);">+ (uint32_t)0xf1, /* crc value calculated by the host */</span><br><span style="color: hsl(120, 100%, 40%);">+ (uint32_t)0xf2, /* crc calc start address */</span><br><span style="color: hsl(120, 100%, 40%);">+ (uint32_t)0xf3 /* crc calc length (byte) */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+__attribute__((section(".crcstub_code"))) static void do_crc32(int8_t c, uint32_t *crc_reg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int32_t i, mask;</span><br><span style="color: hsl(120, 100%, 40%);">+ *crc_reg ^= c;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (unsigned int j = 0; j < 8; j++)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*crc_reg & 1)</span><br><span style="color: hsl(120, 100%, 40%);">+ *crc_reg = (*crc_reg >> 1) ^ 0xEDB88320;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ *crc_reg = *crc_reg >> 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+__attribute__((section(".crcstub_code"), noinline)) static void crc_check_stub()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t crc_reg = 0xffffffff;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t expected_crc_val = crcstub_dummy_table[2];</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *crc_calc_startaddr = (uint8_t *)crcstub_dummy_table[3];</span><br><span style="color: hsl(120, 100%, 40%);">+ volatile uint32_t *actual_exc_tbl = (volatile uint32_t *)crc_calc_startaddr;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t crc_len = crcstub_dummy_table[4];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 4000ms wdt tickling */</span><br><span style="color: hsl(120, 100%, 40%);">+ WDT->WDT_MR = WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT | (((4000UL << 8) / 1000) << 16) |</span><br><span style="color: hsl(120, 100%, 40%);">+ ((4000UL << 8) / 1000);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (uint8_t *i = crc_calc_startaddr; i < crc_calc_startaddr + crc_len; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+ do_crc32(*i, &crc_reg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ crc_reg = ~crc_reg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (crc_reg == expected_crc_val) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* this looks a bit awkward because we have to ensure the bx does not require a sp-relative load */</span><br><span style="color: hsl(120, 100%, 40%);">+ __asm__ volatile("\</span><br><span style="color: hsl(120, 100%, 40%);">+ mov r0, %0;\n\</span><br><span style="color: hsl(120, 100%, 40%);">+ mov r1, %1;\n\</span><br><span style="color: hsl(120, 100%, 40%);">+ MSR msp,r0;\n\</span><br><span style="color: hsl(120, 100%, 40%);">+ bx r1;"</span><br><span style="color: hsl(120, 100%, 40%);">+ :</span><br><span style="color: hsl(120, 100%, 40%);">+ : "r"(actual_exc_tbl[0]), "r"(actual_exc_tbl[1]));</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* no globals ! */</span><br><span style="color: hsl(120, 100%, 40%);">+ ((struct dfudata *)0x20000000)->magic = USB_DFU_MAGIC;</span><br><span style="color: hsl(120, 100%, 40%);">+ __DSB();</span><br><span style="color: hsl(120, 100%, 40%);">+ for (;;) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* no functon call, since NVIC_SystemReset() might not be inlined! */</span><br><span style="color: hsl(120, 100%, 40%);">+ SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |</span><br><span style="color: hsl(120, 100%, 40%);">+ SCB_AIRCR_SYSRESETREQ_Msk);</span><br><span style="color: hsl(120, 100%, 40%);">+ __DSB();</span><br><span style="color: hsl(120, 100%, 40%);">+ while (1)</span><br><span style="color: hsl(120, 100%, 40%);">+ ;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/firmware/misc/crctool b/firmware/misc/crctool</span><br><span>new file mode 100755</span><br><span>index 0000000..07f9592</span><br><span>--- /dev/null</span><br><span>+++ b/firmware/misc/crctool</span><br><span>Binary files differ</span><br><span>diff --git a/firmware/misc/crctool.c b/firmware/misc/crctool.c</span><br><span>new file mode 100644</span><br><span>index 0000000..41ad3cf</span><br><span>--- /dev/null</span><br><span>+++ b/firmware/misc/crctool.c</span><br><span>@@ -0,0 +1,95 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* SIMtrace 2 firmware crc tool</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom -s.f.m.c. GmbH, Author: Eric Wild <ewild@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * as published by the Free Software Foundation; either version 2</span><br><span style="color: hsl(120, 100%, 40%);">+ * of the License, or (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program; if not, write to the Free Software</span><br><span style="color: hsl(120, 100%, 40%);">+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void do_crc32(int8_t c, uint32_t *crc_reg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int32_t i, mask;</span><br><span style="color: hsl(120, 100%, 40%);">+ *crc_reg ^= c;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (unsigned int j = 0; j < 8; j++)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*crc_reg & 1)</span><br><span style="color: hsl(120, 100%, 40%);">+ *crc_reg = (*crc_reg >> 1) ^ 0xEDB88320;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ *crc_reg = *crc_reg >> 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int main(int argc, char *argv[])</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t crc_reg = 0xffffffff;</span><br><span style="color: hsl(120, 100%, 40%);">+ long fsize;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *buffer;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t crc_start_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (argc < 3) {</span><br><span style="color: hsl(120, 100%, 40%);">+ perror("usage: crctool startoffset blupdate.bin");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ crc_start_offset = strtoull(argv[1], 0, 10);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ FILE *blfile = fopen(argv[2], "rb+");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (blfile == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+ perror("error opening file!");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fseek(blfile, 0, SEEK_END);</span><br><span style="color: hsl(120, 100%, 40%);">+ fsize = ftell(blfile);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (fsize <= crc_start_offset) {</span><br><span style="color: hsl(120, 100%, 40%);">+ perror("file size?!");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fseek(blfile, 0, SEEK_SET);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ buffer = malloc(fsize);</span><br><span style="color: hsl(120, 100%, 40%);">+ fread(buffer, 1, fsize, blfile);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*(uint32_t *)buffer != 0xdeadc0de) {</span><br><span style="color: hsl(120, 100%, 40%);">+ perror("weird magic, not a valid blupdate file?");</span><br><span style="color: hsl(120, 100%, 40%);">+ free(buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *startaddr = buffer + crc_start_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *endaddr = buffer + fsize;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (uint8_t *i = startaddr; i < endaddr; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ do_crc32(*i, &crc_reg);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ crc_reg = ~crc_reg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, "len: %ld crc: %.8x\n", fsize - crc_start_offset, crc_reg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ((uint32_t *)buffer)[0] = 0x2000baa0; /* fix magic to valid stack address, checked by BL */</span><br><span style="color: hsl(120, 100%, 40%);">+ ((uint32_t *)buffer)[2] = crc_reg;</span><br><span style="color: hsl(120, 100%, 40%);">+ ((uint32_t *)buffer)[3] = 0x00400000 + 0x4000 + crc_start_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+ ((uint32_t *)buffer)[4] = fsize - crc_start_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fseek(blfile, 0, SEEK_SET);</span><br><span style="color: hsl(120, 100%, 40%);">+ fwrite(buffer, 4, 5, blfile);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fclose(blfile);</span><br><span style="color: hsl(120, 100%, 40%);">+ free(buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/simtrace2/+/26463">change 26463</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/simtrace2/+/26463"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: simtrace2 </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Id6df0486c8b779889d21800dc2441b3aa9af8a5f </div>
<div style="display:none"> Gerrit-Change-Number: 26463 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Hoernchen <ewild@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>