<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.arm.com/utility/feedstylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>David's Activities</title><link>https://community.arm.com/members/davidbo</link><description>David's recent activity</description><dc:language>en-US</dc:language><generator>Telligent Community 10</generator><item><title>Position inpdeped code for bootloader.</title><link>https://community.arm.com/developer/tools-software/oss-platforms/f/gnu-toolchain-forum/47344/position-inpdeped-code-for-bootloader</link><pubDate>Mon, 03 Aug 2020 14:28:53 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:011dc2c0-d8f0-4381-a063-adf4387340c3</guid><dc:creator>Semiory</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;I&amp;#39;m creating a custom OTA firmware update on cc2640 chip from TI. (Cortex M3)&lt;br /&gt; For this reason two memory regions are reserved for firmware images. &lt;br /&gt;The problem is, the code works only if it is stored in one of the regions. (According to the Linker File)&lt;br /&gt;If the code is stored in the second region, it does not start at all. &lt;br /&gt;&lt;br /&gt;In IAR Compiler the -ropi (the same as PIE/PIC in GCC) works correctly. &lt;br /&gt;&lt;br /&gt;The Linker Script is the following:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/* Entry Point */
ENTRY( ResetISR )

/* System memory map */
MEMORY
{
	CRC (RX)		: ORIGIN = 0x00001000, LENGTH = 0x00000004
	OHD (RX)		: ORIGIN = 0x00001004, LENGTH = 0x0000000C
	INT_VEC (RX)	: ORIGIN = 0x00001010, LENGTH = 0x000000C8
	FWU_DESCR (RX)	: ORIGIN = 0x000010D8, LENGTH = 0x00000040
	APP_DESCR (RX)	: ORIGIN = 0x00001118, LENGTH = 0x00000040
	FLASH (RX)      : ORIGIN = 0x00001158, LENGTH = 0x0000AF2F
	CONFIG (RX)		: ORIGIN = 0x0001E000, LENGTH = 0x00001000
	SRAM (RWX)      : ORIGIN = 0x20000000, LENGTH = 0x00005000
	/* Application can use GPRAM region as RAM if cache is disabled in the CCFG
	(DEFAULT_CCFG_SIZE_AND_DIS_FLAGS.SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM = 0) */
	GPRAM (RWX) 	: ORIGIN = 0x11000000, LENGTH = 0x2000
}

/*. Generate a link error if heap and stack don’t fit into RAM .*/
_Min_Heap_Size = 0x800;
_Min_Stack_Size = 0x800;

/*. Highest address of the stack. Used in startup file .*/
_estack = ORIGIN(SRAM) + LENGTH(SRAM); /*end of SRAM .*/


REGION_ALIAS(&amp;quot;REGION_TEXT&amp;quot;, FLASH);
REGION_ALIAS(&amp;quot;REGION_CONFIG&amp;quot;, CONFIG);
REGION_ALIAS(&amp;quot;REGION_BSS&amp;quot;, SRAM);
REGION_ALIAS(&amp;quot;REGION_DATA&amp;quot;, SRAM);
REGION_ALIAS(&amp;quot;REGION_STACK&amp;quot;, SRAM);
REGION_ALIAS(&amp;quot;REGION_HEAP&amp;quot;, SRAM);
REGION_ALIAS(&amp;quot;REGION_ARM_EXIDX&amp;quot;, FLASH);
REGION_ALIAS(&amp;quot;REGION_ARM_EXTAB&amp;quot;, FLASH);


/* Section allocation in memory */

