armcortex-muclibcuclinuxarm-mpu

unhandled MPU fault on Cortex-M3 with uclinux and uclibc


This is a hard question but I hope someone could help ;)

Here is the crash I have from simplest app which just calls pthread_create():

/ # /opt/zpm_thread 
00032 : pthread_initialize: initial thread stack bounds: bos=0x1, tos=0xffffffff
00032 : __pthread_initialize_manager: manager stack: size=8160, bos=0xa02fc008, tos=0xa02fdfe8
00032 : __pthread_initialize_manager: send REQ_DEBUG to manager thread
00032 : pthread_create: write REQ_CREATE to manager thread
00032 : pthread_create: before suspend(self)
00033 : __pthread_manager: before poll
00033 : __pthread_manager: after poll
00033 : __pthread_manager: before read
00033 : __pthread_manager: after read, n=28
00033 : __pthread_manager: got REQ_CREATE

[   13.100000] 
[   13.100000] zpm_thread: unhandled MPU fault (0x08) at 0x00000000 [pc=0xa0088e4a,sp=0xa02fde08]
[   13.100000] 
[   13.100000]  [fp=0x00000000]
[   13.100000] 
[   13.100000] 
[   13.100000] Pid: 33, comm:           zpm_thread
[   13.100000] CPU: 0    Not tainted  (2.6.33-arm1 #2)
[   13.100000] pc : [<a0088e4a>]    lr : [<a0088f8f>]    psr: 21000000
[   13.100000] sp : a02fde08  ip : a00980d8  fp : 00000000
[   13.100000] Code dump at pc [a0088e4a]:
[   13.100000] 68f8601a 683a6979 f7ff6a3b 697bffc8 
[   13.100000] r10: a0095bf0  r9 : 00000000  r8 : 00000000
[   13.100000] r7 : a02fde28  r6 : a02fdf9c  r5 : 00000020  r4 : a0097fb0
[   13.100000] r3 : a001cff4  r2 : 00005000  r1 : a0018000  r0 : a009c5d0
[   13.100000] Flags: nzCv  IRQs on  FIQs on  Mode USER_26  ISA unknown  Segment user
[   13.100000] Backtrace: no frame pointer

Here is what I got from objdump by dissecting the app:

00008dec <__heap_add_free_area>:
   free-area.  */
struct heap_free_area *
__heap_add_free_area (struct heap_free_area **heap, void *mem, size_t size,
                      struct heap_free_area *prev,
                      struct heap_free_area *next)
{
    8dec:       b580            push    {r7, lr}
    8dee:       b086            sub     sp, #24
    8df0:       af00            add     r7, sp, #0
    8df2:       60f8            str     r0, [r7, #12]
    8df4:       60b9            str     r1, [r7, #8]
    8df6:       607a            str     r2, [r7, #4]
    8df8:       603b            str     r3, [r7, #0]
  struct heap_free_area *fa = (struct heap_free_area *)
    8dfa:       68ba            ldr     r2, [r7, #8]
    8dfc:       687b            ldr     r3, [r7, #4]
    8dfe:       f1a3 030c       sub.w   r3, r3, #12
    ((char *)mem + size - sizeof (struct heap_free_area));
    8e02:       4413            add     r3, r2
    8e04:       617b            str     r3, [r7, #20]

  fa->size = size;
    8e06:       697b            ldr     r3, [r7, #20]           <-- store to r3 value from r7+20 ( we have valid pointer - OK)
    8e08:       687a            ldr     r2, [r7, #4]            <-- store to r2 0x5000 - OK
    8e0a:       601a            str     r2, [r3, #0]                    <-- FAIL HERE. (save 0x5000 to address a001cff4 (r3) - seems valid)

  __heap_link_free_area (heap, fa, prev, next);
    8e0c:       68f8            ldr     r0, [r7, #12]
    8e0e:       6979            ldr     r1, [r7, #20]
    8e10:       683a            ldr     r2, [r7, #0]
    8e12:       6a3b            ldr     r3, [r7, #32]
    8e14:       f7ff ffc8       bl      8da8 <__heap_link_free_area>

  return fa;
    8e18:       697b            ldr     r3, [r7, #20]
}
    8e1a:       4618            mov     r0, r3
    8e1c:       f107 0718       add.w   r7, r7, #24
    8e20:       46bd            mov     sp, r7
    8e22:       bd80            pop     {r7, pc}

(gdb) x/100x 0xa02fde28
0xa02fde28: 0x00000000  0x00005000  0xa0018000  0xa009c5d0
0xa02fde38: 0x04000021  0xa001cff4  0xa02fde50  0xa0088f8f
0xa02fde48: 0xa009c5c4  0xa0097fb0  0x00000020  0x00005000
0xa02fde58: 0xa0018000  0xa009c5d0  0x00000000  0xa009c5c4
0xa02fde68: 0x00000000  0xa001d000  0x00005000  0xa00a0834
0xa02fde78: 0xa02fde88  0xa00886b9  0x00000000  0x00000000
0xa02fde88: 0x00000000  0xa00a0834  0xa009c5d0  0x00004008
0xa02fde98: 0x00000000  0xa0018000  0x00005000  0x00000000
0xa02fdea8: 0x00000000  0x00000000  0xa02fdeb8  0xa0088851
0xa02fdeb8: 0x00000000  0x00004000  0x00000000  0x00000000
0xa02fdec8: 0xa02fded0  0xa0082b97  0xa02fdf3c  0x00001000
0xa02fded8: 0xffffbea1  0x00000000  0x00000000  0x00000000
0xa02fdee8: 0x00000000  0x00000000  0x00004000  0xa02fdf88
0xa02fdef8: 0x0000001c  0x00000003  0x726f6665  0x00000002
0xa02fdf08: 0xa02fdf20  0xa0082d25  0xa02fdf38  0xa02fdf34
0xa02fdf18: 0xa02fdf30  0x00000003  0x00000000  0xa00800a5
0xa02fdf28: 0x00000000  0xa0097fe0  0x00000000  0x00000000
0xa02fdf38: 0x00000000  0x00000000  0x00000002  0xa0098110
0xa02fdf48: 0xa02fdf50  0x0000002a  0x00001000  0x00000000
0xa02fdf58: 0xa02fdf80  0xa0082841  0xa0095efc  0xa0097fb0
0xa02fdf68: 0xa02fdf80  0xa0082881  0xa02fdf9c  0x00000020
0xa02fdf78: 0x00000000  0xa00980d8  0x00000000  0x00000003
0xa02fdf88: 0xa0097fb0  0x00000000  0x00000000  0xa00800a5
0xa02fdf98: 0x00000000  0x80000000  0x00000000  0xffffffef
0xa02fdfa8: 0xfffffffe  0x00000003  0x00010001  0x00000003
(gdb) x/100x 0xa001cff4
0xa001cff4: 0x00000000  0x00000000  0x00000000  0x1d03d003
0xa001d004: 0x28006840  0x6841d1f8  0xf0066019  0x4620fa3d
0xa001d014: 0x490d4632  0xfe74f004  0xe74c2001  0x4b091c58
0xa001d024: 0x99029000  0xb9ab681b  0xbf00e75e  0x64790100
0xa001d034: 0x70790100  0x80790100  0x90790100  0xa0790100
0xa001d044: 0x50790100  0xb4a90100  0x58790100  0x2b00685b
0xa001d054: 0xaf4af43f  0x4291681a  0x4668d1f8  0xf7ffa901
0xa001d064: 0x4680fc49  0xf47f2800  0x9f00af3f  0xc000f897
0xa001d074: 0x0f2cf1bc  0xaf38f47f  0x19a61c7d  0x95001b76
0xa001d084: 0xf7ff4630  0x2e00f901  0xdd384605  0xe001f897
0xa001d094: 0x36011e71  0xf1be4642  0xf0010f7d  0xbf1c0101
0xa001d0a4: 0xe000f880  0x0801f04f  0x2302d04b  0xd02342b3
0xa001d0b4: 0x5cf9b159  0x297db9b2  0xf805bf1a  0xf1081008
0xa001d0c4: 0x22010801  0x42b33301  0x5cf9d016  0xf081b352
0xa001d0d4: 0x22000020  0x0008f805  0x0801f108  0x5cf93301
0xa001d0e4: 0xd0e82a00  0x22003301  0xf08142b3  0xf8050c20
0xa001d0f4: 0xf108c008  0xd1e80801  0xf47f2a00  0x4642aef5
0xa001d104: 0x46299802  0xf0049b01  0xf1b0fb13  0xd01a3fff
0xa001d114: 0x49174602  0xf0044620  0x4628fdf3  0xf9b4f006
0xa001d124: 0xe6c82001  0xbf1a297d  0x1008f805  0x0801f108
0xa001d134: 0xe7d32201  0xf7ff4620  0x2001fd11  0x4b0de6bb
0xa001d144: 0x2201e761  0x4620e7b1  0xfd08f7ff  0xf0064628
0xa001d154: 0x2001f99b  0x4620e6af  0x4631462b  0xfd9af7ff
0xa001d164: 0xf7ffe716  0x4630fcfb  0xf98ef006  0xe6a22001
0xa001d174: 0x58790100  0xb4a90100  0xe92d4b76  0x681a01f0

So we are trying to save value 0x5000 to the address 0xa001cff4 and have an exception:

zpm_thread: unhandled MPU fault (0x08) at 0x00000000 [pc=0xa0088e4a,sp=0xa02fde08]

I have 8Mb SDRAM in range 0xa0000000 - 0xa0800000
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0x00000000 - 0x00001000   (   4 kB)
[    0.000000]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
[    0.000000]     vmalloc : 0x00000000 - 0xffffffff   (4095 MB)
[    0.000000]     lowmem  : 0xa0000000 - 0xa0800000   (   8 MB)
[    0.000000]     modules : 0xa0000000 - 0x01000000   (1552 MB)
[    0.000000]       .init : 0xa0008000 - 0xa00e4000   ( 880 kB)
[    0.000000]       .text : 0xa00e4000 - 0xa0197000   ( 716 kB)
[    0.000000]       .data : 0xa0198000 - 0xa01a7c80   (  64 kB)
...
[    4.700000] Freeing init memory: 880K

So it seems to be a valid physical RAM area and address 0xa001cff4 seems valid either. Now this is quite strange for me why in kernel exception it says about 0x00000000 and what this exception means.

Also I want to say that single thread apps works fine and I have those MPU issues during stack allocation for a new threads. But what I want to understand now - why is it MPU fault and how is it able to fail on valid address.


Solution

  • What I actually did - disabled CONFIG_MPU in kernel and it started to work. After that I found that my u-boot is custom fork and probably doesn't setup MPU well. Without CONFIG_MPU everything started to work great. As I said it's Cortex-M3 related issue and what I found is that kernel debug not properly describes the fault (0x00000000 instead of real fault address etc).