cancel
Showing results for 
Search instead for 
Did you mean: 

Position-Independent Code - .data initialization

DWann
Associate III

I'm developing a bootloader for an STM32L0 MCU that will jump to one of two or more application partitions in flash. I'm using IAR 8.22.2.

To make the application binaries position-independent, I've compiled them with the -ropi option. I've also modified the startup code (.s file) to use a Reset_Handler that doesn't have absolute function references in it. At the start of the application, I copy the vector table to SRAM, adjusting all the flash addresses for the current partition offset. I set the VTOR to point to the SRAM location, set the stack pointer, and I'm good to go.

At least, I thought so. I tried jumping to the second partition and running the code, but after some initial excitement at seeing things working, I realized that somehow execution had wandered back into partition 1. To investigate, I compiled 2 separate binaries with the .icf file configured for two different flash partitions. I did a diff on them, expecting to only see differences in the vector table at the beginning of the file. However, I also see differences at the end of the file, in the initializer bytes.

As I read the IAR documentation, -ropi should take care of data initializers as well. ("ROPI = Read-Only Position Independence. This concerns everything that is readonly in the ELF output from the linker. Note that this includes const data and data initializers, i.e. typically everything that is put in FLASH.") Is this not the case? Do I need to use the -rwpi option as well?

I've tried using the -rwpi option, but then I'm completely lost as to how to handle the resulting binary and there are few examples out there (I've found 1 from IAR, but it's very hard to follow.)

Any idea what's going on here? Do I need to use the -rwpi option? If so, are there any good ST-specific examples out there?

Thanks!

10 REPLIES 10

You're either going to have to trace down the execution that gets you there, or do a static review of the listing/disassembly to understand what's going on.

Want to look at values placed in literal pools, as this is where most fixed addressed will end up.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
DWann
Associate III

Thanks for the response.

After some investigation, I discovered that I was failing to account for the vector table partition offset in the bootloader, so I was in fact jumping right to partition 1 instead of partition 2 as I had intended. I fixed that and then voila, I was jumping to the right partition and could easily switch from one to the other.

However, I then erased partition 1, booted into partition 2, and ended up with a Hard fault. I stepped through the dissasembly and found the error occurred within a precompiled function _gLocale_mblenInit (printf->_PrintFull->_gLocale_mblen). In that function, it attempted to branch to 0x08016C99, which was now an erased space in partition 1. I opened the compiled application binary, and as expected, 0x08016C99 shows up in the initializer bytes at the end of ROM_region.

So I guess that brings me back to the questions - shouldn't this be compiled as PIC given the -ropi option? Is there a way to fix this this other than using -rwpi? Are there any good -rwpi examples out there?

omer Korech
Associate II

Great Post

Thanks

Could you please specify how did you modified the startup code (.s file) to use a Reset_Handler that doesn't have absolute function references in it ?

DWann
Associate III

I modified the .s file as follows:

        MODULE  ?cstartup
 
        ;; Forward declaration of sections.
        SECTION CSTACK:DATA:NOROOT(3)
 
        SECTION .intvec:CODE:NOROOT(2)
 
        EXTERN  PI_Reset_Handler         
        ;EXTERN  __iar_program_start      ; comment out
        ;EXTERN  SystemInit               ;  comment out
        PUBLIC  __vector_table
 
        DATA
__vector_table
        DCD     sfe(CSTACK)
        DCD     PI_Reset_Handler          ;  new reset handler to support position independence
 
        DCD     NMI_Handler               ; NMI Handler
        DCD     HardFault_Handler         ; Hard Fault Handler

and added this function to main.c:

void PI_Reset_Handler(void)
{
    SystemInit();
    __iar_data_init3();
    __iar_program_start();
}

omer Korech
Associate II

dwanninger,

You saved me a week of work

I am going to drink beer now on your behalf

For completeness,

The definition of Reset Handler should be commented out:

;    PUBWEAK Reset_Handler

;    SECTION .text:CODE:REORDER:NOROOT(2)

;Reset_Handler

;    LDR   R0, =SystemInit

;    BLX   R0

;    LDR   R0, =__iar_program_start

;    BX   R0

ramfunc should be removed

// #[include "stm32l1xx_hal_flash_ramfunc.h"

And __iar functions may be declared:

extern void __iar_data_init3(void);

extern void __iar_program_start(void);

hhadd
Associate

hello , i develop a boot-loader that need to jump to an application that it must be compiled with ROPI option , i have made all the previous modifications but when my boot-loader jump to app the application can't run , the app is compiled with ivect offset in linker ( 0x8000000) and i put the app in address (0x8010000) , i use a STM32L4R5 board . any idea that can help me please ?

omer Korech
Associate II

Hi

I don't know why your code doesn't work. Let me share the difference between your implementation and a version that worked for me.

I used the NVIC from the ​modified address in flash (0x8010000 in your case), not from RAM.

At the time of writing the binary values to the flash, I added an offset (0x10000 in your case) to the NVIC entries that point to the ISR addresses (there are some addreses in NVIC region that are resereved and should not be modified).

The rest was like you probably did:

Changed the reset handler as described above.

Set the jumpfunction pointer to the value at ​that is written at 0x8010000 in your case.

Modified VTOR to ​0x8010000.

Set the stack pointer according to ​0x8010004.

Finally, jumped to the application.​

helmi haddad
Associate II

Hello Omer , can you share with me your code please? helmi.hadd@gmail.com

omer Korech
Associate II

I can not share the code

But I can share a presentation about the code:

https://www.slideshare.net/OmerKorech/boot-loader-for-stm32l1xx-126547060