umanovskis / baremetal-arm

An ebook about bare-metal programming for ARM

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

04_cenv: data abort bug

qianfan-Zhao opened this issue · 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.