f9micro / f9-kernel

An efficient and secure microkernel built for ARM Cortex-M cores, inspired by L4
Other
682 stars 145 forks source link

Try to access the GPIO pin from user space cause Memory fault #87

Closed benwei closed 10 years ago

benwei commented 10 years ago

I'm trying to modify the PR #86 move the gpio driver (gpio.c with __USER_TEXT)

Unfortunately, Memory fault occurred at 40023830 this address is accessed by gpio_config()

  *RCC_AHB1ENR |= (1 << port);

after gcc -E expended

*(volatile uint32_t *) ((((uint32_t) (0x40000000) + 0x00020000) + 0x3800) + 0x30)
        |= (1 << port);

even though I have grant memory.c memmap table from

         DECLARE_MEMPOOL("AHB1_1DEV", 0x40020000, 0x40022400,

to

         DECLARE_MEMPOOL("AHB1_1DEV", 0x40020000, 0x4002383f,

kernel dump show that user can read/write

----- part from dump begin ----- `
AHB1_1DEV       14399 [40020000:4002383f] --- rw- D
----- part from dump end ----- 

Are there any idea?

===================================================
      Copyright(C) 2013 The F9 Microkernel Project
====================================================
Git head: 972471e29447f150a9504dcc0d5c815e750c6ec2
Host: i686
Build: 2014-04-21T02:21:44+0800

Press '?' to print KDB menu
test gpioer to on off

-------MPU------
b:2000ff00, sz:2**8, attr:1300
b:2000f800, sz:2**8, attr:0300
b:2000fa00, sz:2**9, attr:1300
b:2000f400, sz:2**10, attr:0300
b:20000400, sz:2**8, attr:1300
b:20000500, sz:2**8, attr:1300
b:2000ee00, sz:2**9, attr:0300
b:2000f000, sz:2**8, attr:0300
Memory fault mmsr:00000082, mmar:40023830,
             current:00404002, psp:2000ffb8, pc:2000eefc

-------KTABLES------

KT: fpage_table
bitmap:10000000, data:2000c4e4, num: 256 size: 24
    0: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX--------------------------------
   64: ----------------------------------------------------------------
  128: ----------------------------------------------------------------
  192: ----------------------------------------------------------------

KT: as_table
bitmap:10000028, data:2000e0e4, num: 16 size: 20
    0: XX--------------
KT: ktimer_event_table
bitmap:10000020, data:2000dce4, num: 64 size: 16
    0: X---------------------------------------------------------------

KT: thread_table
bitmap:1000002c, data:2000e224, num: 32 size: 88
    0: XXXXX----------------------------------KTIMER------

ktimer events:
EVENT    DELTA
2000dce4           64
-------NOW------
Now is 0
Ktimer T=3 D=0
-------SOFTIRQ------
Kernel timer events              not scheduled
Asynchronous events              not scheduled
System calls                     not scheduled
KDB enters                       not scheduled
-------THREADS------
type  global   local    state  parent
IDLE  00000000 00000000 RUN    00000000
ROOT  00008000 00000000 RECV   00000000
KERN  00004000 00000000 FREE   00000000
[USR] 00400002 00000040 RECV   00008000
[USR] 00404002 00000040 RUN    00400002
-------MEMPOOLS------
NAME       SIZE       [START   :END     ] FLAGS
KTEXT           20544 [08001000:08006040] r-x --- N
UTEXT            2816 [2000ee00:2000f900] --- r-x M
KIP               512 [20000400:20000600] rw- r-- S
KDATA             888 [20000600:20000978] rw- --- N
KBSS            58148 [20000a00:2000ed24] rw- --- N
UDATA             768 [2000f900:2000fc00] --- rw- M
UBSS                0 [2000fc00:2000fc00] --- rw- M
MEM0            50176 [2000fc00:2001c000] --- rw- S
KBITMAP            48 [10000000:10000030] rw- --- N
MEM1            65488 [10000030:10010000] --- rw- A
APB1DEV         30720 [40000000:40007800] --- rw- D
APB2_1DEV       13312 [40010000:40013400] --- rw- D
APB2_2DEV        3072 [40014000:40014c00] --- rw- D
AHB1_1DEV       14399 [40020000:4002383f] --- rw- D
AHB1_2DEV      115712 [40023c00:40040000] --- rw- D
AHB2DEV        397312 [50000000:50061000] --- rw- D
AHB3DEV    1073745920 [60000000:a0001000] --- rw- D
-------AS------
Address Space 00008000
MEM:   fpage KIP   [b:20000400, sz:2**8]
MEM: o fpage KIP   [b:20000500, sz:2**8]
MEM: o fpage UTEXT [b:2000ee00, sz:2**9]
MEM: o fpage UTEXT [b:2000f000, sz:2**8]
MEM: o fpage UTEXT [b:2000f100, sz:2**8]
MEM: o fpage UTEXT [b:2000f200, sz:2**9]
MEM: o fpage UTEXT [b:2000f400, sz:2**10]
MEM:   fpage UTEXT [b:2000f800, sz:2**8]
MEM: o fpage UDATA [b:2000f900, sz:2**8]
MEM: o fpage UDATA [b:2000fa00, sz:2**9]
MEM:   fpage MEM0  [b:2000fc00, sz:2**8]
MEM:   fpage MEM0  [b:2000fd00, sz:2**8]
MEM:   fpage MEM0  [b:2000fe00, sz:2**8]
MEM:   fpage MEM0  [b:2000ff00, sz:2**8]
Address Space 00400002
MEM: o fpage KIP   [b:20000400, sz:2**8]
MEM: o fpage KIP   [b:20000500, sz:2**8]
MEM: o fpage UTEXT [b:2000ee00, sz:2**9]
MEM: o fpage UTEXT [b:2000f000, sz:2**8]
MEM:   fpage UTEXT [b:2000f100, sz:2**8]
MEM:   fpage UTEXT [b:2000f200, sz:2**9]
MEM: o fpage UTEXT [b:2000f400, sz:2**10]
MEM: o fpage UTEXT [b:2000f800, sz:2**8]
MEM:   fpage UDATA [b:2000f900, sz:2**8]
MEM: o fpage UDATA [b:2000fa00, sz:2**9]
MEM:   fpage MEM0  [b:2000fc00, sz:2**8]
MEM:   fpage MEM0  [b:2000fc00, sz:2**8]
MEM:   fpage MEM0  [b:2000fd00, sz:2**8]
MEM:   fpage MEM0  [b:2000fe00, sz:2**8]
MEM:   fpage MEM0  [b:2000fe00, sz:2**8]
MEM: o fpage MEM0  [b:2000ff00, sz:2**8]
-------TOP------
Init sampling...

Stack dump:
20000388 00000082 08005fb4 2000e384 40023830 00000000 080017ef 08005594
00000082 40023830 00404002 2000ffb8 2000eefc 08004ca3 00000002 08005fb4
2000ff8c 00000000 08001803 fffffffd 00000001 08005bf4 200003b0 08004769
000000f0 08004303 08004770 61000000 08004769 080046dd 00000000 080046bb
00000000 0800472d e000ed24 08004519 40023c00 08003869 00000000
georgekang commented 10 years ago

Does your user space get the authority of AHB1_1DEV?

benwei commented 10 years ago

No, I don't know how to make a thread with authority of AHB1_1DEV. Tried something like L4_Map within user/root_thread.c, but there is no any improvement. I would appreciate if you or anyone could give me a hint or example.

georgekang commented 10 years ago
  1. All memory(USER_TEXT, USER_DATA) used for user space app is fetched by root thread.
    If your user app wants to use gpio memory space, you should add this space to address space of root thread. Following patch is an example to add "AHB1_1DEV" to root thread's address space. And root thread can access it.
  2. Once root thread gets this memory space, your user app could use this memory by L4 mapping. (Map this memory to user app's address space.)

Map "AHB1_1DEV" to root thread. And root thread could access it. (Just a hacking for explanation)

diff --git a/kernel/memory.c b/kernel/memory.c
index fe24d5f..ef479e2 100644
--- a/kernel/memory.c
+++ b/kernel/memory.c
@@ -108,9 +108,8 @@ memptr_t mempool_align(int mpid, memptr_t addr)
        case MP_MEMPOOL:
        case MP_SRAM:
        case MP_AHB_RAM:
-               return addr_align(addr, CONFIG_SMALLEST_FPAGE_SIZE);
        case MP_DEVICES:
-               return addr & 0xFFFC0000;
+               return addr_align(addr, CONFIG_SMALLEST_FPAGE_SIZE);
        }

        return addr_align(addr, CONFIG_SMALLEST_FPAGE_SIZE);
@@ -300,9 +299,14 @@ void as_map_user(as_t *as)
                switch (memmap[i].tag) {
                case MPT_USER_DATA:
                case MPT_USER_TEXT:
+                               assign_fpages(as, memmap[i].start,
+                                             (memmap[i].end - memmap[i].start));
+               case MPT_DEVICES:
                        /* Create fpages only for user text and user data */
-                       assign_fpages(as, memmap[i].start,
-                                     (memmap[i].end - memmap[i].start));
+                       if (memmap[i].start == 0x40020000)
+                               assign_fpages(as, memmap[i].start,
+                                             (memmap[i].end - memmap[i].start));
+                       break;
                }
        }
 }
diff --git a/user/root_thread.c b/user/root_thread.c
index 38effc9..24019cf 100644
--- a/user/root_thread.c
+++ b/user/root_thread.c
@@ -9,6 +9,7 @@
 #include <l4/ipc.h>
 #include <types.h>
 #include <user_runtime.h>
+#include <l4io.h>

 extern user_struct user_runtime_start[];
 extern user_struct user_runtime_end[];
@@ -79,6 +80,8 @@ void __USER_TEXT __root_thread(kip_t *kip_ptr, utcb_t *utcb_ptr)
        L4_ThreadId_t myself = {.raw = utcb_ptr->t_globalid};
        char *free_mem = (char *) get_free_base(kip_ptr);

+       printf("0x40020000 = 0x%x\n", *(unsigned int *)0x40020000);
+
        for (user_struct *ptr = user_runtime_start; ptr != user_runtime_end; ++ptr) {
                L4_ThreadId_t tid;
                L4_Word_t stack;

Output:

====================================================
      Copyright(C) 2013 The F9 Microkernel Project  
====================================================
Git head: fa1e2284b5a74bf2a0dec0c40d5e346f6338db6e
Host: x86_64
Build: 2014-04-21T14:47:59+0800

Press '?' to print KDB menu
0x40020000 = 0xa800000a

L4/Pistachio test suite starts

Simple IPC test (inter-as, only untyped words)
  Send Message transfer:   OK
  ReplyWait Message transfer:   OK
Returned Id 0 != 0 (local) [0 (global)]
  From parameter (local):   FAILED
#
georgekang commented 10 years ago

However, I still do not know the meaning of mask 0xFFFC0000 for MP_DEVICES.
@jserv , could you explain this? Thanks.

benwei commented 10 years ago

Thank for georgekang's hint. It's great. I'm going to try this mechanism for moving gpio driver to user-space this weekend.

jserv commented 10 years ago

@georgekang : It was a historical reason when F9 was prototyping on earlier CM4 cores. You can map the device to any valid address for root task.

jserv commented 10 years ago

After commit 635d63b5005f2137c6b600d86ea20762bc3fbbce, I think the root thread already exposes enough address space maps for accessing GPIOs. So, I close this issue first.