1

I use Eclipse and Yagarto toolchain (non-eabi, GCC 4.7.1) to program a ARM 7 chip (Atmel's AT91SAM7X256), Goal of this project is to place a bootloader in a defined range of ROM, which is copied to RAM later (see image below, ROM address 0x104000 for application code start is fixed). Works as expected ... until you debug the programm (SEGGER J-Link and GDB).

Memory structure image is shown here: http://i47.tinypic.com/2vb6f7o.jpg (sorry, cannot post images here).

The problems start with the .text section of the linked, mainly with the following method, which starts the whole .text section (correct): (disassembled C code by objdump -e -h common/exhandler.o > exhandler.lst)

   00000000 <EXHANDLER_printHex>:
      0:    e92d4038    push    {r3, r4, r5, lr}
      4:    e1a05000    mov r5, r0
      8:    e3a0401c    mov r4, #28
      c:    e1a03435    lsr r3, r5, r4
     10:    e203000f    and r0, r3, #15
     14:    e3500009    cmp r0, #9
     18:    c2800027    addgt   r0, r0, #39 ; 0x27
     1c:    e2800030    add r0, r0, #48 ; 0x30
     20:    ebfffffe    bl  0 <DBGUNIT_sendCharacter>
     24:    e2444004    sub r4, r4, #4
     28:    e3740004    cmn r4, #4
     2c:    1afffff6    bne c <EXHANDLER_printHex+0xc>
     30:    e8bd4038    pop {r3, r4, r5, lr}
     34:    e12fff1e    bx  lr

When disassembling the linked ELF file, the code is outputted as: (wrong)

00104000 <EXHANDLER_printHex>:
  104000:   e92d4038    push    {r3, r4, r5, lr}
  104004:   5000        str r0, [r0, r0]
  104006:   401ce1a0    andsmi  lr, ip, r0, lsr #3
  10400a:   e3a0        b.n 10474e <ADCDAC_get16BitChannel+0x82>
  10400c:   e1a03435    .word   0xe1a03435
  104010:   e203000f    and r0, r3, #15
  104014:   e3500009    cmp r0, #9
  104018:   0027        movs    r7, r4
  10401a:   0030c280    eorseq  ip, r0, r0, lsl #5
  10401e:   e280        b.n 104522 <CSTARTUP_lowLevelInit+0xfa>
  104020:   eb003367    bl  110dc4 <__DBGUNIT_sendCharacter_from_arm>
  104024:   4004        ands    r4, r0
  104026:   e244        .short  0xe244
  104028:   e3740004    cmn r4, #4
  10402c:   1afffff6    .word   0x1afffff6
  104030:   e8bd4038    pop {r3, r4, r5, lr}
  104034:   e12fff1e    .word   0xe12fff1e

While the byte sequences remain intact, the interpretation of those ASM commands differ. My assumption is that something went wrong with Thumb and ARM code in linking process.

My linker file:

/*
 * Linker script for AT91SAM7X256 with internal bootloader.
 *
 * Bootloader is put into first 16 kB of Flash, then loaded to RAM and will connect by DBGU UART interface
 * (115 kBaud, no parity bit).
 */
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)

MEMORY
{
  flash-boot (rx) : ORIGIN = 0x00100000, LENGTH = 16K       /* read-only flash memory for boot-loader and startup sequence */
  flash-app  (rx) : ORIGIN = 0x00104000, LENGTH = 240K      /* read-only flash memory for application */
  ram (rwx)       : ORIGIN = 0x00200000, LENGTH = 64K       /* read/write S-RAM memory */
}


/* Stack is growing backwards, starting at end of RAM and is aligned at 4 byte. First entry in stack will
   use RAM address 0x20fffc to 0x20ffff. */
_estack = 0x20fffc; 




