2014-01-14 11 views
1

Я работаю с двумя памятью на своем устройстве, DDR и SRAM. Устройство использует код предварительной ОС, написанный на C и ARM.Перемещение функций во время выполнения - gcc

Я хотел бы провести калибровку DDR, для этого мне нужно скопировать несколько функций в SRAM, перейти к ней, запустить код калибровки и вернуться к DDR, когда это будет сделано.

Для этого я изменяю свой файл рассеяния (.lds), поэтому соответствующие функции будут отображаться в SRAM (инструкции, данные и т. Д.). После компиляции изображения он копируется в DDR и начинает работать оттуда.

Моя проблема заключается в следующем: Как найти начальный адрес и размер этих функций на DDR, так что я смогу скопировать их в SRAM и перепрыгнуть туда?

Спасибо вам всем заранее!

ответ

0

Я предполагаю, что вы говорите о ARM архитектуры:

  1. компилировать код с __attribute__((always_inline)); всех функций, связанных и компилировать с -fpic -fPIC чтения here для получения дополнительной информации.
  2. разборке его и поставить его как есть на SRAM, например по адресу 0xd1001000
  3. резервного {r4-r15} на SRAM.
  4. комплект pc до 0xd1001000 и sp правильно указать стек.
  5. восстановление {r4-r15}
  6. вернуться в DDR.

Вы можете посмотреть here за хороший ресурс о том, как использовать правильные флаги gcc.


вот от uboot Другой крупный - это не прыгает обратно в исходное место:

/* 
* 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 

 Смежные вопросы

  • Нет связанных вопросов^_^