Browse Source

!367 整理 smart 代码,优化 lwp 宏依赖
Merge pull request !367 from morphlings2014/rt-smart

bernard 4 năm trước cách đây
mục cha
commit
a48ee7ceb7

+ 22 - 1
components/dfs/filesystems/romfs/dfs_romfs.c

@@ -34,7 +34,28 @@ int dfs_romfs_unmount(struct dfs_filesystem *fs)
 
 int dfs_romfs_ioctl(struct dfs_fd *file, int cmd, void *args)
 {
-    return -EIO;
+    int ret = RT_EOK;
+    struct romfs_dirent *dirent;
+
+    dirent = (struct romfs_dirent *)file->fnode->data;
+    RT_ASSERT(dirent != NULL);
+
+    switch (cmd)
+    {
+    case RT_FIOGETADDR:
+        {
+            *(rt_uint32_t*)args = (rt_uint32_t)dirent->data;
+            break;
+        }
+    case RT_FIOFTRUNCATE:
+        {
+            break;
+        }
+    default:
+        ret = -RT_EINVAL;
+        break;
+    }
+    return ret;
 }
 
 rt_inline int check_dirent(struct romfs_dirent *dirent)

+ 1 - 1
components/dfs/include/dfs_file.h

@@ -82,7 +82,7 @@ int dfs_file_ftruncate(struct dfs_fd *fd, off_t length);
 
 /* 0x5254 is just a magic number to make these relatively unique ("RT") */
 #define RT_FIOFTRUNCATE  0x52540000U
-#define RT_FIOGETXIPADDR 0x52540001U
+#define RT_FIOGETADDR    0x52540001U
 
 #ifdef __cplusplus
 }

+ 1 - 2
components/libc/compilers/newlib/SConscript

@@ -18,10 +18,9 @@ if rtconfig.PLATFORM == 'gcc' and GetDepend('RT_USING_LIBC'):
         # musl libc is used as a software library.
         src  = []
         LIBS = []
-    elif not GetDepend('RT_USING_NEWLIB'):
+    elif GetDepend('RT_USING_NEWLIB'):
         # RT_USING_NEWLIB is defined already
         CPPPATH = [cwd]
-        CPPDEFINES = ['RT_USING_NEWLIB']
         group = DefineGroup('newlib', src, depend = ['RT_USING_LIBC'], 
             CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES, LIBS = LIBS)
 

+ 44 - 43
components/lwp/Kconfig

@@ -1,5 +1,5 @@
-config RT_USING_LWP
-    bool "Using light-weight process"
+menuconfig RT_USING_LWP
+    bool "light-weight process"
     select RT_USING_DFS
     select RT_USING_LIBC
     select RT_USING_POSIX_CLOCKTIME
@@ -12,53 +12,54 @@ if RT_USING_LWP
     config RT_LWP_MAX_NR
         int "The max number of light-weight process"
         default 30
-endif
 
-config LWP_TASK_STACK_SIZE
-    int "The lwp thread kernel stack size"
-    default 16384
-    depends on RT_USING_LWP
+    config LWP_TASK_STACK_SIZE
+        int "The lwp thread kernel stack size"
+        default 16384
 
-config RT_CH_MSG_MAX_NR
-    int "The maximum number of channel messages"
-    default 1024
-    depends on RT_USING_LWP
+    config RT_CH_MSG_MAX_NR
+        int "The maximum number of channel messages"
+        default 1024
 
-config RT_LWP_SHM_MAX_NR
-    int "The maximum number of shared memory"
-    default 64
-    depends on RT_USING_LWP
+    config LWP_CONSOLE_INPUT_BUFFER_SIZE
+        int "The input buffer size of lwp console device"
+        default 1024
 
-config LWP_CONSOLE_INPUT_BUFFER_SIZE
-    int "The input buffer size of lwp console device"
-    default 1024
-    depends on RT_USING_LWP
+    config LWP_TID_MAX_NR
+        int "The maximum number of lwp thread id"
+        default 64
 
-config LWP_TID_MAX_NR
-    int "The maximum number of lwp thread id"
-    default 64
-    depends on RT_USING_LWP
+    if ARCH_ARM_MMU
+        config RT_LWP_SHM_MAX_NR
+            int "The maximum number of shared memory"
+            default 64
+    endif
 
-config LWP_UNIX98_PTY 
-    bool "The unix98 PTY support"
-    default n
-    depends on RT_USING_LWP
+    if ARCH_MM_MPU
+        config RT_LWP_MPU_MAX_NR
+            int "The maximum number of mpu region"
+            default 2
+
+        config RT_LWP_USING_SHM
+            bool "Enable shared memory"
+            default y
+    endif
 
-config LWP_PTY_INPUT_BFSZ 
-    int "The unix98 PTY input buffer size"
-    default 1024 
-    depends on RT_USING_LWP
-    depends on LWP_UNIX98_PTY
+    config LWP_UNIX98_PTY
+        bool "The unix98 PTY support"
+        default n
 
-config LWP_PTY_PTS_SIZE 
-    int "The unix98 PTY device max num"
-    default 3 
-    depends on RT_USING_LWP
-    depends on LWP_UNIX98_PTY
+    if LWP_UNIX98_PTY
+        config LWP_PTY_INPUT_BFSZ
+            int "The unix98 PTY input buffer size"
+            default 1024
 
-config LWP_PTY_USING_DEBUG 
-    bool "The unix98 PTY debug output"
-    default n 
-    depends on RT_USING_LWP
-    depends on LWP_UNIX98_PTY
-    
+        config LWP_PTY_PTS_SIZE 
+            int "The unix98 PTY device max num"
+            default 3
+
+        config LWP_PTY_USING_DEBUG 
+            bool "The unix98 PTY debug output"
+            default n
+    endif
+endif

+ 7 - 2
components/lwp/SConscript

@@ -1,5 +1,6 @@
 Import('rtconfig')
 from building import *
+import os
 
 cwd     = GetCurrentDir()
 src     = []
@@ -30,10 +31,14 @@ if platform in platform_file.keys(): # support platforms
     if arch in support_arch.keys() and cpu in support_arch[arch]:
         asm_path = 'arch/' + arch + '/' + cpu + '/*_' + platform_file[platform]
         arch_common = 'arch/' + arch + '/' + 'common/*.c'
-        src += Glob('*.c') + Glob(asm_path) + Glob(arch_common)
+        if not GetDepend('ARCH_ARM_MMU'):
+            excluded_files = ['ioremap.c', 'lwp_futex.c', 'lwp_mm_area.c', 'lwp_pmutex.c', 'lwp_shm.c', 'lwp_user_mm.c']
+            src += [f for f in Glob('*.c') if os.path.basename(str(f)) not in excluded_files] + Glob(asm_path) + Glob(arch_common)
+        else:
+            src += Glob('*.c') + Glob(asm_path) + Glob(arch_common)
         src += Glob('arch/' + arch + '/' + cpu + '/*.c')
         CPPPATH = [cwd]
