基于全志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命令启动时触发上述异常。
问题排查与解决建议
解析ESR异常码:ESR值
0x96000004对应AArch64的Data Abort异常,具体为Translation fault, level 0,说明CPU访问的虚拟地址在MMU开启状态下无法完成地址翻译。U-Boot默认开启MMU,而你的ELF程序直接访问物理寄存器地址,导致地址翻译失败。关闭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 ...
- 简化
bootelf命令:bootelf会自动解析ELF文件的段信息并加载到指定地址,无需额外指定地址范围,修改命令为:
bootelf 0x40080000
验证ELF加载地址:通过
aarch64-none-linux-gnu-readelf -l gboot.elf检查ELF程序头,确认加载地址0x40080000与链接脚本一致,同时通过U-Boot的md命令验证文件是否正确加载到该物理地址。核对寄存器地址:确认全志H6的PA端口寄存器物理地址
0x07022000和0x07022010的正确性,可参考官方 datasheet 进行核对。
内容的提问来源于stack exchange,提问作者Jane
相关产品推荐
相关产品推荐

