使用uclinux和uclibc在Cortex-M3上处理未处理的MPU故障

时间:2014-11-05 15:34:17

标签: arm cortex-m3 uclibc uclinux mpu

这是一个难题,但我希望有人可以提供帮助;)

这是我从最简单的应用程序中发出的崩溃,它只调用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

以下是我通过解剖应用程序从objdump获得的内容:

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

所以我们试图将值0x5000保存到地址0xa001cff4并有一个例外:

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

所以它似乎是一个有效的物理RAM区域,地址0xa001cff4似乎也有效。 现在这对我来说很奇怪为什么在内核异常中它说的是0x00000000 这个例外意味着什么。

另外我想说单线程应用程序工作正常,我在新线程的堆栈分配期间遇到了这些MPU问题。但我现在想要了解的是 - 为什么MPU出现故障以及它如何能够在有效地址上失败。

1 个答案:

答案 0 :(得分:0)

我实际上做了什么 - 在内核中禁用了CONFIG_MPU并且它开始工作了。 之后我发现我的u-boot是自定义分叉,可能并没有很好地设置MPU。 没有CONFIG_MPU,一切都开始变得很好。 正如我所说的Cor​​tex-M3相关问题,我发现内核调试没有正确描述故障(0x00000000而不是真正的故障地址等)。