SECTIONS
{

      /*
     * UDMACC26XX_CONFIG_BASE below must match UDMACC26XX_CONFIG_BASE defined
     * by ti/drivers/dma/UDMACC26XX.h
     * The user is allowed to change UDMACC26XX_CONFIG_BASE to move it away from
     * the default address 0x2000_0400, but remember it must be 1024 bytes aligned.
     */
    UDMACC26XX_CONFIG_BASE = 0x20000400;

    /*
     * Define absolute addresses for the DMA channels.
     * DMA channels must always be allocated at a fixed offset from the DMA base address.
     * --------- DO NOT MODIFY -----------
     */

    DMA_SPI0_RX_CONTROL_TABLE_ENTRY_ADDRESS   = (UDMACC26XX_CONFIG_BASE + 0x30);
    DMA_SPI0_TX_CONTROL_TABLE_ENTRY_ADDRESS   = (UDMACC26XX_CONFIG_BASE + 0x40);
    DMA_ADC_PRI_CONTROL_TABLE_ENTRY_ADDRESS   = (UDMACC26XX_CONFIG_BASE + 0x70);
    DMA_GPT0A_PRI_CONTROL_TABLE_ENTRY_ADDRESS = (UDMACC26XX_CONFIG_BASE + 0x90);
    DMA_SPI1_RX_CONTROL_TABLE_ENTRY_ADDRESS   = (UDMACC26XX_CONFIG_BASE + 0x100);
    DMA_SPI1_TX_CONTROL_TABLE_ENTRY_ADDRESS   = (UDMACC26XX_CONFIG_BASE + 0x110);
    DMA_ADC_ALT_CONTROL_TABLE_ENTRY_ADDRESS   = (UDMACC26XX_CONFIG_BASE + 0x270);
    DMA_GPT0A_ALT_CONTROL_TABLE_ENTRY_ADDRESS = (UDMACC26XX_CONFIG_BASE + 0x290);

    /*
     * Allocate SPI0, SPI1, ADC, and GPTimer0 DMA descriptors at absolute addresses.
     * --------- DO NOT MODIFY -----------
     */
    UDMACC26XX_dmaSpi0RxControlTableEntry_is_placed = 0;
    .dmaSpi0RxControlTableEntry DMA_SPI0_RX_CONTROL_TABLE_ENTRY_ADDRESS (NOLOAD) : AT (DMA_SPI0_RX_CONTROL_TABLE_ENTRY_ADDRESS) {*(.dmaSpi0RxControlTableEntry)} &amp;gt; REGION_DATA

    UDMACC26XX_dmaSpi0TxControlTableEntry_is_placed = 0;
    .dmaSpi0TxControlTableEntry DMA_SPI0_TX_CONTROL_TABLE_ENTRY_ADDRESS (NOLOAD)  : AT (DMA_SPI0_TX_CONTROL_TABLE_ENTRY_ADDRESS) {*(.dmaSpi0TxControlTableEntry)} &amp;gt; REGION_DATA

    UDMACC26XX_dmaADCPriControlTableEntry_is_placed = 0;
    .dmaADCPriControlTableEntry DMA_ADC_PRI_CONTROL_TABLE_ENTRY_ADDRESS (NOLOAD) : AT (DMA_ADC_PRI_CONTROL_TABLE_ENTRY_ADDRESS) {*(.dmaADCPriControlTableEntry)} &amp;gt; REGION_DATA

    UDMACC26XX_dmaGPT0APriControlTableEntry_is_placed = 0;
    .dmaGPT0APriControlTableEntry DMA_GPT0A_PRI_CONTROL_TABLE_ENTRY_ADDRESS (NOLOAD) : AT (DMA_GPT0A_PRI_CONTROL_TABLE_ENTRY_ADDRESS) {*(.dmaGPT0APriControlTableEntry)} &amp;gt; REGION_DATA

    UDMACC26XX_dmaSpi1RxControlTableEntry_is_placed = 0;
    .dmaSpi1RxControlTableEntry DMA_SPI1_RX_CONTROL_TABLE_ENTRY_ADDRESS (NOLOAD) : AT (DMA_SPI1_RX_CONTROL_TABLE_ENTRY_ADDRESS) {*(.dmaSpi1RxControlTableEntry)} &amp;gt; REGION_DATA

    UDMACC26XX_dmaSpi1TxControlTableEntry_is_placed = 0;
    .dmaSpi1TxControlTableEntry DMA_SPI1_TX_CONTROL_TABLE_ENTRY_ADDRESS (NOLOAD) : AT (DMA_SPI1_TX_CONTROL_TABLE_ENTRY_ADDRESS) {*(.dmaSpi1TxControlTableEntry)} &amp;gt; REGION_DATA

    UDMACC26XX_dmaADCAltControlTableEntry_is_placed = 0;
    .dmaADCAltControlTableEntry DMA_ADC_ALT_CONTROL_TABLE_ENTRY_ADDRESS (NOLOAD) : AT (DMA_ADC_ALT_CONTROL_TABLE_ENTRY_ADDRESS) {*(.dmaADCAltControlTableEntry)} &amp;gt; REGION_DATA

    UDMACC26XX_dmaGPT0AAltControlTableEntry_is_placed = 0;
    .dmaGPT0AAltControlTableEntry DMA_GPT0A_ALT_CONTROL_TABLE_ENTRY_ADDRESS (NOLOAD) : AT (DMA_GPT0A_ALT_CONTROL_TABLE_ENTRY_ADDRESS) {*(.dmaGPT0AAltControlTableEntry)} &amp;gt; REGION_DATA


	.SHADOW_CRC :
	{
		KEEP(*(.SHADOW_CRC))
	} &amp;gt; CRC = 0xFF

	.IMAGE_HEADER :
	{
		KEEP(*(.IMAGE_HEADER))
	} &amp;gt; OHD = 0xFF

	.intvec :
	{
		KEEP(*(.vectors))
	} &amp;gt; INT_VEC = 0xFF

	.firmwareDescr :
	{
		KEEP(*(.firmwareDescr))
	} &amp;gt;  FWU_DESCR = 0xFF

	.applicationDescr :
	{
		KEEP(*(.applicationDescr))
	} &amp;gt;  APP_DESCR = 0xFF

	.text : {
        CREATE_OBJECT_SYMBOLS
        *(.text)
        *(.text.*)
        . = ALIGN(0x4);
        __init_array_start = .;
        KEEP (*(.init_array*))
        __init_array_end = .;
        *(.init)
        *(.fini*)
    } &amp;gt; REGION_TEXT AT&amp;gt; REGION_TEXT = 0xFF

    PROVIDE (__etext = .);
    PROVIDE (_etext = .);
    PROVIDE (etext = .);

    .rodata : {
        *(.rodata)
        *(.rodata.*)
    } &amp;gt; REGION_TEXT AT&amp;gt; REGION_TEXT = 0xFF

    .data :
    {
		_ldata = LOADADDR(.data);
        _data = .;
        *(vtable)
        *(.data)
        *(.data*)
        _edata = .;
    } &amp;gt; REGION_DATA AT &amp;gt; REGION_TEXT  = 0xFF
		
		.config (NOLOAD):
		{
			*(.config)
		} &amp;gt; REGION_CONFIG AT &amp;gt; REGION_CONFIG = 0xFF

    .ARM.exidx : {
        __exidx_start = .;
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        __exidx_end = .;
    } &amp;gt; REGION_ARM_EXIDX AT&amp;gt; REGION_ARM_EXIDX

    .ARM.extab : {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } &amp;gt; REGION_ARM_EXTAB AT&amp;gt; REGION_ARM_EXTAB

    .bss : {
        __bss_start__ = .;
        *(.shbss)
        _bss = .;
        *(.bss)
        *(.bss.*)
        *(COMMON)
        . = ALIGN (4);
        _ebss = .;
        __bss_end__ = .;
    } &amp;gt; REGION_BSS AT&amp;gt; REGION_BSS

    .heap : {
        __heap_start__ = .;
        end = __heap_start__;
        _end = end;
        __end = end;
        . = . + _Min_Heap_Size;
        KEEP(*(.heap))
        __heap_end__ = .;
        __HeapLimit = __heap_end__;
    } &amp;gt; REGION_HEAP AT&amp;gt; REGION_HEAP

    .stack (NOLOAD) : ALIGN(0x8) {
        _stack = .;
        __stack = .;
        KEEP(*(.stack))
        . += _Min_Stack_Size;
        _stack_end = .;
        __stack_end = .;
    } &amp;gt; REGION_STACK AT&amp;gt; REGION_STACK
}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;The Startup function was already updated to copy the .rodata correctly as following:&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void
ResetISR(void)
{
    //
    // Final trim of device
    //
    SetupTrimDevice();

    //
    // Copy the data segment initializers from FLASH to SRAM.
    //
    __asm(
        &amp;quot;   ldr     r1, =_ldata \n&amp;quot; // get source
        &amp;quot;   mov     r2, pc\n&amp;quot;       // get program counter
        &amp;quot;   cmp     r1, r2\n&amp;quot;        // compare as difference
        &amp;quot;   it      lo\n&amp;quot; // if then condition. If r2 is greeter than r1
        &amp;quot;   addlo   r1, r1, #45056\n&amp;quot;   // add 0xB000
        &amp;quot;   ldr     r2, =_data\n&amp;quot;       // get start of the ram
        &amp;quot;   ldr     r3, =_edata\n&amp;quot;      // get the data length in the ram
        &amp;quot;   copy_loop:\n&amp;quot;               // start copy loop
        &amp;quot;   ldr     r4, [r1], #4\n&amp;quot;// load a word from the source and
        &amp;quot;   str     r4, [r2], #4\n&amp;quot;// store it to the destination
        &amp;quot;   cmp     r2, r3\n&amp;quot;   // check all bytes are copied
        &amp;quot;   ble     copy_loop\n&amp;quot;);  // jump to loop start
    //
    // Zero fill the bss segment.
    //
    __asm(&amp;quot;    ldr     r0, =_bss\n&amp;quot;
          &amp;quot;    ldr     r1, =_ebss\n&amp;quot;
          &amp;quot;    mov     r2, #0\n&amp;quot;
          &amp;quot;    .thumb_func\n&amp;quot;
          &amp;quot;zero_loop:\n&amp;quot;
          &amp;quot;        cmp     r0, r1\n&amp;quot;
          &amp;quot;        it      lt\n&amp;quot;
          &amp;quot;        strlt   r2, [r0], #4\n&amp;quot;
          &amp;quot;        blt     zero_loop&amp;quot;);

    //
    // Call the application&amp;#39;s entry point.
    //
    main();

    //
    // If we ever return signal Error
    //
    FaultISR();
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The bootloader calles the entry (ResetISR(void)) function of the valid firmware at startup.&lt;/p&gt;
&lt;p&gt;All libraries are linked with -fPIC option.&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#0000ff;"&gt;target_link_libraries&lt;/span&gt;(${TARGETFILE}} ${LIB_LIST} &amp;quot;-fPIC&amp;quot;)&lt;/p&gt;
&lt;p&gt;I have used listet options:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Compiler flags :&amp;nbsp; -O2 -fdata-sections -ffunction-sections -fno-strict-aliasing -nostartfiles -fno-exceptions -mcpu=cortex-m3 -mthumb -g0 -Wall &amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Linker flags: -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections&amp;nbsp; -nostartfiles -mthumb -lc -lm -lgcc -lnosys -u __vector_table&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;Effekt -&amp;gt; Firmware works only at first address (0x1000). Other positions does not works.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Compiler flags :&amp;nbsp; -O2 -fdata-sections -ffunction-sections -fno-strict-aliasing -nostartfiles -fno-exceptions -mcpu=cortex-m3 -mthumb -g0 -Wall -fPIE &amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Linker flags: -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections&amp;nbsp; -nostartfiles -mthumb -lc -lm -lgcc -lnosys -u __vector_table&amp;quot;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;Effekt -&amp;gt; Firmware does not starts&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Compiler flags :&amp;nbsp; -O2 -fdata-sections -ffunction-sections -fno-strict-aliasing -nostartfiles -fno-exceptions -mcpu=cortex-m3 -mthumb -g0 -Wall -fPIE&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Linker flags: -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections&amp;nbsp; -nostartfiles -mthumb -lc -lm -lgcc -lnosys -u __vector_table -pie &amp;quot;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;Effekt -&amp;gt; Firmware does not starts. The linker flag&amp;nbsp;&lt;span style="color:#3366ff;"&gt;-pie &lt;span style="color:#000000;"&gt;causes the &lt;/span&gt;&lt;/span&gt;binarys to be 3 Times grater as whitout this option.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;I have alredy read the &amp;quot;Multiple Application Code with Bootloader&amp;quot; question. Unfortunately, the provided solution does not work for me:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Compiler flags :&amp;nbsp; -O2 -fdata-sections -ffunction-sections -fno-strict-aliasing -nostartfiles -fno-exceptions -mcpu=cortex-m3 -mthumb -g0 -Wall -fPIC &amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Linker flags: -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections&amp;nbsp; -nostartfiles -mthumb -lc -lm -lgcc -lnosys -u __vector_table&amp;nbsp;&lt;code&gt;-msingle-pic-base&lt;/code&gt; -mpic-register=r9&amp;quot;&lt;br /&gt;&lt;/span&gt;Effekt -&amp;gt; Firmware does not starts. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Coud someone provide some assistance to correct the mistake?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Cannot build position independent code that works</title><link>https://community.arm.com/developer/tools-software/oss-platforms/f/gnu-toolchain-forum/44805/cannot-build-position-independent-code-that-works</link><pubDate>Tue, 10 Dec 2019 23:39:29 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:98d74a30-c2b4-433e-999a-2492b47ce920</guid><dc:creator>FreddyBenZeev</dc:creator><description>&lt;p style="margin:0in;margin-bottom:.0001pt;"&gt;&lt;span style="color:#172b4d;"&gt;I&amp;#39;m building code for NXP S32K148 MCU (Arm Cortex M4F) and I need to build code which is position independent. I&amp;#39;m using gcc 6.3.1 provided by NXP.&lt;br /&gt;&lt;br /&gt;I&amp;#39;ve almost managed to make it work...&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:7.5pt 0in .0001pt 0in;text-align:start;"&gt;&lt;span style="color:#172b4d;"&gt;1. I set the compile options &amp;quot;-fpic -msingle-pic-base -mno-pic-data-is-text-relative -mpic-register=r9&amp;quot;.&lt;br /&gt; 2. I modified startup code:&lt;br /&gt; &amp;nbsp; &amp;nbsp;a. Calculate offset between compile time and run-time program counter (relocation offset).&lt;br /&gt; &amp;nbsp; &amp;nbsp;b. Copy the global offsets table to RAM while fixing code addresses by the relocation offset.&lt;br /&gt; &amp;nbsp; &amp;nbsp;c. Fix the interrupts vectors table pointers by the relocation offset.&lt;br /&gt; &amp;nbsp; &amp;nbsp;d. Set R9 to point to the global offsets table.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:7.5pt 0in .0001pt 0in;text-align:start;"&gt;&lt;b&gt;&lt;span style="color:red;"&gt;It worked - except that any function pointers inside initialized variable/structs were not relocated and were not accessed through the global offsets table. When execution reached such a pointer the system of course crashed.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style="margin:0in;margin-bottom:.0001pt;"&gt;&lt;span style="color:#172b4d;"&gt;&lt;br /&gt;Does anyone have a solution?&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in;margin-bottom:.0001pt;"&gt;&lt;span style="color:#172b4d;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in;margin-bottom:.0001pt;"&gt;&lt;span style="color:#172b4d;"&gt;Freddy&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>