My overall goal is to be able to calculate a checksum using the on chip CRC peripheral so that I can verify that the binary was correctly flashed to the board. I've got a working python script which just copies exactly what the CRC peripheral is doing, which I then feed the .bin file to get a checksum from.
In trying to get my script working I've noticed that there are 8 bytes of space in between the .isr_vector section and the .text section that is not matching up between the flashed memory and the binary itself. When debugging on the chip these 8 bytes are all 0xFF but in the binary they are 0x00. I know that the chip defaults to all 1s so I have a vague idea why the two are different (or at least I think I do), but I don't know why that space is even there to begin with.
I spent the better part of yesterday evening playing with the linker script, moving the alignment flags around and playing with the fill/padding values. Using "FILL(0xFF);" does not effect that space, neither does putting "=0xFF" at the end of the section. The alignment flags do move things around but they don't have any effect on the space. I was able to get it filled (and also to finally verify my script matches the CRC peripheral) by putting "BYTE(0xFF);" 8 times at the end of the section, but that just looks like a hacky work around to me.
What is this space, why is it there, how do I get rid of it gracefully, will there be consequences for doing so?
My linker script with my hacky fix in it. If you remove lines 29-38 the "space" appears. This was originally generated by CubeIDE but I've been poking at it quite a bit since. This is my first meaningful foray into liker scripts so I may be doing things terribly wrong.
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */
/* Usedd to generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
_code_size = SIZEOF(.isr_vector) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.ARM);
vector_size = SIZEOF(.isr_vector);
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
KEEP(*(.isr_vector)) /* Startup code */
/* These are the 8 bytes that "fix" the problem, without these the space is filled with zeros */
BYTE(0xFF);
BYTE(0xFF);
BYTE(0xFF);
BYTE(0xFF);
BYTE(0xFF);
BYTE(0xFF);
BYTE(0xFF);
BYTE(0xFF);
} >FLASH =0xEE
/* The program code and other data goes into FLASH */
.text : ALIGN(4)
{
BYTE(vector_size);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH =0xEE
/* Constant data goes into FLASH */
.rodata : ALIGN(4)
{
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
} >FLASH =0xEE
.ARM (READONLY) : ALIGN(4)
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH =0xEE
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 :
{
*(.ARM.attributes)
}
}
Here is the start of my code, It's also mostly generated by CubeIDE with some minor modifications.
.syntax unified
.cpu cortex-m4
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
.equ BootRAM, 0xF1E0F85F
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr r0, =_estack
mov sp, r0 /* set stack pointer */
/* Call the clock system initialization function.*/
bl SystemInit
/* Copy the data segment initializers from flash to SRAM */
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
movs r3, #0
b LoopCopyDataInit
CopyDataInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyDataInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyDataInit
/* Zero fill the bss segment. */
ldr r2, =_sbss
ldr r4, =_ebss
movs r3, #0
b LoopFillZerobss
FillZerobss:
str r3, [r2]
adds r2, r2, #4
LoopFillZerobss:
cmp r2, r4
bcc FillZerobss
/* Call static constructors */
bl __libc_init_array
/* Call the application's entry point.*/
bl main
LoopForever:
b LoopForever
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex-M4. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word WWDG_IRQHandler
.word PVD_PVM_IRQHandler
.word RTC_TAMP_LSECSS_IRQHandler
.word RTC_WKUP_IRQHandler
.word FLASH_IRQHandler
.word RCC_IRQHandler
.word EXTI0_IRQHandler
.word EXTI1_IRQHandler
.word EXTI2_IRQHandler
.word EXTI3_IRQHandler
.word EXTI4_IRQHandler
.word DMA1_Channel1_IRQHandler
.word DMA1_Channel2_IRQHandler
.word DMA1_Channel3_IRQHandler
.word DMA1_Channel4_IRQHandler
.word DMA1_Channel5_IRQHandler
.word DMA1_Channel6_IRQHandler
.word 0
.word ADC1_2_IRQHandler
.word USB_HP_IRQHandler
.word USB_LP_IRQHandler
.word can_isr
.word can_isr
.word EXTI9_5_IRQHandler
.word TIM1_BRK_TIM15_IRQHandler
.word TIM1_UP_TIM16_IRQHandler
.word TIM1_TRG_COM_TIM17_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler
.word I2C1_EV_IRQHandler
.word I2C1_ER_IRQHandler
.word I2C2_EV_IRQHandler
.word I2C2_ER_IRQHandler
.word SPI1_IRQHandler
.word SPI2_IRQHandler
.word USART1_IRQHandler
.word USART2_IRQHandler
.word USART3_IRQHandler
.word EXTI15_10_IRQHandler
.word RTC_Alarm_IRQHandler
.word USBWakeUp_IRQHandler
.word TIM8_BRK_IRQHandler
.word TIM8_UP_IRQHandler
.word TIM8_TRG_COM_IRQHandler
.word TIM8_CC_IRQHandler
.word 0
.word 0
.word LPTIM1_IRQHandler
.word 0
.word SPI3_IRQHandler
.word UART4_IRQHandler
.word 0
.word TIM6_DAC_IRQHandler
.word TIM7_IRQHandler
.word DMA2_Channel1_IRQHandler
.word DMA2_Channel2_IRQHandler
.word DMA2_Channel3_IRQHandler
.word DMA2_Channel4_IRQHandler
.word DMA2_Channel5_IRQHandler
.word 0
.word 0
.word UCPD1_IRQHandler
.word COMP1_2_3_IRQHandler
.word COMP4_IRQHandler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word CRS_IRQHandler
.word SAI1_IRQHandler
.word 0
.word 0
.word 0
.word 0
.word FPU_IRQHandler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word RNG_IRQHandler
.word LPUART1_IRQHandler
.word I2C3_EV_IRQHandler
.word I2C3_ER_IRQHandler
.word DMAMUX_OVR_IRQHandler
.word 0
.word 0
.word DMA2_Channel6_IRQHandler
.word 0
.word 0
.word CORDIC_IRQHandler
.word FMAC_IRQHandler
.size g_pfnVectors, .-g_pfnVectors
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak WWDG_IRQHandler
.thumb_set WWDG_IRQHandler,Default_Handler
.weak PVD_PVM_IRQHandler
.thumb_set PVD_PVM_IRQHandler,Default_Handler
.weak RTC_TAMP_LSECSS_IRQHandler
.thumb_set RTC_TAMP_LSECSS_IRQHandler,Default_Handler
.weak RTC_WKUP_IRQHandler
.thumb_set RTC_WKUP_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak RCC_IRQHandler
.thumb_set RCC_IRQHandler,Default_Handler
.weak EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler
.weak EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler
.weak EXTI2_IRQHandler
.thumb_set EXTI2_IRQHandler,Default_Handler
.weak EXTI3_IRQHandler
.thumb_set EXTI3_IRQHandler,Default_Handler
.weak EXTI4_IRQHandler
.thumb_set EXTI4_IRQHandler,Default_Handler
.weak DMA1_Channel1_IRQHandler
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
.weak DMA1_Channel2_IRQHandler
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
.weak DMA1_Channel3_IRQHandler
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
.weak DMA1_Channel4_IRQHandler
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
.weak DMA1_Channel5_IRQHandler
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
.weak DMA1_Channel6_IRQHandler
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
.weak ADC1_2_IRQHandler
.thumb_set ADC1_2_IRQHandler,Default_Handler
.weak USB_HP_IRQHandler
.thumb_set USB_HP_IRQHandler,Default_Handler
.weak USB_LP_IRQHandler
.thumb_set USB_LP_IRQHandler,Default_Handler
.weak can_isr
.thumb_set can_isr,Default_Handler
.weak EXTI9_5_IRQHandler
.thumb_set EXTI9_5_IRQHandler,Default_Handler
.weak TIM1_BRK_TIM15_IRQHandler
.thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler
.weak TIM1_UP_TIM16_IRQHandler
.thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler
.weak TIM1_TRG_COM_TIM17_IRQHandler
.thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler
.weak TIM1_CC_IRQHandler
.thumb_set TIM1_CC_IRQHandler,Default_Handler
.weak TIM2_IRQHandler
.thumb_set TIM2_IRQHandler,Default_Handler
.weak TIM3_IRQHandler
.thumb_set TIM3_IRQHandler,Default_Handler
.weak TIM4_IRQHandler
.thumb_set TIM4_IRQHandler,Default_Handler
.weak I2C1_EV_IRQHandler
.thumb_set I2C1_EV_IRQHandler,Default_Handler
.weak I2C1_ER_IRQHandler
.thumb_set I2C1_ER_IRQHandler,Default_Handler
.weak I2C2_EV_IRQHandler
.thumb_set I2C2_EV_IRQHandler,Default_Handler
.weak I2C2_ER_IRQHandler
.thumb_set I2C2_ER_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak USART3_IRQHandler
.thumb_set USART3_IRQHandler,Default_Handler
.weak EXTI15_10_IRQHandler
.thumb_set EXTI15_10_IRQHandler,Default_Handler
.weak RTC_Alarm_IRQHandler
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
.weak USBWakeUp_IRQHandler
.thumb_set USBWakeUp_IRQHandler,Default_Handler
.weak TIM8_BRK_IRQHandler
.thumb_set TIM8_BRK_IRQHandler,Default_Handler
.weak TIM8_UP_IRQHandler
.thumb_set TIM8_UP_IRQHandler,Default_Handler
.weak TIM8_TRG_COM_IRQHandler
.thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler
.weak TIM8_CC_IRQHandler
.thumb_set TIM8_CC_IRQHandler,Default_Handler
.weak LPTIM1_IRQHandler
.thumb_set LPTIM1_IRQHandler,Default_Handler
.weak SPI3_IRQHandler
.thumb_set SPI3_IRQHandler,Default_Handler
.weak UART4_IRQHandler
.thumb_set UART4_IRQHandler,Default_Handler
.weak TIM6_DAC_IRQHandler
.thumb_set TIM6_DAC_IRQHandler,Default_Handler
.weak TIM7_IRQHandler
.thumb_set TIM7_IRQHandler,Default_Handler
.weak DMA2_Channel1_IRQHandler
.thumb_set DMA2_Channel1_IRQHandler,Default_Handler
.weak DMA2_Channel2_IRQHandler
.thumb_set DMA2_Channel2_IRQHandler,Default_Handler
.weak DMA2_Channel3_IRQHandler
.thumb_set DMA2_Channel3_IRQHandler,Default_Handler
.weak DMA2_Channel4_IRQHandler
.thumb_set DMA2_Channel4_IRQHandler,Default_Handler
.weak DMA2_Channel5_IRQHandler
.thumb_set DMA2_Channel5_IRQHandler,Default_Handler
.weak UCPD1_IRQHandler
.thumb_set UCPD1_IRQHandler,Default_Handler
.weak COMP1_2_3_IRQHandler
.thumb_set COMP1_2_3_IRQHandler,Default_Handler
.weak COMP4_IRQHandler
.thumb_set COMP4_IRQHandler,Default_Handler
.weak CRS_IRQHandler
.thumb_set CRS_IRQHandler,Default_Handler
.weak SAI1_IRQHandler
.thumb_set SAI1_IRQHandler,Default_Handler
.weak FPU_IRQHandler
.thumb_set FPU_IRQHandler,Default_Handler
.weak RNG_IRQHandler
.thumb_set RNG_IRQHandler,Default_Handler
.weak LPUART1_IRQHandler
.thumb_set LPUART1_IRQHandler,Default_Handler
.weak I2C3_EV_IRQHandler
.thumb_set I2C3_EV_IRQHandler,Default_Handler
.weak I2C3_ER_IRQHandler
.thumb_set I2C3_ER_IRQHandler,Default_Handler
.weak DMAMUX_OVR_IRQHandler
.thumb_set DMAMUX_OVR_IRQHandler,Default_Handler
.weak DMA2_Channel6_IRQHandler
.thumb_set DMA2_Channel6_IRQHandler,Default_Handler
.weak CORDIC_IRQHandler
.thumb_set CORDIC_IRQHandler,Default_Handler
.weak FMAC_IRQHandler
.thumb_set FMAC_IRQHandler,Default_Handler
I'm using MSYS2 GCC version 14.1.0 to compile and link for an STMG4 MCU.
I'm using make to build, the command make is running to link is:
gcc -O0 -g3 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Wall -MMD -fdata-sections -ffunction-sections ${INCLUDE_FLAGS} -DSTM32G431xx -DUSE_HAL_DRIVER -T "${LINKER_SCRIPT}" --specs=nano.specs -Wl,-Map=${OUTPUT_DIR}${SOFTWARE_VERSION}.map -Wl,--gc-sections -Wl,--start-group -lc -lm -Wl,--end-group -Wl,-static ${addprefix ${OBJECT_DIR}, ${OBJECTS}} -o ${OUTPUT_DIR}${SOFTWARE_VERSION}.elf
This is the map file after removing practically all of the code aside from the startup assembly shown earlier, an empty main function, and an empty SystemInit function (called at line 40 of the startup assembly file). Something I did while removing all the other code seems to have fixed my problem, I still haven't figured out why quite yet though.
0x20008000 _estack = (ORIGIN (RAM) + LENGTH (RAM))
0x00000200 _Min_Heap_Size = 0x200
0x00000400 _Min_Stack_Size = 0x400
0x000002ac _code_size = (((SIZEOF (.isr_vector) + SIZEOF (.text)) + SIZEOF (.rodata)) + SIZEOF (.ARM))
0x000001d8 vector_size = SIZEOF (.isr_vector)
.isr_vector 0x08000000 0x1d8
*(.isr_vector)
.isr_vector 0x08000000 0x1d8 build/obj/startup_stm32g431kbtx.o
0x08000000 g_pfnVectors
.text 0x080001d8 0xd4
*(.text)
*(.text*)
.text.__libc_init_array
0x080001d8 0x48 C:\...d\libc_nano.a(libc_a-init.o)
0x080001d8 __libc_init_array
.text.main 0x08000220 0x10 build/obj/main.o
0x08000220 main
.text.SystemInit
0x08000230 0xe build/obj/main.o
0x08000230 SystemInit
*fill* 0x0800023e 0x2 ee
.text.Reset_Handler
0x08000240 0x50 build/obj/startup_stm32g431kbtx.o
0x08000240 Reset_Handler
.text.Default_Handler
0x08000290 0x2 build/obj/startup_stm32g431kbtx.o
0x08000290 RTC_Alarm_IRQHandler
0x08000290 EXTI2_IRQHandler
0x08000290 TIM8_TRG_COM_IRQHandler
0x08000290 TIM8_CC_IRQHandler
0x08000290 DebugMon_Handler
0x08000290 TIM1_CC_IRQHandler
0x08000290 HardFault_Handler
0x08000290 USB_HP_IRQHandler
0x08000290 CORDIC_IRQHandler
0x08000290 SysTick_Handler
0x08000290 PendSV_Handler
0x08000290 NMI_Handler
0x08000290 EXTI3_IRQHandler
0x08000290 I2C3_ER_IRQHandler
0x08000290 EXTI0_IRQHandler
0x08000290 I2C2_EV_IRQHandler
0x08000290 FPU_IRQHandler
0x08000290 TIM1_UP_TIM16_IRQHandler
0x08000290 UsageFault_Handler
0x08000290 ADC1_2_IRQHandler
0x08000290 SPI1_IRQHandler
0x08000290 TIM6_DAC_IRQHandler
0x08000290 TIM8_UP_IRQHandler
0x08000290 DMA2_Channel2_IRQHandler
0x08000290 DMA1_Channel4_IRQHandler
0x08000290 USART3_IRQHandler
0x08000290 TIM4_IRQHandler
0x08000290 DMA2_Channel1_IRQHandler
0x08000290 I2C1_EV_IRQHandler
0x08000290 DMA1_Channel6_IRQHandler
0x08000290 UART4_IRQHandler
0x08000290 DMA2_Channel4_IRQHandler
0x08000290 TIM3_IRQHandler
0x08000290 RCC_IRQHandler
0x08000290 DMA1_Channel1_IRQHandler
0x08000290 Default_Handler
0x08000290 RTC_TAMP_LSECSS_IRQHandler
0x08000290 FMAC_IRQHandler
0x08000290 EXTI15_10_IRQHandler
0x08000290 TIM7_IRQHandler
0x08000290 UCPD1_IRQHandler
0x08000290 I2C3_EV_IRQHandler
0x08000290 EXTI9_5_IRQHandler
0x08000290 RTC_WKUP_IRQHandler
0x08000290 PVD_PVM_IRQHandler
0x08000290 SPI2_IRQHandler
0x08000290 MemManage_Handler
0x08000290 can_isr
0x08000290 SVC_Handler
0x08000290 DMA2_Channel5_IRQHandler
0x08000290 CRS_IRQHandler
0x08000290 DMA1_Channel5_IRQHandler
0x08000290 USB_LP_IRQHandler
0x08000290 EXTI4_IRQHandler
0x08000290 RNG_IRQHandler
0x08000290 TIM1_TRG_COM_TIM17_IRQHandler
0x08000290 DMA1_Channel3_IRQHandler
0x08000290 WWDG_IRQHandler
0x08000290 LPUART1_IRQHandler
0x08000290 DMA2_Channel6_IRQHandler
0x08000290 TIM2_IRQHandler
0x08000290 COMP1_2_3_IRQHandler
0x08000290 EXTI1_IRQHandler
0x08000290 USART2_IRQHandler
0x08000290 I2C2_ER_IRQHandler
0x08000290 DMA1_Channel2_IRQHandler
0x08000290 TIM8_BRK_IRQHandler
0x08000290 FLASH_IRQHandler
0x08000290 BusFault_Handler
0x08000290 USART1_IRQHandler
0x08000290 SPI3_IRQHandler
0x08000290 I2C1_ER_IRQHandler
0x08000290 LPTIM1_IRQHandler
0x08000290 DMAMUX_OVR_IRQHandler
0x08000290 USBWakeUp_IRQHandler
0x08000290 SAI1_IRQHandler
0x08000290 DMA2_Channel3_IRQHandler
0x08000290 COMP4_IRQHandler
0x08000290 TIM1_BRK_TIM15_IRQHandler
*(.init)
*fill* 0x08000292 0x2 ee
.init 0x08000294 0x4 C:/.../crti.o
0x08000294 _init
.init 0x08000298 0x8 C:/.../crtn.o
*(.fini)
.fini 0x080002a0 0x4 C:/.../crti.o
0x080002a0 _fini
.fini 0x080002a4 0x8 C:/.../crtn.o
0x080002ac . = ALIGN (0x4)
0x080002ac _etext = .
.glue_7 0x080002ac 0x0
.glue_7 0x080002ac 0x0 linker stubs
.glue_7t 0x080002ac 0x0
.glue_7t 0x080002ac 0x0 linker stubs
.vfp11_veneer 0x080002ac 0x0
.vfp11_veneer 0x080002ac 0x0 linker stubs
.v4_bx 0x080002ac 0x0
.v4_bx 0x080002ac 0x0 linker stubs
.iplt 0x080002ac 0x0
.iplt 0x080002ac 0x0 C:/...\libc_nano.a(libc_a-init.o)
.rel.dyn 0x080002ac 0x0
.rel.iplt 0x080002ac 0x0 C:/...\libc_nano.a(libc_a-init.o)
.rodata
*(.rodata)
*(.rodata*)
.ARM 0x080002ac 0x0
0x080002ac __exidx_start = .
*(.ARM.exidx*)
0x080002ac __exidx_end = .
0x080002ac _sidata = LOADADDR (.data)
.data 0x20000000 0x0 load address 0x080002ac
0x20000000 . = ALIGN (0x4)
0x20000000 _sdata = .
*(.data)
*(.data*)
0x20000000 . = ALIGN (0x4)
0x20000000 _edata = .
.igot.plt 0x20000000 0x0 load address 0x080002ac
.igot.plt 0x20000000 0x0 C:/...\libc_nano.a(libc_a-init.o)
0x20000000 . = ALIGN (0x4)
.bss 0x20000000 0x0 load address 0x080002ac
0x20000000 _sbss = .
0x20000000 __bss_start__ = _sbss
*(.bss)
*(.bss*)
*(COMMON)
0x20000000 . = ALIGN (0x4)
0x20000000 _ebss = .
0x20000000 __bss_end__ = _ebss
._user_heap_stack
0x20000000 0x600 load address 0x080002ac
0x20000000 . = ALIGN (0x8)
[!provide] PROVIDE (end = .)
[!provide] PROVIDE (_end = .)
0x20000200 . = (. + _Min_Heap_Size)
*fill* 0x20000000 0x200
0x20000600 . = (. + _Min_Stack_Size)
*fill* 0x20000200 0x400
0x20000600 . = ALIGN (0x8)
/DISCARD/
libc.a(*)
libm.a(*)
libgcc.a(*)
.ARM.attributes
0x00000000 0x30
*(.ARM.attributes)
.ARM.attributes
0x00000000 0x22 C:/.../crti.o
.ARM.attributes
0x00000022 0x34 C:/...\libc_nano.a(libc_a-init.o)
.ARM.attributes
0x00000056 0x34 build/obj/main.o
.ARM.attributes
0x0000008a 0x21 build/obj/startup_stm32g431kbtx.o
.ARM.attributes
0x000000ab 0x22 C:/.../crtn.o
OUTPUT(build/VERSION0/VERSION0.elf elf32-littlearm)
LOAD linker stubs
LOAD C:/...\libc.a
LOAD C:/...\libm.a
LOAD C:/...\libgcc.a
.debug_frame 0x00000000 0x7c
.debug_frame 0x00000000 0x2c C:/...\libc_nano.a(libc_a-init.o)
.debug_frame 0x0000002c 0x50 build/obj/main.o
.debug_info 0x00000000 0x8a
.debug_info 0x00000000 0x5a build/obj/main.o
.debug_info 0x0000005a 0x30 build/obj/startup_stm32g431kbtx.o
.debug_abbrev 0x00000000 0x79
.debug_abbrev 0x00000000 0x55 build/obj/main.o
.debug_abbrev 0x00000055 0x24 build/obj/startup_stm32g431kbtx.o
.debug_aranges 0x00000000 0x50
.debug_aranges
0x00000000 0x28 build/obj/main.o
.debug_aranges
0x00000028 0x28 build/obj/startup_stm32g431kbtx.o
.debug_rnglists
0x00000000 0x32
.debug_rnglists
0x00000000 0x19 build/obj/main.o
.debug_rnglists
0x00000019 0x19 build/obj/startup_stm32g431kbtx.o
.debug_macro 0x00000000 0xac9
.debug_macro 0x00000000 0x1b build/obj/main.o
.debug_macro 0x0000001b 0xaae build/obj/main.o
.debug_line 0x00000000 0xce
.debug_line 0x00000000 0x53 build/obj/main.o
.debug_line 0x00000053 0x7b build/obj/startup_stm32g431kbtx.o
.debug_str 0x00000000 0x2e0b
.debug_str 0x00000000 0x2dcf build/obj/main.o
.debug_str 0x00002dcf 0x3c build/obj/startup_stm32g431kbtx.o
0x7c (size before relaxing)
.comment 0x00000000 0x43
.comment 0x00000000 0x43 build/obj/main.o
0x44 (size before relaxing)
.debug_line_str
0x00000000 0x60
.debug_line_str
0x00000000 0x60 build/obj/startup_stm32g431kbtx.o
What is this space, why is it there, how do I get rid of it gracefully, will there be consequences for doing so?
.text : ALIGN(4)
This sets the section at a new address ALIGN(4). There is no data defined in between. When you output to a binary the fill of undefined space is 0x00 by default. If you created an 'ihex' or other output format, it would just skip the space.
Something I did while removing all the other code seems to have fixed my problem, I still haven't figured out why quite yet though.
If you alter the code so that isr_vector
is aligned to 4, then there is no effective gap.
There are multiple solutions.
isr_vector
is padded to the alignment of the following text
section. You can use ALIGN
(or FILL
, but ALIGN
does the math for you).isr_vector
code to be at the start of text and remove the isr_vector
section. Functions should already have alignment by the compiler. Section alignment is another level.Bonus: The _user_heap_stack and _data have an . = ALIGN(8)
and . = ALIGN(4)
at the beginning. These do nothing. The linker file ._user_heap_stack:ALIGN(8)
and .data:ALIGN(4)
would accomplish the intent here.
Related:
isr_vector
assembler is quite inefficient extending boot time.