04_cenv: data abort bug
qianfan-Zhao opened this issue · 4 comments
Hi:
04_cenv example doesn't work on my qemu env, data abort bug happens, next is the u-boot logs:
## Booting kernel from Legacy Image at 60000000 ...
Image Name:
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 502 Bytes = 502 Bytes
Load Address: 60000000
Entry Point: 60000000
Verifying Checksum ... OK
Loading Kernel Image ... OK
Starting kernel ...
data abort
pc : [<60000080>] lr : [<7ff974f0>]
sp : 70003008 ip : 7fef5976 fp : 00000000
r10: 7fef6a6c r9 : 7fef5ef8 r8 : 00000001
r7 : 00000000 r6 : 60000000 r5 : 7ffd85cc r4 : 00000000
r3 : 7fef5fa8 r2 : 70000008 r1 : 70000000 r0 : 600001ee
Flags: Nzcv IRQs on FIQs on Mode SVC_32
Code: e59f0050 e59f1050 e59f2050 e1510002 (b4903004)
Resetting CPU ...
resetting ...
Next is the asm code disassembly by objdump.
60000070: e59f0050 ldr r0, [pc, #80] ; 600000c8 <Abort_Exception+0x1c>
60000074: e59f1050 ldr r1, [pc, #80] ; 600000cc <Abort_Exception+0x20>
60000078: e59f2050 ldr r2, [pc, #80] ; 600000d0 <Abort_Exception+0x24>
6000007c <data_loop>:
6000007c: e1510002 cmp r1, r2
60000080: b4903004 ldrlt r3, [r0], #4
60000084: b4813004 strlt r3, [r1], #4
60000088: bafffffb blt 6000007c <data_loop>
6000008c: e3a00000 mov r0, #0
60000090: e59f103c ldr r1, [pc, #60] ; 600000d4 <Abort_Exception+0x28>
60000094: e59f203c ldr r2, [pc, #60] ; 600000d8 <Abort_Exception+0x2c>
...
600000c8: 600001ee .word 0x600001ee
600000cc: 70000000 .word 0x70000000
600000d0: 70000008 .word 0x70000008
Seems data abort is trigger by unaligned memory access, _text_end
is not an aligned address.
$ arm-none-eabi-objdump -t cenv.elf | grep text_end
600001ee g .text 00000000 _text_end
Apply this patch to make sure text section aligned, this example can work fine again.
diff --git a/src/04_cenv/linkscript.ld b/src/04_cenv/linkscript.ld
index ab58e41..eb5f558 100644
--- a/src/04_cenv/linkscript.ld
+++ b/src/04_cenv/linkscript.ld
@@ -14,6 +14,7 @@ SECTIONS
startup.o (.vector_table)
*(.text*)
*(.rodata*)
+ . = ALIGN(4);
} > ROM
_text_end = .;
.data : AT(ADDR(.text) + SIZEOF(.text))
Now _text_end
is an aligned address.
$ arm-none-eabi-objdump -t cenv.elf | grep text_end
600001f0 g .text 00000000 _text_end
@qianfan-Zhao how you know? Explain please
u-boot report the register values when bug happens, you can read the PC value:
data abort
pc : [<60000080>] lr : [<7ff974f0>]
disassembly the code in this location:
60000080: b4903004 ldrlt r3, [r0], #4
R0 is also printed by u-boot, it's value is r0 : 600001ee
, that is not a aligned value.
@qianfan-Zhao could you guess why the symbol was apparently aligned for the author (the pdf shows it at 600001ea)? maybe the linker version implicitly aligned it? just very curious :)
@qianfan-Zhao could you guess why the symbol was apparently aligned for the author (the pdf shows it at 600001ea)? maybe the linker version implicitly aligned it? just very curious :)
I think it is a behavier of the gcc, this code is developed at many years ago and gcc also has many versions this years.