-        CPPPATH += ['arch/' + arch + '/' + cpu]
+        CPPPATH += [cwd + '/arch/' + arch + '/' + cpu]
 
 group = DefineGroup('lwP', src, depend = ['RT_USING_LWP'], CPPPATH = CPPPATH)
 

+ 68 - 15
components/lwp/lwp.c

@@ -23,7 +23,6 @@
 #endif
 
 #include "lwp.h"
-#include "lwp_arch.h"
 
 #define DBG_TAG "LWP"
 #define DBG_LVL DBG_WARNING
@@ -113,7 +112,18 @@ uint32_t *lwp_get_kernel_sp(void)
 #ifdef RT_USING_USERSPACE
     return (uint32_t *)rt_thread_self()->sp;
 #else
-    return (uint32_t *)rt_thread_self()->kernel_sp;
+    uint32_t* kernel_sp;
+    extern rt_uint32_t rt_interrupt_from_thread;
+    extern rt_uint32_t rt_thread_switch_interrupt_flag;
+    if (rt_thread_switch_interrupt_flag)
+    {
+        kernel_sp = (uint32_t *)((rt_thread_t)rt_container_of(rt_interrupt_from_thread, struct rt_thread, sp))->kernel_sp;
+    }
+    else
+    {
+        kernel_sp = (uint32_t *)rt_thread_self()->kernel_sp;
+    }
+    return kernel_sp;
 #endif
 }
 
@@ -217,13 +227,17 @@ struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **argv, char
 #else
 static struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **argv, char **envp)
 {
+#ifdef ARCH_ARM_MMU
     int size = sizeof(int) * 5; /* store argc, argv, envp, aux, NULL */
+    struct process_aux *aux;
+#else
+    int size = sizeof(int) * 4; /* store argc, argv, envp, NULL */
+#endif /* ARCH_ARM_MMU */
     int *args;
     char *str;
     char **new_argve;
     int i;
     int len;
-    struct process_aux *aux;
 
     for (i = 0; i < argc; i++)
     {
@@ -242,6 +256,7 @@ static struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **arg
         }
     }
 
+#ifdef ARCH_ARM_MMU
     /* for aux */
     size += sizeof(struct process_aux);
 
@@ -253,6 +268,14 @@ static struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **arg
 
     /* argc, argv[], 0, envp[], 0 */
     str = (char *)((size_t)args + (argc + 2 + i + 1 + AUX_ARRAY_ITEMS_NR * 2 + 1) * sizeof(int));
+#else
+    args = (int *)rt_malloc(size);
+    if (args == RT_NULL)
+    {
+        return RT_NULL;
+    }
+    str = (char*)((int)args + (argc + 2 + i + 1) * sizeof(int));
+#endif /* ARCH_ARM_MMU */
 
     new_argve = (char **)&args[1];
     args[0] = argc;
@@ -281,7 +304,7 @@ static struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **arg
         }
         new_argve[i] = 0;
     }
-
+#ifdef ARCH_ARM_MMU
     /* aux */
     aux = (struct process_aux *)(new_argve + i);
     aux->item[0].key = AT_EXECFN;
@@ -292,9 +315,16 @@ static struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **arg
     lwp->args = args;
 
     return aux;
+#else
+    lwp->args = args;
+    lwp->args_length = size;
+
+    return (struct process_aux *)(new_argve + i);
+#endif /* ARCH_ARM_MMU */
 }
 #endif
 
+#ifdef ARCH_ARM_MMU
 #define check_off(voff, vlen)           \
     do                                  \
     {                                   \
@@ -475,9 +505,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
     struct map_range user_area[2] = {{NULL, 0}, {NULL, 0}}; /* 0 is text, 1 is data */
     void *pa, *va;
     void *va_self;
-#endif
 
-#ifdef RT_USING_USERSPACE
     rt_mmu_info *m_info = &lwp->mmu_info;
 #endif
 
@@ -924,6 +952,7 @@ _exit:
     }
     return result;
 }
+#endif /* ARCH_ARM_MMU */
 
 int lwp_load(const char *filename, struct rt_lwp *lwp, uint8_t *load_addr, size_t addr_size, struct process_aux *aux);
 
@@ -994,13 +1023,6 @@ void lwp_cleanup(struct rt_thread *tid)
 
     LOG_I("cleanup thread: %s, stack_addr: %08X", tid->name, tid->stack_addr);
 
-#ifndef RT_USING_USERSPACE
-    if (tid->user_stack != RT_NULL)
-    {
-        rt_free(tid->user_stack);
-    }
-#endif
-
     level = rt_hw_interrupt_disable();
     lwp = (struct rt_lwp *)tid->lwp;
 
@@ -1054,7 +1076,11 @@ static void lwp_thread_entry(void *parameter)
     }
 #endif
 
+#ifdef ARCH_ARM_MMU
     lwp_user_entry(lwp->args, lwp->text_entry, (void *)USER_STACK_VEND, tid->stack_addr + tid->stack_size);
+#else
+    lwp_user_entry(lwp->args, lwp->text_entry, lwp->data_entry, (void *)((uint32_t)lwp->data_entry + lwp->data_size));
+#endif /* ARCH_ARM_MMU */
 }
 
 struct rt_lwp *lwp_self(void)
@@ -1127,24 +1153,37 @@ pid_t lwp_execve(char *filename, int argc, char **argv, char **envp)
     }
 
     result = lwp_load(filename, lwp, RT_NULL, 0, aux);
+#ifdef ARCH_ARM_MMU
     if (result == 1)
     {
         /* dynmaic */
         lwp_unmap_user(lwp, (void *)(USER_VADDR_TOP - ARCH_PAGE_SIZE));
         result = load_ldso(lwp, filename, argv, envp);
     }
+#endif /* ARCH_ARM_MMU */
     if (result == RT_EOK)
     {
         rt_thread_t thread = RT_NULL;
+        rt_uint32_t priority = 25, tick = 200;
 
         lwp_copy_stdio_fdt(lwp);
 
         /* obtain the base name */
         thread_name = strrchr(filename, '/');
         thread_name = thread_name ? thread_name + 1 : filename;
-
+#ifndef ARCH_ARM_MMU
+        struct lwp_app_head *app_head = lwp->text_entry;
+        if (app_head->priority)
+        {
+            priority = app_head->priority;
+        }
+        if (app_head->tick)
+        {
+            tick = app_head->tick;
+        }
+#endif /* not defined ARCH_ARM_MMU */
         thread = rt_thread_create(thread_name, lwp_thread_entry, RT_NULL,
-                LWP_TASK_STACK_SIZE, 25, 200);
+                LWP_TASK_STACK_SIZE, priority, tick);
         if (thread != RT_NULL)
         {
             struct rt_lwp *self_lwp;
@@ -1163,6 +1202,18 @@ pid_t lwp_execve(char *filename, int argc, char **argv, char **envp)
                 lwp->parent = self_lwp;
             }
             thread->lwp = lwp;
