Alignment in linker scripts

0

I am looking at trezor's bootloader linker script:

/* TREZORv2 bootloader linker script */

ENTRY(reset_handler)

MEMORY {
  FLASH  (rx)  : ORIGIN = 0x08020000, LENGTH = 128K
  CCMRAM (wal) : ORIGIN = 0x10000000, LENGTH = 64K
  SRAM   (wal) : ORIGIN = 0x20000000, LENGTH = 192K
}

main_stack_base = ORIGIN(CCMRAM) + LENGTH(CCMRAM); /* 8-byte aligned full descending stack */

/* used by the startup code to populate variables used by the C code */
data_lma = LOADADDR(.data);
data_vma = ADDR(.data);
data_size = SIZEOF(.data);

/* used by the startup code to wipe memory */
ccmram_start = ORIGIN(CCMRAM);
ccmram_end = ORIGIN(CCMRAM) + LENGTH(CCMRAM);

/* used by the startup code to wipe memory */
sram_start = ORIGIN(SRAM);
sram_end = ORIGIN(SRAM) + LENGTH(SRAM);

_codelen = SIZEOF(.flash) + SIZEOF(.data);

SECTIONS {
  .header : ALIGN(4) {
    KEEP(*(.header));
  } >FLASH AT>FLASH

  .flash : ALIGN(512) {
    KEEP(*(.vector_table));
    . = ALIGN(4);
    *(.text*);
    . = ALIGN(4);
    *(.rodata*);
    . = ALIGN(512);
  } >FLASH AT>FLASH

  .data : ALIGN(4) {
    *(.data*);
    . = ALIGN(512);
  } >CCMRAM AT>FLASH

  .bss : ALIGN(4) {
    *(.bss*);
    . = ALIGN(4);
  } >CCMRAM

  .stack : ALIGN(8) {
    . = 4K; /* this acts as a build time assertion that at least this much memory is available for stack use */
  } >CCMRAM
}

It can be found here.

I understand that the code needs to be 32bit ( ALIGN(4) ) aligned, because the ARM processor can crash if it tries to access unaligned address, but I do not understand why the stack alignment is 8 bytes and furthermore why the hell do you need to waste(?) 512 bytes for alignment of the flash section?!

I would like to understand how the alignment is decided when writing a linker script.

Thank you in advance for your answers!

EDIT:

I think i answered my own question:

1. .flash section:

It is aligned like that, because the vector table, that is inside it always needs to be "32-word aligned". This can also be seen be the case in Trezor's boardloader linker script. As you can see the vector table is 512 byte (4 x 32-word) aligned.

2. .stack section:

According to ARM's own documentation the stack section needs to always be 8 byte aligned.

P.S. Of course if this is not the case, please correct me.

arm
alignment
linker-scripts
trezor
asked on Stack Overflow Aug 17, 2018 by Slav • edited Aug 3, 2019 by glts

1 Answer

0

Okay, so since cooperised confirmed my theory I can now close this question.

1. .flash section:

It is aligned like that, because the vector table, that is inside it always needs to be "32-word aligned". This can also be seen be the case in Trezor's boardloader linker script. As you can see the vector table is 512 byte (4 x 32-word) aligned.

2. .stack section:

According to ARM's own documentation the stack section needs to always be 8 byte aligned.

Thank you cooperised for the confirmation!

answered on Stack Overflow Aug 20, 2018 by Slav

User contributions licensed under CC BY-SA 3.0