Linker script: align section to the next power of two

3

So, I have this linker script:

MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
    SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
SECTIONS
{
    .kernel.text :
    {
        _kernel_text = .;
        KEEP(kernel.a(.isr_vector))
        KEEP(kernel.a(_sbrk))
        kernel.a(.text*)
        kernel.a(.rodata*)
        _kernel_etext = .;
        _kernel_flash_data = ALIGN(0x4);
    } > FLASH

    .kernel.data : /*AT(ADDR(.text) + SIZEOF(.text))*/ /*contains initialized data*/
    {
        _kernel_data = .;
        kernel.a(vtable)
        kernel.a(.data*)
        _kernel_edata = .;
    } > SRAM AT > FLASH

    .kernel.bss : 
    {
        _kernel_bss = .;
        kernel.a(.bss*)
        kernel.a(COMMON)
        _kernel_ebss = .;
    } > SRAM

    .core.text : ALIGN(0x1000) 
    {
        _core_text = .;
        core.a(.text*)
        core.a(.rodata*)
        _core_etext = .;
        _core_flash_data = ALIGN(0x4);
    } > FLASH
 /* There is lots more, but this is the interesting part */
}

And lets focus on the flash. The flash starts at 0x0 and first the entire kernel.text is written to it, then kernel.data is written to it. And I want a MPU to protect this memory region. This MPU can only work on memory sections with a size of a power of two. I want the entire kernel section in the flash (data + text) to be protected under a single region by the MPU, so I need its total size to be a power of two. The align command on .core.text will do this for me, for now. I know for a fact that .kernel.text + .kernel.data = 3960 bytes long, so I want to align to 2^12 = 4096 = 0x1000. Now I can protect from 0x0 to 0x1000 under a single region and protect the kernel under a single MPU region. Party on!

But the project is far from done and code will be added, so we might cross this boundry. The first time this is not a problem: the memory will align to the next 4096 barrier, which is 8192 and 2^13. But after that, the memory will align to 12288, which is not a power of two, so my MPU will spit at me and scoff me.

Is there a way to make this linker script always align to the next power of two?

linker
embedded
ld
linker-scripts
asked on Stack Overflow Apr 7, 2015 by Cheiron • edited Apr 7, 2015 by Cheiron

1 Answer

3

Thankfully, GNU ld provides a handy-dandy log2ceil() function for instances just like this. Simply write your linker script as follows:

/* ... */
_flash_text_data_end_aligned = (2 << LOG2CEIL( _etext + SIZEOF(.data)));
/* ... */
.core.text: ALIGN(_flash_text_data_end_aligned)
/* ... */
answered on Stack Overflow Apr 15, 2015 by LThode • edited May 20, 2015 by LThode

User contributions licensed under CC BY-SA 3.0