+#ifndef ARCH_ARM_MMU
+            struct lwp_app_head *app_head = (struct lwp_app_head*)lwp->text_entry;
+            thread->user_stack = app_head->stack_offset ?
+                              (void *)(app_head->stack_offset -
+                                       app_head->data_offset +
+                                       (uint32_t)lwp->data_entry) : RT_NULL;
+            thread->user_stack_size = app_head->stack_size;
+            /* init data area */
+            rt_memset(lwp->data_entry, 0, lwp->data_size);
+            /* init user stack */
+            rt_memset(thread->user_stack, '#', thread->user_stack_size);
+#endif /* not defined ARCH_ARM_MMU */
             rt_list_insert_after(&lwp->t_grp, &thread->sibling);
 
 #ifdef RT_USING_GDBSERVER
@@ -1201,6 +1252,7 @@ pid_t exec(char *filename, int argc, char **argv)
 }
 #endif
 
+#ifdef ARCH_ARM_MMU
 void lwp_user_setting_save(rt_thread_t thread)
 {
     if (thread)
@@ -1240,3 +1292,4 @@ void lwp_user_setting_restore(rt_thread_t thread)
     }
 #endif
 }
+#endif /* ARCH_ARM_MMU */

+ 12 - 7
components/lwp/lwp.h

@@ -27,16 +27,22 @@
 #include "lwp_ipc.h"
 #include "lwp_signal.h"
 #include "lwp_syscall.h"
+#include "lwp_avl.h"
 
 #ifdef RT_USING_USERSPACE
 #include "lwp_shm.h"
 
 #include "mmu.h"
 #include "page.h"
-#include "lwp_arch.h"
+#else
+#include "lwp_mpu.h"
 #endif
+#include "lwp_arch.h"
 
+#ifdef RT_USING_MUSL
 #include <locale.h>
+typedef int32_t pid_t;
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -49,16 +55,17 @@ extern "C" {
 
 #define LWP_ARG_MAX         8
 
-typedef int32_t pid_t;
-
 struct rt_lwp
 {
 #ifdef RT_USING_USERSPACE
     rt_mmu_info mmu_info;
     struct lwp_avl_struct *map_area;
     size_t end_heap;
+#else
+#ifdef ARCH_MM_MPU
+    struct rt_mpu_info mpu_info;
+#endif /* ARCH_MM_MPU */
 #endif
-
     uint8_t lwp_type;
     uint8_t reserv[3];
 
@@ -74,12 +81,10 @@ struct rt_lwp
     uint32_t text_size;
     void *data_entry;
     uint32_t data_size;
-#ifndef RT_USING_USERSPACE
-    size_t load_off;
-#endif
 
     int ref;
     void *args;
+    uint32_t args_length;
     pid_t pid;
     rt_list_t t_grp;
     struct dfs_fdtable fdt;

+ 18 - 0
components/lwp/lwp_avl.c

@@ -207,3 +207,21 @@ int lwp_avl_traversal(struct lwp_avl_struct *ptree, int (*fun)(struct lwp_avl_st
     }
     return ret;
 }
+
+RT_WEAK struct lwp_avl_struct* lwp_map_find_first(struct lwp_avl_struct* ptree)
+{
+    if (ptree == AVL_EMPTY)
+    {
+        return (struct lwp_avl_struct *)0;
+    }
+    while (1)
+    {
+        if (!ptree->avl_left)
+        {
+            break;
+        }
+        ptree = ptree->avl_left;
+    }
+    return ptree;
+}
+

+ 1 - 0
components/lwp/lwp_avl.h

@@ -37,6 +37,7 @@ void lwp_avl_remove(struct lwp_avl_struct * node_to_delete, struct lwp_avl_struc
 void lwp_avl_insert (struct lwp_avl_struct * new_node, struct lwp_avl_struct ** ptree);
 struct lwp_avl_struct* lwp_avl_find(avl_key_t key, struct lwp_avl_struct* ptree);
 int lwp_avl_traversal(struct lwp_avl_struct* ptree, int (*fun)(struct lwp_avl_struct*, void *), void *arg);
+struct lwp_avl_struct* lwp_map_find_first(struct lwp_avl_struct* ptree);
 
 #ifdef __cplusplus
 }

+ 24 - 10
components/lwp/lwp_pid.c

@@ -360,9 +360,12 @@ void lwp_free(struct rt_lwp* lwp)
     lwp->finish = 1;
     if (lwp->args != RT_NULL)
     {
-#ifndef RT_USING_USERSPACE
+#ifndef ARCH_MM_MMU
+        lwp->args_length = RT_NULL;
+#ifndef ARCH_MM_MPU
         rt_free(lwp->args);
-#endif
+#endif /* not defined ARCH_MM_MPU */
+#endif /* ARCH_ARM_MMU */
         lwp->args = RT_NULL;
     }
 
@@ -380,7 +383,16 @@ void lwp_free(struct rt_lwp* lwp)
     /* free data section */
     if (lwp->data_entry != RT_NULL)
     {
+#ifdef ARCH_ARM_MMU
         rt_free_align(lwp->data_entry);
+#else
+#ifdef ARCH_MM_MPU
+        rt_lwp_umap_user(lwp, lwp->text_entry, 0);
+        rt_lwp_free_user(lwp, lwp->data_entry, lwp->data_size);
+#else
+        rt_free_align(lwp->data_entry);
+#endif /* ARCH_MM_MPU */
+#endif /* ARCH_ARM_MMU */
         lwp->data_entry = RT_NULL;
     }
 
@@ -390,13 +402,9 @@ void lwp_free(struct rt_lwp* lwp)
         if (lwp->text_entry)
         {
             LOG_D("lwp text free: %p", lwp->text_entry);
-#ifndef RT_USING_USERSPACE
-#ifdef RT_USING_CACHE
-            rt_free_align((void*)lwp->load_off);
-#else
-            rt_free((void*)lwp->load_off);
-#endif
-#endif
+#ifndef ARCH_ARM_MMU
+            rt_free((void*)lwp->text_entry);
+#endif /* not defined ARCH_ARM_MMU */
             lwp->text_entry = RT_NULL;
         }
     }
@@ -493,7 +501,13 @@ void lwp_ref_dec(struct rt_lwp *lwp)
                 memset(&msg, 0, sizeof msg);
                 rt_raw_channel_send(gdb_get_server_channel(), &msg);
             }
-#endif
+#endif /* RT_USING_GDBSERVER */
+
+#ifndef ARCH_ARM_MMU
+#ifdef RT_LWP_USING_SHM
+            lwp_shm_lwp_free(lwp);
+#endif /* RT_LWP_USING_SHM */
+#endif /* not defined ARCH_ARM_MMU */
             lwp_free(lwp);
         }
     }

