I started experimenting with some bootloader code, and running it in gdb-multiarch, I realized that it hardfaulted right at start. This happened for pico-sdk 2.1.0, and just today I updated to
Then I tried making a minimal reproducible example - and that one, of course, works fine (no hardfault, gdb shows it ultimately settles on the ""while(1){};" line with an infinite loop, as expected). So, that is the one I'm going to be posting - one difference from the use in my real project, is that in the real project this bootloader resides in a subdirectory, and the main project CmakeLists.txt "includes" it via `add_subdirectory` (and therefore the bootloader CMakeLists.txt does not include pico_sdk_init.cmake, and does not call pico_sdk_init()):
main.c
CMakeLists.txt
memmap_copy_to_ram_bl.ld linker script is a copy of memmap_copy_to_ram.ld; instead of posting the whole file which is large-ish, here is the output of `diff -Naur --strip-trailing-cr /src/pico-sdk/src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld memmap_copy_to_ram_bl.ld`:
memmap_defines.ld is just a single line: Here is how I confirm in the debugger that it hardfaults with the real project:
Here is the result of stepping through in debugger - since this is copy_to_ram, we have to have first breakpoint on platform_entry (I have found armex function via Debugging multicore crash - Raspberry Pi Forums):
Well, from what I can tell, it is `platform_entry` or `data_cpy_table` - pico-sdk functions - causing the hardfault?! Hard to believe, yet, there it is ... For reference, this is what `arm-none-eabi-objdump -d --dwarf=follow-links bootload_subdir.elf` gives me for these two functions - I am pretty bad at assembly, but maybe others can recognize something:
So, how can I get this code working without it hardfaulting at the very start?
Then I tried making a minimal reproducible example - and that one, of course, works fine (no hardfault, gdb shows it ultimately settles on the ""while(1){};" line with an infinite loop, as expected). So, that is the one I'm going to be posting - one difference from the use in my real project, is that in the real project this bootloader resides in a subdirectory, and the main project CmakeLists.txt "includes" it via `add_subdirectory` (and therefore the bootloader CMakeLists.txt does not include pico_sdk_init.cmake, and does not call pico_sdk_init()):
main.c
Code:
#include "hardware/clocks.h" // set_sys_clock_pll#include "hardware/structs/bus_ctrl.h" // bus_ctrl_hwuint8_t status = 0;extern char __BOOTLOADER_LENGTH;uint16_t BOOTLOADER_LENGTH;static void setup_hardware( void );int main( void ){ BOOTLOADER_LENGTH = (uint16_t)(((uintptr_t)&__BOOTLOADER_LENGTH) % 0xFFFF); status = 0; setup_hardware(); while(1){};}static void setup_hardware( void ){ set_sys_clock_pll( 1596000000, 6, 2 ); // 133 MHz bus_ctrl_hw->priority = BUSCTRL_BUS_PRIORITY_PROC0_BITS ;}
Code:
cmake_minimum_required(VERSION 3.15)# initialize the SDK directlyinclude($ENV{PICO_SDK_PATH}/pico_sdk_init.cmake)project(my_project)# initialize the Raspberry Pi Pico SDKpico_sdk_init()# rest of your projectset(PICO_COPY_TO_RAM 1)add_compile_options(-Wall -Wno-format # int != int32_t as far as the compiler is concerned because gcc has int32_t as long int -Wno-unused-function # we have some for the docs that aren't called -Wno-maybe-uninitialized -Os # Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.)add_executable(hello_world main.c)pico_set_binary_type(hello_world copy_to_ram)# Add pico_stdlib library which aggregates commonly used featurestarget_link_libraries(hello_world #pico_stdlib #pico_platform pico_standard_link pico_crt0 pico_runtime_headers pico_bootrom pico_runtime hardware_clocks)# create map/bin/hex/uf2 file in addition to ELF.pico_add_extra_outputs(hello_world)pico_minimize_runtime(hello_world EXCLUDE ALL)pico_set_linker_script(hello_world ${CMAKE_CURRENT_SOURCE_DIR}/memmap_copy_to_ram_bl.ld)
Code:
--- /src/pico-sdk/src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld2025-03-02 18:23:01.110668270 +0100+++ memmap_copy_to_ram_bl.ld2025-03-03 01:57:05.521966619 +0100@@ -21,10 +21,13 @@ __stack (== StackTop) */ +/* memmap_defines.ld: __BOOTLOADER_LENGTH ; */+INCLUDE "/home/user/Desktop/test/memmap_defines.ld"+ MEMORY {- INCLUDE "pico_flash_region.ld"- RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k+ FLASH(rx) : ORIGIN = 0x10000000, LENGTH = __BOOTLOADER_LENGTH+ RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k }@@ -180,7 +183,7 @@ .tdata : { . = ALIGN(4);-*(.tdata .tdata.* .gnu.linkonce.td.*)+ *(.tdata .tdata.* .gnu.linkonce.td.*) /* All data end */ __tdata_end = .; } > RAM AT> FLASH@@ -199,7 +202,7 @@ __tls_end = .; } > RAM - .bss : {+ .bss : { . = ALIGN(4); __tbss_end = .; @@ -284,4 +287,3 @@ ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") /* todo assert on extra code */ }-
Code:
__BOOTLOADER_LENGTH = 44k;
Code:
(gdb) rThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/user/Desktop/REAL_project/build/Debug/bootload_subdir/bootload_subdir.elf target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x00000138 msp: 0x20041f00[New Thread 2]Thread 1 received signal SIGTRAP, Trace/breakpoint trap.isr_hardfault () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:170170decl_isr_bkpt isr_hardfault(gdb) bt#0 isr_hardfault () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:170#1 <signal handler called>#2 0x2000012a in spin_locks_reset () at /src/pico-sdk/src/rp2_common/hardware_sync_spin_lock/sync_spin_lock.c:12#3 0x10000226 in platform_entry () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:455Backtrace stopped: previous frame identical to this frame (corrupt stack?)(gdb)
Code:
(gdb) b platform_entryBreakpoint 1 at 0x1000021e: file /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S, line 452.Note: automatically using hardware breakpoints for read-only addresses.(gdb) rThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/user/Desktop/REAL_project/build/Debug/bootload_subdir/bootload_subdir.elf target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x00000138 msp: 0x20041f00[New Thread 2]Thread 1 hit Breakpoint 1, platform_entry () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:452452 ldr r1, =runtime_init(gdb) n453 blx r1(gdb) ntarget halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x00000138 msp: 0x20041f00454 ldr r1, =main(gdb) n455 blx r1(gdb) ntarget halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x00000138 msp: 0x20041f00Thread 1 received signal SIGTRAP, Trace/breakpoint trap.isr_hardfault () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:170170decl_isr_bkpt isr_hardfault(gdb) bt#0 isr_hardfault () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:170#1 <signal handler called>#2 0x2000012a in spin_locks_reset () at /src/pico-sdk/src/rp2_common/hardware_sync_spin_lock/sync_spin_lock.c:12#3 0x10000226 in platform_entry () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:455Backtrace stopped: previous frame identical to this frame (corrupt stack?)(gdb) armexEXEC_RETURN (LR):lr 0xfffffff9 -7Uses MSP 0x20041fe0 return.xPSR 0x21000000ReturnAddress 0x2000012aLR (R14) 0x10000227R12 0x4001801cR3 0x8R2 0x0R1 0x20000111R0 0x0Return instruction: 0x2000012a <spin_locks_reset+18>:pop{r4, pc}LR instruction: 0x10000227 <platform_entry+8>:ldrr1, [pc, #88]; (0x10000280 <data_cpy_table+72>)
Code:
1000021e <platform_entry>:1000021e: 4916 ldr r1, [pc, #88] ; (10000278 <data_cpy_table+0x40>)10000220: 4788 blx r110000222: 4916 ldr r1, [pc, #88] ; (1000027c <data_cpy_table+0x44>)10000224: 4788 blx r110000226: 4916 ldr r1, [pc, #88] ; (10000280 <data_cpy_table+0x48>)10000228: 4788 blx r11000022a: be00 bkpt 0x00001000022c: e7fd b.n 1000022a <platform_entry+0xc>10000238 <data_cpy_table>:10000238: 10000830 .word 0x100008301000023c: 20000650 .word 0x2000065010000240: 20000860 .word 0x2000086010000244: 10000a40 .word 0x10000a4010000248: 20040000 .word 0x200400001000024c: 20040000 .word 0x2004000010000250: 10000a40 .word 0x10000a4010000254: 20041000 .word 0x2004100010000258: 20041000 .word 0x200410001000025c: 00000000 .word 0x0000000010000260: 4770 bx lr10000262: 0000 .short 0x000010000264: 00000000 .word 0x0000000010000268: e000ed08 .word 0xe000ed081000026c: d0000000 .word 0xd000000010000270: 20000860 .word 0x2000086010000274: 200008a0 .word 0x200008a010000278: 20000621 .word 0x200006211000027c: 20000111 .word 0x2000011110000280: 200005e5 .word 0x200005e5
Statistics: Posted by sdbbs — Mon Mar 03, 2025 1:24 am — Replies 2 — Views 76