在运行时重新定位函数-gcc

在运行时重新定位函数-gcc,c,gcc,compiler-construction,linker,lds,C,Gcc,Compiler Construction,Linker,Lds,我的设备上有两个内存,DDR和SRAM。该设备正在运行用C和ARM编写的操作系统前代码 我想进行DDR校准,为此我需要将一些功能复制到SRAM,跳转到SRAM,运行校准代码,完成后返回DDR 为此,我修改了分散文件(.lds),以便将相关函数映射到SRAM(指令、数据等)。 编译完图像后,他被复制到DDR中并从那里开始运行 我的问题如下: 如何在DDR上找到这些函数的起始地址和大小,以便能够将它们复制到SRAM并跳转到那里 提前谢谢大家 我假设您谈论的是ARM架构: 使用\uuuuu属性(总是内

我的设备上有两个内存,DDR和SRAM。该设备正在运行用C和ARM编写的操作系统前代码

我想进行DDR校准,为此我需要将一些功能复制到SRAM,跳转到SRAM,运行校准代码,完成后返回DDR

为此,我修改了分散文件(.lds),以便将相关函数映射到SRAM(指令、数据等)。 编译完图像后,他被复制到DDR中并从那里开始运行

我的问题如下: 如何在DDR上找到这些函数的起始地址和大小,以便能够将它们复制到SRAM并跳转到那里


提前谢谢大家

我假设您谈论的是
ARM
架构:

  • 使用
    \uuuuu属性(总是内联)编译代码所有相关函数,并使用
    -fpic-fpic
    进行编译,以了解更多信息
  • 将其分解并按原样放在SRAM上,例如地址
    0xd1001000
  • 在SRAM上保留
    {r4-r15}
  • pc
    正确设置为
    0xd1001000
    sp
    以指向堆栈
  • 还原
    {r4-r15}
  • 跳回DDR
  • 您可以查看如何使用正确的gcc标志的良好资源


    这是一个引用-它不会跳回初始位置:

    /*
     * void relocate_code (addr_sp, gd, addr_moni)
     *
     * This "function" does not return, instead it continues in RAM
     * after relocating the monitor code.
     *
     */
        .globl  relocate_code
    relocate_code:
        mov r4, r0  /* save addr_sp */
        mov r5, r1  /* save addr of gd */
        mov r6, r2  /* save addr of destination */
    
        /* Set up the stack                         */
    stack_setup:
        mov sp, r4
    
        adr r0, _start
        cmp r0, r6
        moveq   r9, #0      /* no relocation. relocation offset(r9) = 0 */
        beq clear_bss       /* skip relocation */
        mov r1, r6          /* r1 <- scratch for copy_loop */
        ldr r3, _image_copy_end_ofs
        add r2, r0, r3      /* r2 <- source end address     */
    
    copy_loop:
        ldmia   r0!, {r9-r10}       /* copy from source address [r0]    */
        stmia   r1!, {r9-r10}       /* copy to   target address [r1]    */
        cmp r0, r2          /* until source end address [r2]    */
        blo copy_loop
    
    #ifndef CONFIG_SPL_BUILD
        /*
         * fix .rel.dyn relocations
         */
        ldr r0, _TEXT_BASE      /* r0 <- Text base */
        sub r9, r6, r0      /* r9 <- relocation offset */
        ldr r10, _dynsym_start_ofs  /* r10 <- sym table ofs */
        add r10, r10, r0        /* r10 <- sym table in FLASH */
        ldr r2, _rel_dyn_start_ofs  /* r2 <- rel dyn start ofs */
        add r2, r2, r0      /* r2 <- rel dyn start in FLASH */
        ldr r3, _rel_dyn_end_ofs    /* r3 <- rel dyn end ofs */
        add r3, r3, r0      /* r3 <- rel dyn end in FLASH */
    fixloop:
        ldr r0, [r2]        /* r0 <- location to fix up, IN FLASH! */
        add r0, r0, r9      /* r0 <- location to fix up in RAM */
        ldr r1, [r2, #4]
        and r7, r1, #0xff
        cmp r7, #23         /* relative fixup? */
        beq fixrel
        cmp r7, #2          /* absolute fixup? */
        beq fixabs
        /* ignore unknown type of fixup */
        b   fixnext
    fixabs:
        /* absolute fix: set location to (offset) symbol value */
        mov r1, r1, LSR #4      /* r1 <- symbol index in .dynsym */
        add r1, r10, r1     /* r1 <- address of symbol in table */
        ldr r1, [r1, #4]        /* r1 <- symbol value */
        add r1, r1, r9      /* r1 <- relocated sym addr */
        b   fixnext
    fixrel:
        /* relative fix: increase location by offset */
        ldr r1, [r0]
        add r1, r1, r9
    fixnext:
        str r1, [r0]
        add r2, r2, #8      /* each rel.dyn entry is 8 bytes */
        cmp r2, r3
        blo fixloop
        b   clear_bss
    _rel_dyn_start_ofs:
        .word __rel_dyn_start - _start
    _rel_dyn_end_ofs:
        .word __rel_dyn_end - _start
    _dynsym_start_ofs:
        .word __dynsym_start - _start
    
    #endif  /* #ifndef CONFIG_SPL_BUILD */
    
    clear_bss:
    #ifdef CONFIG_SPL_BUILD
        /* No relocation for SPL */
        ldr r0, =__bss_start
        ldr r1, =__bss_end__
    #else
        ldr r0, _bss_start_ofs
        ldr r1, _bss_end_ofs
        mov r4, r6          /* reloc addr */
        add r0, r0, r4
        add r1, r1, r4
    #endif
        mov r2, #0x00000000     /* clear                */
    
    clbss_l:str r2, [r0]        /* clear loop...            */
        add r0, r0, #4
        cmp r0, r1
        bne clbss_l
    
    /*
     * We are done. Do not return, instead branch to second part of board
     * initialization, now running from RAM.
     */
    jump_2_ram:
    /*
     * If I-cache is enabled invalidate it
     */
    #ifndef CONFIG_SYS_ICACHE_OFF
        mcr p15, 0, r0, c7, c5, 0   @ invalidate icache
        mcr     p15, 0, r0, c7, c10, 4  @ DSB
        mcr     p15, 0, r0, c7, c5, 4   @ ISB
    #endif
        ldr r0, _board_init_r_ofs
        adr r1, _start
        add lr, r0, r1
        add lr, lr, r9
        /* setup parameters for board_init_r */
        mov r0, r5      /* gd_t */
        mov r1, r6      /* dest_addr */
        /* jump to it ... */
        mov pc, lr
    
    _board_init_r_ofs:
        .word board_init_r - _start
    
    /*
    *无效重新定位代码(地址sp、gd、地址moni)
    *
    *此“函数”不会返回,而是在RAM中继续
    *重新定位监视器代码后。
    *
    */
    .globl重新定位代码
    重新定位代码:
    mov r4、r0/*保存地址sp*/
    mov r5,r1/*保存gd的地址*/
    mov r6,r2/*保存目标地址*/
    /*设置堆栈*/
    堆栈设置:
    mov sp,r4
    adr r0,开始
    cmp r0,r6
    moveq r9,#0/*无重新安置。重新定位偏移量(r9)=0*/
    beq clear_bss/*跳过重新安置*/
    mov r1,r6/*r1