+ 20 - 0
components/lwp/lwp_signal.c

@@ -286,6 +286,13 @@ lwp_sighandler_t lwp_sighandler_get(int sig)
     }
     level = rt_hw_interrupt_disable();
     thread = rt_thread_self();
+#ifndef ARCH_ARM_MMU
+    if (thread->signal_in_process)
+    {
+        func = thread->signal_handler[sig - 1];
+        goto out;
+    }
+#endif
     lwp = (struct rt_lwp*)thread->lwp;
 
     func = lwp->signal_handler[sig - 1];
@@ -324,6 +331,19 @@ void lwp_sighandler_set(int sig, lwp_sighandler_t func)
     rt_hw_interrupt_enable(level);
 }
 
+#ifndef ARCH_ARM_MMU
+void lwp_thread_sighandler_set(int sig, lwp_sighandler_t func)
+{
+    rt_base_t level;
+
+    if (sig == 0 || sig > _LWP_NSIG)
+        return;
+    level = rt_hw_interrupt_disable();
+    rt_thread_self()->signal_handler[sig - 1] = func;
+    rt_hw_interrupt_enable(level);
+}
+#endif
+
 int lwp_sigaction(int sig, const struct lwp_sigaction *act,
              struct lwp_sigaction *oact, size_t sigsetsize)
 {

+ 3 - 0
components/lwp/lwp_signal.h

@@ -22,6 +22,9 @@ int lwp_signal_backup(void *user_sp, void *user_pc, void* user_flag);
 struct rt_user_context *lwp_signal_restore(void);
 lwp_sighandler_t lwp_sighandler_get(int sig);
 void lwp_sighandler_set(int sig, lwp_sighandler_t func);
+#ifndef ARCH_ARM_MMU
+void lwp_thread_sighandler_set(int sig, lwp_sighandler_t func);
+#endif
 int lwp_sigprocmask(int how, const lwp_sigset_t *sigset, lwp_sigset_t *oset);
 int lwp_sigaction(int sig, const struct lwp_sigaction *act, struct lwp_sigaction * oact, size_t sigsetsize);
 int lwp_thread_sigprocmask(int how, const lwp_sigset_t *sigset, lwp_sigset_t *oset);

+ 319 - 48
components/lwp/lwp_syscall.c

@@ -57,8 +57,6 @@
 #include <lwp_console.h>
 #include "lwp_ipc_internal.h"
 
-#define ALLOC_KERNEL_STACK_SIZE 5120
-
 #define SET_ERRNO(no) rt_set_errno(-(no))
 #define GET_ERRNO() ((rt_get_errno() > 0) ? (-rt_get_errno()) : rt_get_errno())
 struct musl_sockaddr
@@ -67,10 +65,17 @@ struct musl_sockaddr
     char     sa_data[14];
 };
 
-extern void lwp_user_thread_entry(void *args, const void *text, void *ustack, void *user_stack);
-
+int sys_dup(int oldfd);
+int sys_dup2(int oldfd, int new);
 void lwp_cleanup(struct rt_thread *tid);
-#ifdef RT_USING_USERSPACE
+
+#ifdef ARCH_ARM_MMU
+#define ALLOC_KERNEL_STACK_SIZE 5120
+
+extern void lwp_user_thread_entry(void *args, const void *text, void *ustack, void *user_stack);
+int sys_futex(int *uaddr, int op, int val, void *timeout, void *uaddr2, int val3);
+int sys_pmutex(void *umutex, int op, void *arg);
+int sys_cacheflush(void *addr, int len, int cache);
 static void *kmem_get(size_t size)
 {
     return rt_malloc(size);
@@ -80,9 +85,14 @@ static void kmem_put(void *kptr)
 {
     rt_free(kptr);
 }
-#endif
+#else
+#define ALLOC_KERNEL_STACK_SIZE 1536
+#define ALLOC_KERNEL_STACK_SIZE_MIN 1024
+#define ALLOC_KERNEL_STACK_SIZE_MAX 4096
 
-int sys_futex(int *uaddr, int op, int val, void *timeout, void *uaddr2, int val3);
+extern void lwp_user_entry(void *args, const void *text, void *data, void *user_stack);
+extern void set_user_context(void *stack);
+#endif /* ARCH_ARM_MMU */
 
 /* The same socket option is defined differently in the user interfaces and the
  * implementation. The options should be converted in the kernel. */
@@ -352,7 +362,12 @@ static void lwp_user_thread(void *parameter)
     user_stack = (rt_size_t)tid->user_stack + tid->user_stack_size;
     user_stack &= ~7; //align 8
 
+#ifdef ARCH_ARM_MMU
     lwp_user_thread_entry(parameter, tid->user_entry, (void *)user_stack, tid->stack_addr + tid->stack_size);
+#else
+    set_user_context((void*)user_stack);
+    lwp_user_entry(parameter, tid->user_entry, ((struct rt_lwp *)tid->lwp)->data_entry, (void*)user_stack);
+#endif /* ARCH_ARM_MMU */
 }
 
 /* thread/process */
@@ -368,6 +383,7 @@ void sys_exit(int value)
     lwp = (struct rt_lwp *)tid->lwp;
 
     level = rt_hw_interrupt_disable();
+#ifdef ARCH_ARM_MMU
     if (tid->clear_child_tid)
     {
         int t = 0;
@@ -384,6 +400,25 @@ void sys_exit(int value)
         lwp_wait_subthread_exit();
         lwp->lwp_ret = value;
     }
+#else
+    main_thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling);
+    if (main_thread == tid)
+    {
+        rt_thread_t sub_thread;
+        rt_list_t *list;
+
+        lwp_terminate(lwp);
+
+        /* delete all subthread */
+        while ((list = tid->sibling.prev) != &lwp->t_grp)
+        {
+            sub_thread = rt_list_entry(list, struct rt_thread, sibling);
+            rt_list_remove(&sub_thread->sibling);
+            rt_thread_delete(sub_thread);
+        }
+        lwp->lwp_ret = value;
+    }
+#endif /* ARCH_ARM_MMU */
 
     rt_thread_delete(tid);
     rt_schedule();
@@ -430,6 +465,10 @@ ssize_t sys_read(int fd, void *buf, size_t nbyte)
     kmem_put(kmem);
     return (ret < 0 ? GET_ERRNO() : ret);
 #else
+    if (!lwp_user_accessable((void *)buf, nbyte))
+    {
+        return -EFAULT;
+    }
     ssize_t ret = read(fd, buf, nbyte);
     return (ret < 0 ? GET_ERRNO() : ret);
 #endif
