Skip to content
Advertisement

How to understand the ARM registers dumped by kernel panic?

After Linux kernel oops on ARM platform, registers are dumped to console. But I got confused with analyzing these registers.

For example,

Unable to handle kernel paging request at virtual address 0b56e8b8
pgd = c0004000
[0b56e8b8] *pgd=00000000
 Internal error: Oops: 5 [#1] PREEMPT SMP ARM
    ......
 pc : [<bf65e7c0>]    lr : [<bf65ec14>]    psr: 20000113
 sp : c07059f0 ip : 00008d4c  fp : c0705a3c
 r10: 00000003  r9 : e8bcd800  r8 : e88b006c
 r7 : 0000e203  r6 : c0705a44  r5 : e88b0000  r4 : 0b56e8b8
 r3 : 00000000 r2 : 00000b56  r1 : e4592e10  r0 : e889570c
 Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
 Control: 10c5787d  Table: 69fec06a  DAC: 00000015

SP: 0xc0705970:
5970  e8e70000 e45de100 00000181 00000180 c070599c bf65e7c0 20000113 ffffffff
5990  c07059dc e88b006c c0705a3c c07059a8 c000e318 c0008360 e889570c e4592e10
59b0  00000b56 00000000 0b56e8b8 e88b0000 c0705a44 0000e203 e88b006c e8bcd800
59d0  00000003 c0705a3c 00008d4c c07059f0 bf65ec14 bf65e7c0 20000113 ffffffff
59f0  e8b80000 e2030b56 00000000 e889570c 00000003 e88b006c c007eccc c007ebb4
5a10  00000000 eacc0480 e88b0000 00002098 e9c80480 e8c08000 00000000 e8bcdc80
5a30  c0705a5c c0705a40 bf65ec14 bf65e6c0 bf5e51c4 00000000 e88b0000 00000000
5a50  c0705a74 c0705a60 bf65ecfc bf65ebe4 e4554500 e4554500 c0705a84 c0705a78

R5: 0xe88aff80:
ff80  bf10f0b0 e8aca4c0 e88aff8c e88b1680 00000000 bf05b70c e87c3580 00000000
ffa0  bf095024 e87c3580 00000000 bf095024 e87c3580 00000000 bf095024 00000001
ffc0  00000004 ebd83000 00000793 e8cc2500 00000002 00000004 00000043 ffffffff
ffe0  40320354 be9ee8d8 00030444 40320380 20000010 00000000 70cfe821 70cfec21
0000  bf81e1f8 e88b0018 e88b000c e88e9a00 00000000 bf095024 00000000 fffffffe
0020  00000000 00000000 fffffffe 00000000 00000000 fffffffe 00000000 00000000
0040  00000001 e91dd000 00001073 0010051b 00080000 f1e4d900 00000001 00000002
0060  000000c8 6df9eca0 00008044 e8895700 00000040 00000026 00000003 0b56e8b8

R8: 0xe88affec:
ffec  40320380 20000010 00000000 70cfe821 70cfec21 bf81e1f8 e88b0018 e88b000c
000c  e88e9a00 00000000 bf095024 00000000 fffffffe 00000000 00000000 fffffffe
002c  00000000 00000000 fffffffe 00000000 00000000 00000001 e91dd000 00001073
004c  0010051b 00060000 f1e4d900 00000001 00000002 000000c8 6df9eca0 00008044
006c  e8895700 00000040 00000026 00000003 0b56e8b8 e4604000 0000026c 000000da
008c  00000000 21d7ff6e 000078a9 bf05add4 e88b0000 e88b0000 ebd02600 f1015a05
00ac  00000001 000000a6 000000c4 00000000 e88b0000 1e1e1e1e 1e1e1e1e 1e1e1e1e
00cc  1e1e1e1e 1e1e1e1e 1e1e1e1e 1e1e1e1e 1e1e1e1e 1e1e1e1e 1e1e1e1e 1e1e1e1e

Questions:

  1. What does the 0xc0705970 stands for in SP: 0xc0705970:? Code address or data address? Where to find it?

  2. Why sp : c07059f0 is not at the beginning or end of SP register? How is the stack organized in this register?

  3. What does the first column of each register mean? If they stand for relative address, why are they not continuous?

  4. Is 0b56e8b8 a pointer pointing to a page? How is it be accessed in R5 and R8?

Advertisement

Answer

How the registers are used in an OS is something up to the ABI, a.k.a Application Binary Interface.

However we can give a quick, informal and simplified explanation of the dump.

I’m not an expert on Linux on ARM but some name seem quite intuitive:

  • sp is Stack Pointer. A pointer to a useful memory area called the stack.
  • fp is Frame Pointer. A pointer used by routine to access local vars.
  • lr is Link Register. A register containing the Return address of a call.
  • nzCv are the flags, If a flag is in uppercase it is set, otherwise clear.
    • n = Last result was Negative
    • z = Last result was Zero
    • C = Last result needed/produced a Carry bit
    • v = Last result Overflowed
  • IRQ on means Hardware interrupts are enabled.
  • FIRQ on means that some hardware interrupts are handled with a fast context switch.
  • Mode is the CPU mode, indicating that the code was privileged.
  • The following info are control structures for the the CPU set by the kernel.

The dump make you a favor by considering the sp, r5 and r8 register values as pointers and showing the memory at that addresses.
The block below SP: 0xc0705970: for example is a dump of the memory at 0xc0705970. Each row is formatted as follow:

  • The first column is the current address. Only the last four digit are shown as is it obvious what the full address is (ie there is no ambiguity, the addresses start from 0xc0705970).

  • The following eight columns are 32 bit values dumped from memory. Each row show you 32 byte of memory.

For example by looking at

R5: 0xe88aff80:
ff80  bf10f0b0 e8aca4c0 e88aff8c e88b1680 00000000 bf05b70c e87c3580 00000000
ffa0  bf095024 e87c3580 00000000 bf095024 e87c3580 00000000 bf095024 00000001
ffc0  00000004 ebd83000 00000793 e8cc2500 00000002 00000004 00000043 ffffffff
ffe0  40320354 be9ee8d8 00030444 40320380 20000010 00000000 70cfe821 70cfec21
0000  bf81e1f8 e88b0018 e88b000c e88e9a00 00000000 bf095024 00000000 fffffffe
0020  00000000 00000000 fffffffe 00000000 00000000 fffffffe 00000000 00000000
0040  00000001 e91dd000 00001073 0010051b 00080000 f1e4d900 00000001 00000002
0060  000000c8 6df9eca0 00008044 e8895700 00000040 00000026 00000003 0b56e8b8

You can tell that the 32 bit value r5 was pointing to was 0xbf10f0b0 or that the 32 bit value at 0xe88a0000 was 0xbf81e1f8 or that the 32 bit value at 0xe88a0028 was 0xfffffffe.

All this information are useful for the developer of the code that panicked.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement