u-bootarmv8orange-pi

"Synchronous Abort" handler, esr 0x96000004


I am trying to boot an ELF file using u-boot on the orangepi-lite2 board, which is based on an allwinnertech-H6 (Cortex-A53 CPU).

The execution of my program is triggering an exception:

elr: 000000004a004d60 lr : 000000004a004dac (reloc)
elr: 000000007ff59d60 lr : 000000007ff59dac
x0 : 0000000000000221 x1 : 00000000400800c0
x2 : 0000000000000040 x3 : 000000000000003f
x4 : 0000000040080090 x5 : 000000007ff7435c
x6 : 000000007bf2e588 x7 : 0000000000000008
x8 : 0000000000000010 x9 : 0000000000000008
x10: 0000000000000044 x11: 000000000000000a
x12: 0000000000000000 x13: 0000000000000200
x14: 0000000040080000 x15: 0000000000000020
x16: 000000007ff59bf8 x17: 0000000000000000
x18: 000000007bf34df0 x19: 0000000040080000
x20: b900002098080381 x21: 0000000000000000
x22: 000000007bf64a40 x23: 0000000000000000
x24: 0000000000000002 x25: 0000000000000000
x26: 0000000000000000 x27: 0000000000000000
x28: 000000007bf65ec0 x29: 000000007bf2e590

Code: 17ffffd9 f9401674 8b140274 8b181a94 (f9400680)
Resetting CPU ...

Here are the files/commands I am using:

boot.txt:

···
setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p1 rootwait panic=10
load mmc 0:1 0x40080000 boot/app.elf

# bootm 0x42000000 - 0x43000000

bootelf 0x40080000 - 0x40280000`

start.S:

#define PACFG1  0x07022000
#define PADAT   0x07022010

.global _start
    .align 3
_start:
main_loop :
    bl led_on
    bl delay
    bl led_off
    bl delay
    b main_loop

led_on :
    ldr w0, = 0x11111111    
    ldr x1, = PACFG1
    str w0, [x1]            

    ldr w0, = 0xFFFFFFFF  
    ldr x1, = PADAT
    str w0, [x1]            
    ret

led_off :
    ldr w0, = 0x11111111    
    ldr x1, = PACFG1
    str w0, [x1]            

    ldr w0, = 0x0       
    ldr x1, = PADAT
    str w0, [x1]            
    ret

delay:
    mov x2, #0x40000
    mov x3, #0
delay_loop:
    sub x2, x2, #1    
    cmp x2, x3        
    bne delay_loop    
    ret

gboot.lds:

OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
ENTRY(_start)
SECTIONS
{
    . = 0x40080000;
    . = ALIGN(8);
    .text :
    {
        start.o(.text*)
        *(.text*)
    }

    . = ALIGN(8);
    .data :
    {
        *(.data*)
    }

    _end = .;

    . = ALIGN(8);

    .bss_start : {
        KEEP(*(.__bss_start));
    }
    . = ALIGN(8);

    .bss : {
        *(.bss*)
         . = ALIGN(8);
    }

    . = ALIGN(8);
    .bss_end : {
        KEEP(*(.__bss_end));
    } 
}

Makefile:

ARCH = arm64
CROSS_COMPILE = aarch64-none-linux-gnu
CC = $(CROSS_COMPILE)-gcc
LD = $(CROSS_COMPILE)-ld
OBJCOPY = $(CROSS_COMPILE)-objcopy

all : start.o
    $(LD) -Tgboot.lds -o gboot.elf $^
    $(OBJCOPY) -O binary gboot.elf gboot.bin
    ../tools/mksunxiboot gboot.bin gboot.bins

%.o : %.S
    $(CC) -g -c $^
%.o : %.c
    $(CC) -g -c $^

clean:
    rm -rf gboot.elf gboot.bin *.o gboot.bins

I am just using the 'gboot.elf' file, which I renamed to 'app.elf'. Its path on the SD card is: boot/app.elf.

I need a god to save me.


Solution

  • For this kind of typical bare-metal program, attempting to load an ELF file looks a little bit overkill to me. I was able to test your program on an Orangepi Plus One (Allwinner H6), with a slightly different procedure, and it was able to light a couple of the on-board LED on without triggering any exceptions, even though the wiring of the LEDs may be different on my SBC.

    I would add that mksunxiboot is 12 years old and was written for a Cortex-A7 A33 (32 bit) Soc. I would therefore stay away from this tool for now.

    Just copy gboot.bin on your SD card, and use the following commands:

    loadb mmc 0:1 0x40080000 boot/gboot.bin
    go 0x40080000
    

    Note that the gocommand is very convenient in your case because simple programs can just return to u-boot by executing ret - the value ix x0 will be returned to u-boot as the program exit code.

    Example:

            .global _start
            .align 3
            .text
    _start:
            mov x0, xzr
            add x0, x0, #10
            ret
    

    Now execute the program:

    => go 0x40080000
    ## Starting application at 0x40080000 ...
    ## Application terminated, rc = 0xA
    

    Application exited with 10d/0x0a as its exit status, as expected.

    Please note that if you load successive programs without rebooting, you may have to flush the caches in order to the second program to be executed instead of the cached first one:

    => dcache flush
    => icache flush
    => go 0x40080000
    ## Starting application at 0x40080000 ...
    ## Application terminated, rc = 0xA
    

    This caused me a load of headaches when I started experimenting with sample programs from u-boot.