@@ -464,6 +503,10 @@ ssize_t sys_write(int fd, const void *buf, size_t nbyte)
     kmem_put(kmem);
     return (ret < 0 ? GET_ERRNO() : ret);
 #else
+    if (!lwp_user_accessable((void *)buf, nbyte))
+    {
+        return -EFAULT;
+    }
     ssize_t ret = write(fd, buf, nbyte);
     return (ret < 0 ? GET_ERRNO() : ret);
 #endif
@@ -507,6 +550,10 @@ int sys_open(const char *name, int flag, ...)
     kmem_put(kname);
     return (ret < 0 ? GET_ERRNO() : ret);
 #else
+    if (!lwp_user_accessable((void *)name, 1))
+    {
+        return -EFAULT;
+    }
     int ret = open(name, flag, 0);
     return (ret < 0 ? GET_ERRNO() : ret);
 #endif
@@ -551,6 +598,10 @@ int sys_fstat(int file, struct stat *buf)
         return (ret < 0 ? GET_ERRNO() : ret);
     }
 #else
+    if (!lwp_user_accessable((void *)buf, sizeof(struct stat)))
+    {
+        return -EFAULT;
+    }
     int ret = fstat(file, buf);
     return (ret < 0 ? GET_ERRNO() : ret);
 #endif
@@ -685,11 +736,18 @@ int sys_poll(struct pollfd *fds, nfds_t nfds, int timeout)
     kmem_put(kfds);
     return ret;
 #else
+#ifdef RT_USING_MUSL
     for (i = 0; i < nfds; i++)
     {
         musl2dfs_events(&fds->events);
     }
+#endif /* RT_USING_MUSL */
+    if (!lwp_user_accessable((void *)fds, nfds * sizeof *fds))
+    {
+        return -EFAULT;
+    }
     ret = poll(fds, nfds, timeout);
+#ifdef RT_USING_MUSL
     if (ret > 0)
     {
         for (i = 0; i < nfds; i++)
@@ -697,9 +755,9 @@ int sys_poll(struct pollfd *fds, nfds_t nfds, int timeout)
             dfs2musl_events(&fds->revents);
         }
     }
-
+#endif /* RT_USING_MUSL */
     return ret;
-#endif
+#endif /* RT_USING_USERSPACE */
 }
 
 int sys_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
@@ -783,6 +841,19 @@ quit:
     return (ret < 0 ? GET_ERRNO() : ret);
 #else
     int ret;
+
+    if (!lwp_user_accessable((void *)readfds, sizeof *readfds))
+    {
+        return -EFAULT;
+    }
+    if (!lwp_user_accessable((void *)writefds, sizeof *writefds))
+    {
+        return -EFAULT;
+    }
+    if (!lwp_user_accessable((void *)exceptfds, sizeof *exceptfds))
+    {
+        return -EFAULT;
+    }
     ret = select(nfds, readfds, writefds, exceptfds, timeout);
     return (ret < 0 ? GET_ERRNO() : ret);
 #endif
@@ -863,11 +934,21 @@ int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
 #else
     dbg_log(DBG_LOG, "sys_nanosleep\n");
 
