You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于全志H6的OrangePi-Lite2开发板U-Boot启动ELF文件异常求助

全志H6(OrangePi-Lite2)U-Boot启动ELF触发Synchronous Abort异常排查

基于全志H6(Cortex-A53 CPU)的OrangePi-Lite2开发板,通过U-Boot启动ELF文件时触发Synchronous Abort异常,ESR值为0x96000004,具体报错信息如下:

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 ...

操作流程与相关文件

U-Boot启动脚本(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

执行步骤

将编译生成的gboot.elf重命名为app.elf,放置在SD卡的boot/app.elf路径下,通过U-Boot执行bootelf命令启动时触发上述异常。

问题排查与解决建议

  1. 解析ESR异常码:ESR值0x96000004对应AArch64的Data Abort异常,具体为Translation fault, level 0,说明CPU访问的虚拟地址在MMU开启状态下无法完成地址翻译。U-Boot默认开启MMU,而你的ELF程序直接访问物理寄存器地址,导致地址翻译失败。

  2. 关闭MMU与缓存:在_start入口处添加关闭MMU和缓存的代码,确保程序运行在物理地址空间:

_start:
    // 关闭MMU、ICache、DCache
    mrs x0, sctlr_el1
    bic x0, x0, #(1 << 0)    // 关闭MMU (M bit)
    bic x0, x0, #(1 << 12)   // 关闭ICache (I bit)
    bic x0, x0, #(1 << 2)    // 关闭DCache (C bit)
    msr sctlr_el1, x0
    isb
    dsb sy

main_loop :
    bl led_on
    ...
  1. 简化bootelf命令:bootelf会自动解析ELF文件的段信息并加载到指定地址,无需额外指定地址范围,修改命令为:
bootelf 0x40080000
  1. 验证ELF加载地址:通过aarch64-none-linux-gnu-readelf -l gboot.elf检查ELF程序头,确认加载地址0x40080000与链接脚本一致,同时通过U-Boot的md命令验证文件是否正确加载到该物理地址。

  2. 核对寄存器地址:确认全志H6的PA端口寄存器物理地址0x07022000和0x07022010的正确性,可参考官方 datasheet 进行核对。

内容的提问来源于stack exchange,提问作者Jane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 02:09:18