SECTIONS
{
  . = 0;


    /* Elements required during start-up sequence. Must be first elements in ROM. */
    .startup : {
        obj/sys/startup.o(.text .rodata)
        . = ALIGN(4);
        obj/sys/swi_handler.o(.text .rodata)
        . = ALIGN(4);
        _estartup = .;                          /* end of startup segment */
    } >flash-boot

    .ramvect : {                        /* used for vectors remapped to RAM */
        __ram_start = .;
        . = 0x40;
    } >ram

    /* Further elements for bootloader, which are placed into RAM for allowing chip flash. */   
    .bootloader : {
        _bootloader = .;        /* RAM */
        obj/comm/dbgunit.o(.text .rodata)
        . = ALIGN(4);
        _ebootloader = .;       /* RAM */
    } >ram AT>flash-boot

    /* Code starts at fixed address in flash (application start) and is kept there. */
    .text : {
        CREATE_OBJECT_SYMBOLS
        *(.text .text.* .gnu.linkonce.t.*)         /* remaining code */
        *(.plt)
        *(.gnu.warning)
        *(.glue_7) *(.glue_7t)  /* stub for code which glues together ARM7 and Thumb code */

        . = ALIGN(4);
        *(.rodata .rodata.* .gnu.linkonce.r.*)  /* read-only data (constants) */        
        *(.ARM.extab* .gnu.linkonce.armextab.*)
        *(.gcc_except_table)

        *(.init)
        *(.fini)

        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP (*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        PROVIDE_HIDDEN (__fini_array_end = .);

        . = ALIGN(4);
    } >flash-app

     /* .ARM.exidx is sorted, so has to go in its own output section.  */
    .ARM.exidx : {
        __exidx_start = .;
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        __exidx_end = .;
    } >flash-app

    _etext = .;

    /* Initialized .data sections go into RAM. */ 
    .data : 
    {
        _data = .;                      /* create a global symbol marking the start of the .data section (RAM) */
        *(.ramsection .ramsection.*)
        . = ALIGN(4);
        *(.data .data.* .gnu.linkonce.d.*)
        . = ALIGN(4);
        _edata = .;                     /* define a global symbol marking the end of the .data section  */
    } >ram AT>flash-app                         /* put all the above into RAM */


    /* Uninitialized .bss sections go into RAM. */
    .bss (NOLOAD):                      
    {
        __bss_start__ = .;              /* define a global symbol marking the start of the .bss section */
        *(.bss .bss.* .gnu.linkonce.b.*)
        *(COMMON)
        . = ALIGN(4);
    } > ram                             /* put all the above in RAM (it will be cleared in the startup code */

    _bss_end        = . ;               
    __bss_end__     = . ;               /* define a global symbol marking the end of the .bss section */    



    . = ALIGN(4);                       /* advance location counter to the next 32-bit boundary */
    _end = .;                           /* define a global symbol marking the end of application RAM */
    PROVIDE (end = .);


    /* DWARF debug sections.
    * Symbols in the DWARF debugging sections are relative to the beginning
    * of the section so we begin them at 0.
    */
    /* DWARF 1 */
    .debug          0 : { *(.debug) }
    .line           0 : { *(.line) }
    /* GNU DWARF 1 extensions */
    .debug_srcinfo  0 : { *(.debug_srcinfo) }
    .debug_sfnames  0 : { *(.debug_sfnames) }
    /* DWARF 1.1 and DWARF 2 */
    .debug_aranges  0 : { *(.debug_aranges) }
    .debug_pubnames 0 : { *(.debug_pubnames) }
    /* DWARF 2 */
    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
    .debug_abbrev   0 : { *(.debug_abbrev) }
    .debug_line     0 : { *(.debug_line) }
    .debug_frame    0 : { *(.debug_frame) }
    .debug_str      0 : { *(.debug_str) }
    .debug_loc      0 : { *(.debug_loc) }
    .debug_macinfo  0 : { *(.debug_macinfo) }
    /* SGI/MIPS DWARF 2 extensions */
    .debug_weaknames 0 : { *(.debug_weaknames) }
    .debug_funcnames 0 : { *(.debug_funcnames) }
    .debug_typenames 0 : { *(.debug_typenames) }
    .debug_varnames  0 : { *(.debug_varnames) }
    .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
    .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
    /DISCARD/ : { *(.note.GNU-stack)  }

}

Can anyone spot an error in linker file or give me a hint, where to look next?

Thank you for reading, Paule

PS: Here's some output of the ELF file section headers, so that it's clear there are no overlapping sections.

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .startup      0000033c  00100000  00100000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .ramvect      00000040  00200000  00200000  00030000  2**0
                  ALLOC
  2 .bootloader   000001cc  00200040  0010033c  00010040  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  3 .text         0000ce08  00104000  00104000  00014000  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  4 .ARM.exidx    000000f0  00110e08  00110e08  00020e08  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .data         0000129c  00200210  00110ef8  00028210  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  6 .bss          000008c8  002014ac  00112194  000294ac  2**2
                  ALLOC
  7 .debug_aranges 000009b8  00000000  00000000  000294b0  2**3
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_info   0002166d  00000000  00000000  00029e68  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_abbrev 00006cb4  00000000  00000000  0004b4d5  2**0
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_line   00007db7  00000000  00000000  00052189  2**0
                  CONTENTS, READONLY, DEBUGGING
 11 .debug_frame  0000232c  00000000  00000000  00059f40  2**2
                  CONTENTS, READONLY, DEBUGGING
 12 .debug_str    0000682a  00000000  00000000  0005c26c  2**0
                  CONTENTS, READONLY, DEBUGGING
 13 .debug_loc    00016421  00000000  00000000  00062a96  2**0
                  CONTENTS, READONLY, DEBUGGING
 14 .comment      00000011  00000000  00000000  00078eb7  2**0
                  CONTENTS, READONLY
 15 .ARM.attributes 0000002e  00000000  00000000  00078ec8  2**0
                  CONTENTS, READONLY
 16 .debug_ranges 00000968  00000000  00000000  00078ef6  2**0
                  CONTENTS, READONLY, DEBUGGING
Paule
  • 13
  • 3

1 Answers1

0

It seems, the wrong disassembled code is a problem of the disassembler, which isn't able to distinguish between ARM and Thumb compiled code in a intermixed object file.

The method EXHANDLER_printHex() had been compiled in ARM mode, but was wrongly deciphered to Thumb code.

Conclusion: DisASM's code does not lead to solution of problem.

Mihai Iorga
  • 39,330
  • 16
  • 106
  • 107
Paule
  • 13
  • 3