+    if (!lwp_user_accessable((void *)rqtp, sizeof *rqtp))
+    {
+        return -EFAULT;
+    }
+
     tick = rqtp->tv_sec * RT_TICK_PER_SECOND + ((uint64_t)rqtp->tv_nsec * RT_TICK_PER_SECOND) / 1000000000;
     rt_thread_delay(tick);
 
     if (rmtp)
     {
+        if (!lwp_user_accessable((void *)rmtp, sizeof *rmtp))
+        {
+            return -EFAULT;
+        }
+
         tick = rt_tick_get() - tick;
         /* get the passed time */
         rmtp->tv_sec = tick / RT_TICK_PER_SECOND;
@@ -881,9 +962,9 @@ int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
 /* syscall: "gettimeofday" ret: "int" args: "struct timeval *" "struct timezone *" */
 int sys_gettimeofday(struct timeval *tp, struct timezone *tzp)
 {
+#ifdef RT_USING_USERSPACE
     struct timeval t_k;
 
-#ifdef RT_USING_USERSPACE
     if (tp)
     {
         if (!lwp_user_accessable((void *)tp, sizeof *tp))
@@ -899,6 +980,10 @@ int sys_gettimeofday(struct timeval *tp, struct timezone *tzp)
 #else
     if (tp)
     {
+        if (!lwp_user_accessable((void *)tp, sizeof *tp))
+        {
+            return -EFAULT;
+        }
         tp->tv_sec = rt_tick_get() / RT_TICK_PER_SECOND;
         tp->tv_usec = (rt_tick_get() % RT_TICK_PER_SECOND) * (1000000 / RT_TICK_PER_SECOND);
     }
@@ -1076,6 +1161,10 @@ rt_err_t sys_event_recv(rt_event_t   event,
                        rt_int32_t   timeout,
                        rt_uint32_t *recved)
 {
+    if (!lwp_user_accessable((void *)recved, sizeof(rt_uint32_t *)))
+    {
+        return -EFAULT;
+    }
     return rt_event_recv(event, set, opt, timeout, recved);
 }
 
@@ -1109,6 +1198,10 @@ rt_err_t sys_mb_send_wait(rt_mailbox_t mb,
 
 rt_err_t sys_mb_recv(rt_mailbox_t mb, rt_uint32_t *value, rt_int32_t timeout)
 {
+    if (!lwp_user_accessable((void *)value, sizeof(rt_uint32_t *)))
+    {
+        return -EFAULT;
+    }
     return rt_mb_recv(mb, (rt_ubase_t *)value, timeout);
 }
 
@@ -1133,11 +1226,19 @@ rt_err_t sys_mq_delete(rt_mq_t mq)
 
 rt_err_t sys_mq_send(rt_mq_t mq, void *buffer, rt_size_t size)
 {
+    if (!lwp_user_accessable((void *)buffer, size))
+    {
+        return -EFAULT;
+    }
     return rt_mq_send(mq, buffer, size);
 }
 
 rt_err_t sys_mq_urgent(rt_mq_t mq, void *buffer, rt_size_t size)
 {
+    if (!lwp_user_accessable((void *)buffer, size))
+    {
+        return -EFAULT;
+    }
     return rt_mq_urgent(mq, buffer, size);
 }
 
@@ -1146,6 +1247,10 @@ rt_err_t sys_mq_recv(rt_mq_t    mq,
                     rt_size_t  size,
                     rt_int32_t timeout)
 {
+    if (!lwp_user_accessable((void *)buffer, size))
+    {
+        return -EFAULT;
+    }
     return rt_mq_recv(mq, buffer, size, timeout);
 }
 
@@ -1201,9 +1306,6 @@ rt_thread_t sys_thread_create(void *arg[])
     lwp_ref_inc(lwp);
 #ifdef RT_USING_USERSPACE
     user_stack  = lwp_map_user(lwp, 0, (size_t)arg[3], 0);
-#else
-    user_stack  = (void *)RT_KERNEL_MALLOC((uint32_t)arg[3]);
-#endif
     if (!user_stack)
     {
         goto fail;
@@ -1227,6 +1329,41 @@ rt_thread_t sys_thread_create(void *arg[])
     thread->user_entry = (void (*)(void *))arg[1];
     thread->user_stack = (void *)user_stack;
     thread->user_stack_size = (rt_size_t)arg[3];
+#else
+    rt_uint32_t kstack_size = (rt_uint32_t)arg[7];
+    if (kstack_size < ALLOC_KERNEL_STACK_SIZE_MIN)
+    {
+        /* When kstack size is 0, the default size of the kernel stack is used */
+        kstack_size = kstack_size ? ALLOC_KERNEL_STACK_SIZE_MIN : ALLOC_KERNEL_STACK_SIZE;
+    }
+    else if (kstack_size > ALLOC_KERNEL_STACK_SIZE_MAX)
+    {
+        kstack_size = ALLOC_KERNEL_STACK_SIZE_MAX;
+    }
+
+    user_stack  = (void *)arg[3];
+    if ((!user_stack) || ((rt_uint32_t)arg[6] == RT_NULL))
+    {
+        goto fail;
+    }
+
+    if ((tid = lwp_tid_get()) == 0)
+    {
+        goto fail;
+    }
+
+    thread = rt_thread_create((const char *)arg[0], lwp_user_thread, (void *)arg[2], kstack_size, (rt_uint8_t)(size_t)arg[5], (rt_uint32_t)arg[6]);
+    if (!thread)
+    {
+        goto fail;
+    }
+    thread->cleanup = lwp_cleanup;
+    thread->user_entry = (void (*)(void *))arg[1];
+    thread->user_stack = (void *)user_stack;
+    thread->user_stack_size = (uint32_t)arg[4];
+    rt_memset(thread->user_stack, '#', thread->user_stack_size);
+#endif /* RT_USING_USERSPACE */
+
     thread->lwp = (void*)lwp;
     thread->tid = tid;
     lwp_tid_set_thread(tid, thread);
@@ -1239,19 +1376,13 @@ rt_thread_t sys_thread_create(void *arg[])
 
 fail:
     lwp_tid_put(tid);
-#ifndef RT_USING_USERSPACE
-    if (user_stack)
-    {
-        RT_KERNEL_FREE(user_stack);
-    }
-#endif
     if (lwp)
     {
         lwp_ref_dec(lwp);
     }
     return RT_NULL;
 }
-
+#ifdef ARCH_ARM_MMU
 #define CLONE_VM    0x00000100
 #define CLONE_FS    0x00000200
 #define CLONE_FILES 0x00000400
@@ -2205,10 +2336,31 @@ quit:
     }
     return (ret < 0 ? GET_ERRNO() : ret);
 }
+#endif /* ARCH_ARM_MMU */
 
 rt_err_t sys_thread_delete(rt_thread_t thread)
 {
+#ifdef ARCH_ARM_MMU
     return rt_thread_delete(thread);
+#else
+    rt_err_t ret = 0;
+
+    if(thread->type != RT_Object_Class_Thread)
+    {
+        ret = -EINVAL;
+        goto __exit;
+    }
+
+    ret = rt_thread_delete(thread);
+
+    if (rt_thread_self() == thread)
+    {
+        rt_schedule();
+    }
+
+__exit:
+    return ret;
+#endif
 }
 
 rt_err_t sys_thread_startup(rt_thread_t thread)
@@ -2346,6 +2498,34 @@ int sys_shmdt(void* shm_vaddr)
 {
     return lwp_shmdt(shm_vaddr);
 }
+#elif defined RT_LWP_USING_SHM
+void *sys_shm_alloc(int size)
+{
+    if (size < 0)
+    {
+        return RT_NULL;
+    }
+    return lwp_shm_alloc((rt_size_t)size);
+}
+
+void *sys_shm_retain(void *mem)
+{
+    if (!lwp_user_accessable(mem, sizeof (void *)))
+    {
+        return RT_NULL;
+    }
+    return lwp_shm_retain(mem);
+}
+
+int sys_shm_free(void *mem)
+{
+    if (!lwp_user_accessable(mem, sizeof (void *)))
+    {
+        return -EFAULT;
+    }
+    lwp_shm_free(mem);
+    return 0;
+}
 #endif
 
 /* device interfaces */
@@ -2866,6 +3046,7 @@ int sys_sigaction(int sig, const struct k_sigaction *act,
     }
 
     ret = lwp_sigaction(sig, pkact, pkoact, sigsetsize);
+#ifdef ARCH_ARM_MMU
     if (ret == 0 && oact)
     {
         lwp_put_to_user(&oact->handler, &pkoact->__sa_handler._sa_handler, sizeof(void (*)(int)));
@@ -2873,6 +3054,7 @@ int sys_sigaction(int sig, const struct k_sigaction *act,
         lwp_put_to_user(&oact->flags, &pkoact->sa_flags, sizeof(int));
         lwp_put_to_user(&oact->restorer, &pkoact->sa_restorer, sizeof(void (*)(void)));
     }
+#endif /* ARCH_ARM_MMU */
 out:
     return (ret < 0 ? GET_ERRNO() : ret);
 }
@@ -2880,8 +3062,10 @@ out:
 int sys_sigprocmask(int how, const sigset_t *sigset, sigset_t *oset, size_t size)
 {
     int ret = -1;
-    lwp_sigset_t newset, *pnewset = RT_NULL;
-    lwp_sigset_t oldset, *poldset = RT_NULL;
+    lwp_sigset_t *pnewset = RT_NULL, *poldset = RT_NULL;
+#ifdef ARCH_ARM_MMU
+    lwp_sigset_t newset, oldset;
+#endif /* ARCH_ARM_MMU*/
 
     if (!size)
     {
@@ -2897,22 +3081,39 @@ int sys_sigprocmask(int how, const sigset_t *sigset, sigset_t *oset, size_t size
     }
     if (oset)
     {
+#ifdef ARCH_ARM_MMU
         if (!lwp_user_accessable((void *)oset, size))
         {
             return -EFAULT;
         }
         poldset = &oldset;
+#else
+        if (!lwp_user_accessable((void *)oset, size))
+        {
+            return -EFAULT;
+        }
+        poldset = (lwp_sigset_t *)oset;
+#endif
     }
     if (sigset)
     {
+#ifdef ARCH_ARM_MMU
         if (!lwp_user_accessable((void *)sigset, size))
         {
             return -EFAULT;
         }
         lwp_get_from_user(&newset, (void *)sigset, size);
         pnewset = &newset;
+#else
+        if (!lwp_user_accessable((void *)sigset, size))
+        {
+            return -EFAULT;
+        }
+        pnewset = (lwp_sigset_t *)sigset;
+#endif /* ARCH_ARM_MMU */
     }
     ret = lwp_sigprocmask(how, pnewset, poldset);
+#ifdef ARCH_ARM_MMU
     if (ret < 0)
     {
         return ret;
@@ -2921,11 +3122,13 @@ int sys_sigprocmask(int how, const sigset_t *sigset, sigset_t *oset, size_t size
     {
         lwp_put_to_user(oset, poldset, size);
     }
+#endif /* ARCH_ARM_MMU */
     return (ret < 0 ? -EFAULT: ret);
 }
 
 int sys_tkill(int tid, int sig)
 {
+#ifdef ARCH_ARM_MMU
     rt_base_t level;
     rt_thread_t thread;
     int ret;
@@ -2935,13 +3138,18 @@ int sys_tkill(int tid, int sig)
     ret =  lwp_thread_kill(thread, sig);
     rt_hw_interrupt_enable(level);
     return ret;
+#else
+    return lwp_thread_kill((rt_thread_t)tid, sig);
+#endif
 }
 
 int sys_thread_sigprocmask(int how, const lwp_sigset_t *sigset, lwp_sigset_t *oset, size_t size)
 {
     int ret = -1;
-    lwp_sigset_t newset, *pnewset = RT_NULL;
-    lwp_sigset_t oldset, *poldset = RT_NULL;
+    lwp_sigset_t *pnewset = RT_NULL, *poldset = RT_NULL;
+#ifdef ARCH_ARM_MMU
+    lwp_sigset_t newset, oldset;
+#endif /* ARCH_ARM_MMU */
 
     if (!size)
     {
@@ -2957,19 +3165,23 @@ int sys_thread_sigprocmask(int how, const lwp_sigset_t *sigset, lwp_sigset_t *os
     }
     if (oset)
     {
-#ifdef RT_USING_USERSPACE
+#ifdef ARCH_ARM_MMU
         if (!lwp_user_accessable((void *)oset, size))
         {
             return -EFAULT;
         }
         poldset = &oldset;
 #else
+        if (!lwp_user_accessable((void *)oset, size))
+        {
+            return -EFAULT;
+        }
         poldset = oset;
 #endif
     }
     if (sigset)
     {
-#ifdef RT_USING_USERSPACE
+#ifdef ARCH_ARM_MMU
         if (!lwp_user_accessable((void *)sigset, size))
         {
             return -EFAULT;
@@ -2977,7 +3189,11 @@ int sys_thread_sigprocmask(int how, const lwp_sigset_t *sigset, lwp_sigset_t *os
         lwp_get_from_user(&newset, (void *)sigset, sizeof(lwp_sigset_t));
         pnewset = &newset;
 #else
-        pnewset = sigset;
+        if (!lwp_user_accessable((void *)sigset, size))
+        {
+            return -EFAULT;
+        }
+        pnewset = (lwp_sigset_t *)sigset;
 #endif
     }
     ret = lwp_thread_sigprocmask(how, pnewset, poldset);
@@ -2985,7 +3201,7 @@ int sys_thread_sigprocmask(int how, const lwp_sigset_t *sigset, lwp_sigset_t *os
     {
         return ret;
     }
-#ifdef RT_USING_USERSPACE
+#ifdef ARCH_ARM_MMU
     if (oset)
     {
         lwp_put_to_user(oset, poldset, sizeof(lwp_sigset_t));
@@ -2994,6 +3210,30 @@ int sys_thread_sigprocmask(int how, const lwp_sigset_t *sigset, lwp_sigset_t *os
     return (ret < 0 ? -EFAULT: ret);
 }
 
+#ifndef ARCH_ARM_MMU
+int sys_lwp_sighandler_set(int sig, lwp_sighandler_t func)
+{
+    if (!lwp_user_accessable((void *)func, sizeof(lwp_sighandler_t)))
+    {
+        return -EFAULT;
+    }
+
+    lwp_sighandler_set(sig, func);
+    return 0;
+}
+
+int sys_thread_sighandler_set(int sig, lwp_sighandler_t func)
+{
+    if (!lwp_user_accessable((void *)func, sizeof(lwp_sighandler_t)))
+    {
+        return -EFAULT;
+    }
+
+    lwp_thread_sighandler_set(sig, func);
+    return 0;
+}
+#endif /* not defined ARCH_ARM_MMU */
+
 int32_t sys_waitpid(int32_t pid, int *status, int options)
 {
     int ret = -1;
@@ -3001,13 +3241,16 @@ int32_t sys_waitpid(int32_t pid, int *status, int options)
     if (!lwp_user_accessable((void *)status, sizeof(int)))
     {
         return -EFAULT;
-        ret = -1;
     }
     else
     {
         ret = waitpid(pid, status, options);
     }
 #else
+    if (!lwp_user_accessable((void *)status, sizeof(int)))
+    {
+        return -EFAULT;
+    }
     ret = waitpid(pid, status, options);
 #endif
     return ret;
@@ -3259,12 +3502,10 @@ __exit:
 
 char *sys_getcwd(char *buf, size_t size)
 {
-#ifdef RT_USING_USERSPACE
     if (!lwp_user_accessable((void *)buf, size))
     {
         return RT_NULL;
     }
-#endif
     getcwd(buf, size);
 
     return (char *)strlen(buf);
@@ -3324,7 +3565,9 @@ int sys_rmdir(const char *path)
 #endif
 }
 
+#ifdef RT_USING_MUSL
 typedef uint64_t ino_t;
+#endif
 struct libc_dirent {
     ino_t d_ino;
     off_t d_off;
@@ -3381,7 +3624,7 @@ rt_err_t sys_get_errno(void)
 {
     return rt_get_errno();
 }
-
+#ifdef ARCH_ARM_MMU
 int sys_set_thread_area(void *p)
 {
     rt_thread_t thread;
@@ -3407,6 +3650,7 @@ int sys_set_tid_address(int *tidptr)
     thread->clear_child_tid = tidptr;
     return thread->tid;
 }
+#endif /* ARCH_ARM_MMU */
 
 int sys_gettid(void)
 {
@@ -3494,6 +3738,10 @@ int sys_clock_settime(clockid_t clk, const struct timespec *ts)
 
     kmem_put(kts);
 #else
+    if (!lwp_user_accessable((void *)ts, sizeof(struct timespec)))
+    {
+        return -EFAULT;
+    }
     now = ts->tv_sec;
 #endif
     return rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &now);
@@ -3533,6 +3781,10 @@ int sys_clock_gettime(clockid_t clk, struct timespec *ts)
 
     kmem_put(kts);
 #else
+    if (!lwp_user_accessable((void *)ts, sizeof(struct timespec)))
+    {
+        return -EFAULT;
+    }
     ts->tv_sec = now;
     ts->tv_nsec = 0;
 #endif
@@ -3554,18 +3806,16 @@ int sys_clock_getres(clockid_t clk, struct timespec *ts)
     kts.tv_nsec = 0;
     lwp_put_to_user(ts, &kts, size);
 #else
+    if (!lwp_user_accessable((void *)ts, sizeof(struct timespec)))
+    {
+        return -EFAULT;
+    }
     ts->tv_sec = 1;
     ts->tv_nsec = 0;
 #endif
     return 0;
 }
 
-int sys_futex(int *uaddr, int op, int val, void *timeout, void *uaddr2, int val3);
-int sys_pmutex(void *umutex, int op, void *arg);
-
-int sys_dup(int oldfd);
-int sys_dup2(int oldfd, int new);
-
 int sys_rename(const char *oldpath, const char *newpath)
 {
     int ret = -1;
@@ -3647,8 +3897,6 @@ int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
     return -ENOSYS;
 }
 
-int sys_cacheflush(void *addr, int len, int cache);
-
 const static void* func_table[] =
 {
     (void *)sys_exit,            /* 01 */
@@ -3706,12 +3954,24 @@ const static void* func_table[] =
     SYSCALL_USPACE(sys_brk),
     SYSCALL_USPACE(sys_mmap2),
     SYSCALL_USPACE(sys_munmap),
-
+#ifdef ARCH_ARM_MMU
     SYSCALL_USPACE(sys_shmget), /* 55 */
     SYSCALL_USPACE(sys_shmrm),
     SYSCALL_USPACE(sys_shmat),
     SYSCALL_USPACE(sys_shmdt),
-
+#else
+#ifdef RT_LWP_USING_SHM
+    (void *)sys_shm_alloc,      /* 55 */
+    (void *)sys_shm_free,
+    (void *)sys_shm_retain,
+    (void *)sys_notimpl,
+#else
+    (void *)sys_notimpl,      /* 55 */
+    (void *)sys_notimpl,
+    (void *)sys_notimpl,
+    (void *)sys_notimpl,
+#endif /* RT_LWP_USING_SHM */
+#endif /* ARCH_ARM_MMU */
     (void *)sys_device_init,
     (void *)sys_device_register, /* 60 */
     (void *)sys_device_control,
@@ -3772,9 +4032,15 @@ const static void* func_table[] =
     (void *)sys_sigprocmask,
     (void *)sys_tkill,             /* 105 */
     (void *)sys_thread_sigprocmask,
+#ifdef ARCH_ARM_MMU
     (void *)sys_cacheflush,
     (void *)sys_notimpl,
     (void *)sys_notimpl,
+#else
+    (void *)sys_notimpl,
+    (void *)sys_lwp_sighandler_set,
+    (void *)sys_thread_sighandler_set,
+#endif
     (void *)sys_waitpid,          /* 110 */
 
     (void *)sys_timer_create,
@@ -3789,22 +4055,27 @@ const static void* func_table[] =
     (void *)sys_rmdir,          /* 120 */
     (void *)sys_getdents,
     (void *)sys_get_errno,
+#ifdef ARCH_ARM_MMU
     (void *)sys_set_thread_area,
     (void *)sys_set_tid_address,
+#else
+    (void *)sys_notimpl,
+    (void *)sys_notimpl,
+#endif
     (void *)sys_access,         /* 125 */
     (void *)sys_pipe,
     (void *)sys_clock_settime,
     (void *)sys_clock_gettime,
     (void *)sys_clock_getres,
-    (void *)sys_clone,           /* 130 */
-    (void *)sys_futex,
-    (void *)sys_pmutex,
+    SYSCALL_USPACE(sys_clone),           /* 130 */
+    SYSCALL_USPACE(sys_futex),
+    SYSCALL_USPACE(sys_pmutex),
     (void *)sys_dup,
     (void *)sys_dup2,
     (void *)sys_rename,         /* 135 */
-    (void *)sys_fork,
-    (void *)sys_execve,
-    (void *)sys_vfork,
+    SYSCALL_USPACE(sys_fork),
+    SYSCALL_USPACE(sys_execve),
+    SYSCALL_USPACE(sys_vfork),
     (void *)sys_gettid,
     (void *)sys_prlimit64,      /* 140 */
     (void *)sys_getrlimit,

+ 3 - 0
include/rtdef.h

@@ -737,6 +737,9 @@ struct rt_thread
     lwp_sigset_t signal_mask;
     int signal_mask_bak;
     rt_uint32_t signal_in_process;
+#ifndef ARCH_ARM_MMU
+    lwp_sighandler_t signal_handler[32];
+#endif
     struct rt_user_context user_ctx;
 
     struct rt_wakeup wakeup;                            /**< wakeup data */

+ 4 - 0
libcpu/Kconfig

@@ -36,6 +36,10 @@ config ARCH_ARM_MPU
     bool
     depends on ARCH_ARM
 
+config ARCH_MM_MPU
+    bool
+    depends on ARCH_ARM_MPU
+
 config ARCH_ARM_CORTEX_M4
     bool
     select ARCH_ARM_CORTEX_M

+ 1 - 2
src/mem.c

@@ -632,10 +632,9 @@ void rt_memory_info(rt_uint32_t *total,
 
 #ifdef RT_USING_LWP
 #include <lwp.h>
-#else
+#endif
 #ifndef ARCH_PAGE_SIZE
 #define ARCH_PAGE_SIZE  0
-#endif
 
 #endif
 

+ 17 - 0
src/scheduler.c

@@ -33,6 +33,10 @@
 #include <rtthread.h>
 #include <rthw.h>
 
+#ifdef RT_USING_LWP
+#include <lwp.h>
+#endif /* RT_USING_LWP */
+
 rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];
 rt_uint32_t rt_thread_ready_priority_group;
 #if RT_THREAD_PRIORITY_MAX > 32
@@ -82,6 +86,19 @@ static void _rt_scheduler_stack_check(struct rt_thread *thread)
 {
     RT_ASSERT(thread != RT_NULL);
 
+#ifdef RT_USING_LWP
+#ifndef ARCH_ARM_MMU
+    struct rt_lwp *lwp = thread ? (struct rt_lwp *)thread->lwp : 0;
+
+    /* if stack pointer locate in user data section skip stack check. */
+    if (lwp && ((rt_uint32_t)thread->sp > (rt_uint32_t)lwp->data_entry &&
+    (rt_uint32_t)thread->sp <= (rt_uint32_t)lwp->data_entry + (rt_uint32_t)lwp->data_size))
+    {
+        return;
+    }
+#endif /* not defined ARCH_ARM_MMU */
+#endif /* RT_USING_LWP */
+
 #if defined(ARCH_CPU_STACK_GROWS_UPWARD)
     if (*((rt_uint8_t *)((rt_ubase_t)thread->stack_addr + thread->stack_size - 1)) != '#' ||
 #else