9
0
Fork 0

Rework of kernel build signal dispatch to user-space handlers

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5778 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2013-03-23 14:46:02 +00:00
parent f4a74d79f3
commit a8cb02138c
24 changed files with 412 additions and 242 deletions

View File

@ -4428,3 +4428,10 @@
2013-03-22).
* configs/stm32f4discovery/kostest: Add a kernel mode version
of the OS test for the STM32F4Discovery board (2013-03-22).
* nuttx/include/nuttx, nuttx/configs/sam3u-ek, nuttx/configs/open1788,
nuttx/configs/stm32f4discovery, and nuttx/arch/arm: Complete
re-archtecting of how signals are dispatched to user-space code
in the kernel build. The original implementation was C-based
and simpler. However, the C code intermixed with SVC calls was
not properly preserving registers. The more complex, assembly
language version does not suffer from these issues (2013-03-23).

View File

@ -190,7 +190,7 @@ endif
# USERLIBS is the list of libraries used to build the final user-space
# application
NUTTXLIBS = lib/libsched$(LIBEXT) lib/libarch$(LIBEXT)
NUTTXLIBS = lib/libsched$(LIBEXT)
USERLIBS =
# Add libraries for syscall support. The C library will be needed by
@ -199,9 +199,11 @@ USERLIBS =
ifeq ($(CONFIG_NUTTX_KERNEL),y)
NUTTXLIBS += lib/libstubs$(LIBEXT) lib/libkc$(LIBEXT) lib/libkmm$(LIBEXT)
USERLIBS += lib/libproxies$(LIBEXT) lib/libuc$(LIBEXT) lib/libumm$(LIBEXT)
NUTTXLIBS += lib/libkarch$(LIBEXT)
USERLIBS += lib/libproxies$(LIBEXT) lib/libuc$(LIBEXT) lib/libumm$(LIBEXT)
USERLIBS += lib/libuarch$(LIBEXT)
else
NUTTXLIBS += lib/libc$(LIBEXT) lib/libmm$(LIBEXT)
NUTTXLIBS += lib/libc$(LIBEXT) lib/libmm$(LIBEXT) lib/libarch$(LIBEXT)
endif
# Add libraries for C++ support. CXX, CXXFLAGS, and COMPILEXX must
@ -463,18 +465,19 @@ mm/libkmm$(LIBEXT): context
lib/libkmm$(LIBEXT): mm/libkmm$(LIBEXT)
$(Q) install mm/libkmm$(LIBEXT) lib/libkmm$(LIBEXT)
$(ARCH_SRC)/libkarch$(LIBEXT): context
$(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" libkarch$(LIBEXT) EXTRADEFINES=$(KDEFINE)
lib/libkarch$(LIBEXT): $(ARCH_SRC)/libkarch$(LIBEXT)
$(Q) install $(ARCH_SRC)/libkarch$(LIBEXT) lib/libkarch$(LIBEXT)
sched/libsched$(LIBEXT): context
$(Q) $(MAKE) -C sched TOPDIR="$(TOPDIR)" libsched$(LIBEXT) EXTRADEFINES=$(KDEFINE)
lib/libsched$(LIBEXT): sched/libsched$(LIBEXT)
$(Q) install sched/libsched$(LIBEXT) lib/libsched$(LIBEXT)
$(ARCH_SRC)/libarch$(LIBEXT): context
$(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" libarch$(LIBEXT) EXTRADEFINES=$(KDEFINE)
lib/libarch$(LIBEXT): $(ARCH_SRC)/libarch$(LIBEXT)
$(Q) install $(ARCH_SRC)/libarch$(LIBEXT) lib/libarch$(LIBEXT)
net/libnet$(LIBEXT): context
$(Q) $(MAKE) -C net TOPDIR="$(TOPDIR)" libnet$(LIBEXT) EXTRADEFINES=$(KDEFINE)
@ -525,6 +528,13 @@ mm/libumm$(LIBEXT): context
lib/libumm$(LIBEXT): mm/libumm$(LIBEXT)
$(Q) install mm/libumm$(LIBEXT) lib/libumm$(LIBEXT)
$(ARCH_SRC)/libuarch$(LIBEXT): context
$(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" libuarch$(LIBEXT)
lib/libuarch$(LIBEXT): $(ARCH_SRC)/libuarch$(LIBEXT)
$(Q) install $(ARCH_SRC)/libuarch$(LIBEXT) lib/libuarch$(LIBEXT)
libxx/libcxx$(LIBEXT): context
$(Q) $(MAKE) -C libxx TOPDIR="$(TOPDIR)" libcxx$(LIBEXT)
@ -557,6 +567,12 @@ mm/libmm$(LIBEXT): context
lib/libmm$(LIBEXT): mm/libmm$(LIBEXT)
$(Q) install mm/libmm$(LIBEXT) lib/libmm$(LIBEXT)
$(ARCH_SRC)/libarch$(LIBEXT): context
$(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" libarch$(LIBEXT)
lib/libarch$(LIBEXT): $(ARCH_SRC)/libarch$(LIBEXT)
$(Q) install $(ARCH_SRC)/libarch$(LIBEXT) lib/libarch$(LIBEXT)
# pass1 and pass2
#
# If the 2 pass build option is selected, then this pass1 target is

View File

@ -183,7 +183,7 @@ endif
# USERLIBS is the list of libraries used to build the final user-space
# application
NUTTXLIBS = lib\libsched$(LIBEXT) lib\libarch$(LIBEXT)
NUTTXLIBS = lib\libsched$(LIBEXT)
USERLIBS =
# Add libraries for syscall support. The C library will be needed by
@ -192,9 +192,11 @@ USERLIBS =
ifeq ($(CONFIG_NUTTX_KERNEL),y)
NUTTXLIBS += lib\libstubs$(LIBEXT) lib\libkc$(LIBEXT) lib\libkmm$(LIBEXT)
USERLIBS += lib\libproxies$(LIBEXT) lib\libuc$(LIBEXT) lib\libumm$(LIBEXT)
NUTTXLIBS += lib\libkarch$(LIBEXT)
USERLIBS += lib\libproxies$(LIBEXT) lib\libuc$(LIBEXT) lib\libumm$(LIBEXT)
USERLIBS += lib\libuarch$(LIBEXT)
else
NUTTXLIBS += lib\libc$(LIBEXT) lib\libmm$(LIBEXT)
NUTTXLIBS += lib\libc$(LIBEXT) lib\libmm$(LIBEXT) lib\libarch$(LIBEXT)
endif
# Add libraries for C++ support. CXX, CXXFLAGS, and COMPILEXX must
@ -479,18 +481,19 @@ mm\libkmm$(LIBEXT): context
lib\libkmm$(LIBEXT): mm\libkmm$(LIBEXT)
$(Q) install mm\libkmm$(LIBEXT) lib\libkmm$(LIBEXT)
$(ARCH_SRC)\libkarch$(LIBEXT): context
$(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" libkarch$(LIBEXT) EXTRADEFINES=$(KDEFINE)
lib\libkarch$(LIBEXT): $(ARCH_SRC)\libkarch$(LIBEXT)
$(Q) install $(ARCH_SRC)\libkarch$(LIBEXT) lib\libkarch$(LIBEXT)
sched\libsched$(LIBEXT): context
$(Q) $(MAKE) -C sched TOPDIR="$(TOPDIR)" libsched$(LIBEXT) EXTRADEFINES=$(KDEFINE)
lib\libsched$(LIBEXT): sched\libsched$(LIBEXT)
$(Q) install sched\libsched$(LIBEXT) lib\libsched$(LIBEXT)
$(ARCH_SRC)\libarch$(LIBEXT): context
$(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" libarch$(LIBEXT) EXTRADEFINES=$(KDEFINE)
lib\libarch$(LIBEXT): $(ARCH_SRC)\libarch$(LIBEXT)
$(Q) install $(ARCH_SRC)\libarch$(LIBEXT) lib\libarch$(LIBEXT)
net\libnet$(LIBEXT): context
$(Q) $(MAKE) -C net TOPDIR="$(TOPDIR)" libnet$(LIBEXT) EXTRADEFINES=$(KDEFINE)
@ -541,6 +544,13 @@ mm\libumm$(LIBEXT): context
lib\libumm$(LIBEXT): mm\libumm$(LIBEXT)
$(Q) install mm\libumm$(LIBEXT) lib\libumm$(LIBEXT)
$(ARCH_SRC)\libuarch$(LIBEXT): context
$(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" libuarch$(LIBEXT)
lib\libuarch$(LIBEXT): $(ARCH_SRC)\libuarch$(LIBEXT)
$(Q) install $(ARCH_SRC)\libuarch$(LIBEXT) lib\libuarch$(LIBEXT)
libxx\libcxx$(LIBEXT): context
$(Q) $(MAKE) -C libxx TOPDIR="$(TOPDIR)" libcxx$(LIBEXT)
@ -573,6 +583,12 @@ mm\libmm$(LIBEXT): context
lib\libmm$(LIBEXT): mm\libmm$(LIBEXT)
$(Q) install mm\libmm$(LIBEXT) lib\libmm$(LIBEXT)
$(ARCH_SRC)\libarch$(LIBEXT): context
$(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" libarch$(LIBEXT)
lib\libarch$(LIBEXT): $(ARCH_SRC)\libarch$(LIBEXT)
$(Q) install $(ARCH_SRC)\libarch$(LIBEXT) lib\libarch$(LIBEXT)
# pass1 and pass2
#
# If the 2 pass build option is selected, then this pass1 target is

View File

@ -7,9 +7,10 @@ standards, things that could be improved, and ideas for enhancements.
nuttx/
(10) Task/Scheduler (sched/)
(2) Memory Managment (mm/)
(4) Signals (sched/, arch/)
(1) Memory Managment (mm/)
(3) Signals (sched/, arch/)
(2) pthreads (sched/)
(5) Kernel Build
(2) C++ Support
(6) Binary loaders (binfmt/)
(16) Network (net/, drivers/net)
@ -19,7 +20,7 @@ nuttx/
(5) Graphics subystem (graphics/)
(1) Pascal add-on (pcode/)
(1) Documentation (Documentation/)
(7) Build system / Toolchains
(6) Build system / Toolchains
(5) Linux/Cywgin simulation (arch/sim)
(4) ARM (arch/arm/)
(1) ARM/C5471 (arch/arm/src/c5471/)
@ -253,44 +254,6 @@ o Memory Managment (mm/)
Priority: Medium/Low, a good feature to prevent memory leaks but would
have negative impact on memory usage and code size.
Title: MEMORY MANAGEMENT IN THE KERNEL BUILD
Description: At present, there are two options for memory management in
the NuttX kernel build:
1) Have only a single user-space heap and heap allocator that
is shared by both kernel- and user-modes. PROs: Simple,
CONs: Awkward architecture and no security for kernel-mode
allocations.
2) Two separate heap partitions and two copies of the memory
allocators. One heap partition is protected and the the
is user accessible. PROs: Still simple, CONs: Partitioning
the heap will not make the best use of heap memory.
A complication is that the kernel needs to allocate both
protected, kernel private as well as user accessible memory
(such as for stacks). A more traditional approarch would be
something like:
3) Implement sbrk(). The would still be kernel- and user-mode
instances of the memory allocators. Each would sbrk() as
necessary to extend their heap; the pages allocated for
the kernel-mode allocator would be protected but the pages
allocated for the user-mode allocator would not. PROs:
Meets all of the needs. CONs: Complex. Memory losses,
due to quanitization. sbrk'ed memory would not be
contiguous; this would limit the sizes of allocations
due to the physical pages.
This feels like overkill for this class of processor.
This approach probably could not be implemented using
a simple memory protection unit (such as that of the
ARM Cortex-M family).
See other kernel build issues under "Build system"
Status: Open
Priority: Low, unless you need a working kernel build now.
o Signals (sched/, arch/)
^^^^^^^^^^^^^^^^^^^^^^^
@ -319,14 +282,6 @@ o Signals (sched/, arch/)
Status: Open
Priority: Low. Even if there are only 31 usable signals, that is still a lot.
Title: USER-MODE SIGNALS
Description: In a kernel build (CONFIG_NUTTX_KERNEL). Signal handlers should
execute in user mode. This is to prevent a security hole where
user code can get control of the system in kernel mode if the signal
executes in kernel mode.
Status: Open
Priority: Low
o pthreads (sched/)
^^^^^^^^^^^^^^^^^
@ -394,6 +349,82 @@ o pthreads (sched/)
solution. So I discarded a few hours of programming. Not a
big loss from the experience I gained."
o Kernel Build
^^^^^^^^^^^^
Title: KERNEL BUILD MODE ISSUES - GRAPHICS/NSH PARTITIONING.
Description: In the kernel build mode (where NuttX is built as a monlithic
kernel and user code must trap into the protected kernel via
syscalls), the single user mode cannot be supported. In this
built configuration, only the multiple user mode can be supported
with the NX server residing inside of the kernel space. In
this case, most of the user end functions in graphics/nxmu
must be moved to libc/nx and those functions must be built into
libuser.a to be linked with the user-space code.
A similar issue exists in NSH that uses some internal OS
interfaces that would not be available in a kernel build
(such as foreach_task, foreach_mountpoint, etc.).
See also "Memory Management" for another kernel build issue.
Status: Open
Priority: Low -- the kernel build configuration is not fully fielded
yet.
Title: NSH ps AND mount COMMANDS DISABLED
Description: NSH's ps and mount command (with not arguments) cannot currently
be supported in the kernel build. That is because these commands
depend on kernel internal, non-standard interfaces that are not
accessible in user-space. These are both critical NSH commands
and need to be supported.
Status: Open
Priority: High. I really like these commands!
Title: LOAD-ABLE MODULE SUPPORT UNVERIFIED
Description: It has not been verified if NXFLAT and ELF modules work correctly
in the kernel build. They should load into user-space memory.
Status: Open
Priority: Medium. There is no configuration that uses NXFLAT or ELF with
a kernel build now.
Title: C++ CONSTRUCTORS HAVE TOO MANY PRIVILEGES
Description: When a C++ ELF module is loaded, its C++ constructors are called
via sched/task_starthook.c logic. This logic runs in kernel mode.
The is a security hole because the user code runs with kernel-
priviledges when the constuctor executes.
Destructors likely have the opposite problem. The probably try to
execute some kernel logic in user mode? Obviously this needs to
be investigated further.
Status: Open
Priority: Low (unless you need build a secure C++ system).
Title: TOO MANY SYSCALLS
Description: There are a few syscalls that operate very often in user space.
Since syscalls are (relatively) time consuming this could be
a performance issue. Here is some numbers that I collected
in an application that was doing mostly printf outout:
sem_post - 18% of syscalls
sem_wait - 18% of syscalls
getpid - 59% of syscalls
--------------------------
95% of syscalls
Obviously system performance could be improved greatly by simply
optimizing these functions so that they do not need to system calls
so frequently. getpid() is (I believe) part of the re-entrant
semaphore logic. Something like TLS might be used to retain the
thread's ID locally.
Linux, for example, has functions call up() and down(). up()
increments the semaphore count but does not call into the kernel
unless incrementing the count unblocks a task; similarly, down
decrements the count and does not call into the the kernel unless
the count becomes negative the caller must be blocked.
Status: Open
Priority: Low-Medium. Right now, I do not know if these syscalls are a
real performance issue or not.
o C++ Support
^^^^^^^^^^^
@ -1088,24 +1119,6 @@ o Build system
Status: Open
Priority: Low.
Title: KERNEL BUILD MODE ISSUES - GRAPHICS/NSH PARTITIONING.
Description: In the kernel build mode (where NuttX is built as a monlithic
kernel and user code must trap into the protected kernel via
syscalls), the single user mode cannot be supported. In this
built configuration, only the multiple user mode can be supported
with the NX server residing inside of the kernel space. In
this case, most of the user end functions in graphics/nxmu
must be moved to libc/nx and those functions must be built into
libuser.a to be linked with the user-space code.
A similar issue exists in NSH that uses some internal OS
interfaces that would not be available in a kernel build
(such as foreach_task, foreach_mountpoint, etc.).
See also "Memory Management" for another kernel build issue.
Status: Open
Priority: Low -- the kernel build configuration is not fully fielded
yet.
Title: kconfig-mconf NOT AVAILABLE IN NATIVE WINDOWS BUILD
Description: NuttX is migrating to the use of the kconfig-frontends kconfig-mconf
tool for all configurations. In NuttX 6.24, support for native

View File

@ -241,25 +241,6 @@ static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
return reg0;
}
/* This inline function is used by user-space code in order to return from
* a signal handler.
*/
#if defined(CONFIG_NUTTX_KERNEL) && !defined(__KERNEL__)
static inline void signal_handler_return(void) noreturn_function;
static inline void signal_handler_return(void)
{
__asm__ __volatile__
(
" mov r0, %0\n"
" svc %1\n"
:
: "i" (SYS_signal_handler_return), "i"(SYS_syscall)
: "memory"
);
}
#endif
/****************************************************************************
* Public Variables
****************************************************************************/

View File

@ -241,25 +241,6 @@ static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
return reg0;
}
/* This inline function is used by user-space code in order to return from
* a signal handler.
*/
#if defined(CONFIG_NUTTX_KERNEL) && !defined(__KERNEL__)
static inline void signal_handler_return(void) noreturn_function;
static inline void signal_handler_return(void)
{
__asm__ __volatile__
(
" mov r0, %0\n"
" svc %1\n"
:
: "i" (SYS_signal_handler_return), "i"(SYS_syscall)
: "memory"
);
}
#endif
/****************************************************************************
* Public Variables
****************************************************************************/

View File

@ -74,8 +74,12 @@ else
endif
endif
# The "head" object
HEAD_OBJ = $(HEAD_ASRC:.S=$(OBJEXT))
# Flat build or kernel-mode objects
ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS)
AOBJS = $(ASRCS:.S=$(OBJEXT))
@ -85,6 +89,21 @@ COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS)
OBJS = $(AOBJS) $(COBJS)
# User-mode objects
UASRCS = $(CHIP_UASRCS) $(CMN_UASRCS)
UAOBJS = $(UASRCS:.S=$(OBJEXT))
UCSRCS = $(CHIP_UCSRCS) $(CMN_UCSRCS)
UCOBJS = $(UCSRCS:.c=$(OBJEXT))
USRCS = $(UASRCS) $(UCSRCS)
UOBJS = $(UAOBJS) $(UCOBJS)
KBIN = libkarch$(LIBEXT)
UBIN = libuarch$(LIBEXT)
BIN = libarch$(LIBEXT)
LDFLAGS += $(ARCHSCRIPT)
EXTRA_LIBS ?=
@ -125,19 +144,22 @@ GCC_LIBDIR := ${shell dirname $(LIBGCC)}
VPATH = chip:common:$(ARCH_SUBDIR)
all: $(HEAD_OBJ) libarch$(LIBEXT)
all: $(HEAD_OBJ) $(BIN)
.PHONY: board/libboard$(LIBEXT)
$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %.S
$(AOBJS) $(UAOBJS) $(HEAD_OBJ): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
$(COBJS): %$(OBJEXT): %.c
$(COBJS) $(UCOBJS): %$(OBJEXT): %.c
$(call COMPILE, $<, $@)
libarch$(LIBEXT): $(OBJS)
$(BIN): $(OBJS)
$(call ARCHIVE, $@, $(OBJS))
$(UBIN): $(UOBJS)
$(call ARCHIVE, $@, $(UOBJS))
board/libboard$(LIBEXT):
$(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES)
@ -182,7 +204,9 @@ clean:
ifeq ($(BOARDMAKE),y)
$(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" clean
endif
$(call DELFILE, libarch$(LIBEXT))
$(call DELFILE, $(KBIN))
$(call DELFILE, $(UBIN))
$(call DELFILE, $(BIN))
$(call CLEAN)
distclean: clean

View File

@ -1,5 +1,5 @@
/****************************************************************************
* libc/signal/signal_handler.c
* arch/arm/srcm/armv6-m/up_signal_handler.S
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@ -39,33 +39,16 @@
#include <nuttx/config.h>
#include <signal.h>
#include <assert.h>
#include <arch/syscall.h>
#include <nuttx/userspace.h>
#if defined(CONFIG_NUTTX_KERNEL) && !defined(__KERNEL__)
/****************************************************************************
* Pre-processor Definitions
* File info
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Global Variables
****************************************************************************/
/****************************************************************************
* Private Variables
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
.cpu cortex-m0
.file "up_signal_handler.S"
/****************************************************************************
* Private Functions
@ -76,35 +59,57 @@
****************************************************************************/
/****************************************************************************
* Name: signal_handler
* Name: up_signal_handler
*
* Description:
* This function is the user-space, signal handler trampoline function. It
* is called from up_signal_handler() in user-mode.
* is called from up_signal_dispatch() in user-mode.
*
* Inputs:
* sighand - The address user-space signal handling function
* signo, info, and ucontext - Standard arguments to be passed to the
* signal handling function.
* R0 = sighand
* The address user-space signal handling function
* R1-R3 = signo, info, and ucontext
* Standard arguments to be passed to the signal handling function.
*
* Return:
* None. This function does not return in the normal sense. It returns
* via signal_handler_return (see include/nuttx/arch.h)
* via the SYS_signal_handler_return (see svcall.h)
*
****************************************************************************/
void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info,
FAR void *ucontext)
{
DEBUGASSERT(sighand);
.text
.align 2
.code 16
.thumb_func
.globl up_signal_handler
.type up_signal_handler, function
up_signal_handler:
/* Execute the signal handler. */
/* Save some register */
sighand(signo, info, ucontext);
push {r4, r5 /* Save R4 and R5 on the stack */
mov r5, lr /* Save LR in R5 */
/* And return from the signal handler */
/* Call the signal handler */
signal_handler_return();
}
mov r4, r0 /* R4=sighand */
mov r0, r1 /* R0=signo */
mov r1, r2 /* R1=info */
mov r2, r3 /* R2=ucontext */
blx r4 /* Call the signal handler */
/* Restore the registers */
mov lr, r5 /* Restore LR */
pop {r4, r5} /* Restore R4 and R5 */
/* Execute the SYS_signal_handler_return SVCall (will not return) */
mov r0, #SYS_signal_handler_return
svc 0
nop
.size up_signal_handler, .-up_signal_handler
.end
#endif /* CONFIG_NUTTX_KERNEL && !__KERNEL__ */

View File

@ -101,4 +101,3 @@ up_saveusercontext:
* context switch with r0=1 */
.size up_saveusercontext, .-up_saveusercontext
.end

View File

@ -0,0 +1,118 @@
/****************************************************************************
* arch/arm/srcm/armv7-m/up_signal_handler.S
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/syscall.h>
#if defined(CONFIG_NUTTX_KERNEL) && !defined(__KERNEL__)
/****************************************************************************
* File info
****************************************************************************/
.syntax unified
.thumb
.cpu cortex-m3
.file "up_signal_handler.S"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_signal_handler
*
* Description:
* This function is the user-space, signal handler trampoline function. It
* is called from up_signal_dispatch() in user-mode.
*
* R0-R3, R11 - volatile registers need not be preserved.
* R4-R10 - static registers must be preserved
* R12-R14 - LR and SP must be preserved
*
* Inputs:
* R0 = sighand
* The address user-space signal handling function
* R1-R3 = signo, info, and ucontext
* Standard arguments to be passed to the signal handling function.
*
* Return:
* None. This function does not return in the normal sense. It returns
* via the SYS_signal_handler_return (see svcall.h)
*
****************************************************************************/
.text
.thumb_func
.globl up_signal_handler
.type up_signal_handler, function
up_signal_handler:
/* Save some register */
push {lr} /* Save LR on the stack */
/* Call the signal handler */
mov ip, r0 /* IP=sighand */
mov r0, r1 /* R0=signo */
mov r1, r2 /* R1=info */
mov r2, r3 /* R2=ucontext */
blx ip /* Call the signal handler */
/* Restore the registers */
pop {r2} /* Recover LR in R2 */
mov lr, r2 /* Restore LR */
/* Execute the SYS_signal_handler_return SVCall (will not return) */
mov r0, #SYS_signal_handler_return
svc 0
nop
.size up_signal_handler, .-up_signal_handler
.end
#endif /* CONFIG_NUTTX_KERNEL && !__KERNEL__ */

View File

@ -1,5 +1,5 @@
/****************************************************************************
* arch/arm/src/common/up_task_start.c
* arch/arm/src/common/up_signal_dispatch.c
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@ -62,7 +62,7 @@
****************************************************************************/
/****************************************************************************
* Name: up_signal_handler
* Name: up_signal_dispatch
*
* Description:
* In this kernel mode build, this function will be called to execute a
@ -73,9 +73,9 @@
*
* Normally the a user-mode signalling handling stub will also execute
* before the ultimate signal handler is called. See
* libc/signal/signal_handler.c This function is the user-space, signal
* handler trampoline function. It is called from up_signal_handler() in
* user-mode.
* arch/arm/src/armv[6\7]/up_signal_handler. This function is the
* user-space, signal handler trampoline function. It is called from
* up_signal_dispatch() in user-mode.
*
* Inputs:
* sighand - The address user-space signal handling function
@ -84,12 +84,14 @@
*
* Return:
* None. This function does not return in the normal sense. It returns
* via signal_handler_return (below)
* via an architecture specific system call made by up_signal_handler().
* However, this will look like a normal return by the caller of
* up_signal_dispatch.
*
****************************************************************************/
void up_signal_handler(_sa_sigaction_t sighand, int signo,
FAR siginfo_t *info, FAR void *ucontext)
void up_signal_dispatch(_sa_sigaction_t sighand, int signo,
FAR siginfo_t *info, FAR void *ucontext)
{
/* Let sys_call4() do all of the work */

View File

@ -43,6 +43,9 @@ endif
# Common ARM and Cortex-M3 files
CMN_UASRCS =
CMN_UCSRCS =
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
CMN_ASRCS += vfork.S
@ -70,7 +73,8 @@ endif
ifeq ($(CONFIG_NUTTX_KERNEL),y)
CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c up_stackframe.c
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
CMN_CSRCS += up_signal_handler.c
CMN_CSRCS += up_signal_dispatch.c
CMN_UASRCS += up_signal_handler.S
endif
endif

View File

@ -39,6 +39,9 @@ HEAD_ASRC = sam3u_vectors.S
# Common ARM and Cortex-M3 files
CMN_UASRCS =
CMN_UCSRCS =
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
CMN_ASRCS += vfork.S
CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c up_createstack.c
@ -62,7 +65,8 @@ endif
ifeq ($(CONFIG_NUTTX_KERNEL),y)
CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c up_stackframe.c
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
CMN_CSRCS += up_signal_handler.c
CMN_CSRCS += up_signal_dispatch.c
CMN_UASRCS += up_signal_handler.S
endif
endif

View File

@ -39,6 +39,9 @@ else
HEAD_ASRC = stm32_vectors.S
endif
CMN_UASRCS =
CMN_UCSRCS =
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
CMN_ASRCS += vfork.S
@ -67,7 +70,8 @@ endif
ifeq ($(CONFIG_NUTTX_KERNEL),y)
CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c up_stackframe.c
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
CMN_CSRCS += up_signal_handler.c
CMN_CSRCS += up_signal_dispatch.c
CMN_UASRCS += up_signal_handler.S
endif
endif

View File

@ -111,7 +111,7 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) =
/* Signal handler trampoline */
#ifndef CONFIG_DISABLE_SIGNALS
.signal_handler = signal_handler,
.signal_handler = up_signal_handler,
#endif
/* Memory manager entry points (declared in include/nuttx/mm.h) */

View File

@ -51,10 +51,14 @@
*
* This alignment requirement means that the largest user space FLASH region
* you can have will be 256KB at it would have to be positioned at
* 0x00400000. If you change this address, don't forget to chagne the
* 0x00400000. If you change this address, don't forget to change the
* CONFIG_NUTTX_USERSPACE configuration setting to match and to modify
* the check in kernel/userspace.c.
*
* For the same reasons, the maximum size of the SRAM mapping is limited to
* 4KB. Both of these alignment limitations could be reduced by using
* multiple regions to map the FLASH/SDRAM range.
*
* A detailed memory map for the 64KB CPU SRAM region is as follows:
*
* 0x10000 0000: Kernel .data region. Typical size: 0.1KB
@ -76,12 +80,14 @@ MEMORY
/* 256Kb FLASH */
kflash (rx) : ORIGIN = 0x00000000, LENGTH = 64K
uflash (rx) : ORIGIN = 0x00010000, LENGTH = 448K
uflash (rx) : ORIGIN = 0x00010000, LENGTH = 64K
xflash (rx) : ORIGIN = 0x00010000, LENGTH = 384K
/* 64Kb of SRAM in the CPU block */
ksram (rwx) : ORIGIN = 0x10000000, LENGTH = 4K
usram (rwx) : ORIGIN = 0x10001000, LENGTH = 60K
usram (rwx) : ORIGIN = 0x10001000, LENGTH = 4K
xsram (rwx) : ORIGIN = 0x10001000, LENGTH = 56K
/* Other peripheral memory (free, nothing is linked here) */

View File

@ -111,7 +111,7 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) =
/* Signal handler trampoline */
#ifndef CONFIG_DISABLE_SIGNALS
.signal_handler = signal_handler,
.signal_handler = up_signal_handler,
#endif
/* Memory manager entry points (declared in include/nuttx/mm.h) */

View File

@ -51,11 +51,15 @@
* requirement also increases.
*
* This alignment requirement means that the largest user space FLASH region
* you can have will be 2128KB at it would have to be positioned at
* 0x000a0000. If you change this address, don't forget to chagne the
* you can have will be 128KB at it would have to be positioned at
* 0x000a0000. If you change this address, don't forget to change the
* CONFIG_NUTTX_USERSPACE configuration setting to match and to modify
* the check in kernel/userspace.c.
*
* For the same reasons, the maximum size of the SRAM mapping is limited to
* 4KB. Both of these alignment limitations could be reduced by using
* multiple regions to map the FLASH/SDRAM range.
*
* A detailed memory map for the 16Kb SRAM region is as follows:
*
* 0x20000 0000: Kernel .data region. Typical size: 0.1KB
@ -77,12 +81,14 @@ MEMORY
/* 256Kb FLASH */
kflash (rx) : ORIGIN = 0x00080000, LENGTH = 64K
uflash (rx) : ORIGIN = 0x00090000, LENGTH = 192K
uflash (rx) : ORIGIN = 0x00090000, LENGTH = 64K
xflash (rx) : ORIGIN = 0x000a0000, LENGTH = 128K
/* 32Kb SRAM */
ksram1 (rwx) : ORIGIN = 0x20000000, LENGTH = 4K
usram1 (rwx) : ORIGIN = 0x20001000, LENGTH = 28K
usram1 (rwx) : ORIGIN = 0x20001000, LENGTH = 4K
xsram1 (rwx) : ORIGIN = 0x20001000, LENGTH = 24K
/* 16Kb SRAM */

View File

@ -111,7 +111,7 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) =
/* Signal handler trampoline */
#ifndef CONFIG_DISABLE_SIGNALS
.signal_handler = signal_handler,
.signal_handler = up_signal_handler,
#endif
/* Memory manager entry points (declared in include/nuttx/mm.h) */

View File

@ -42,8 +42,7 @@
*
* When booting from FLASH, FLASH memory is aliased to address 0x0000:0000
* where the code expects to begin execution by jumping to the entry point in
* the 0x0800:0000 address
* range.
* the 0x0800:0000 address range.
*
* For MPU support, the kernel-mode NuttX section is assumed to be 128Kb of
* FLASH and 4Kb of SRAM. That is an excessive amount for the kernel which
@ -60,10 +59,14 @@
*
* This alignment requirement means that the largest user space FLASH region
* you can have will be 512KB at it would have to be positioned at
* 0x08800000. If you change this address, don't forget to chagne the
* 0x08800000. If you change this address, don't forget to change the
* CONFIG_NUTTX_USERSPACE configuration setting to match and to modify
* the check in kernel/userspace.c.
*
* For the same reasons, the maximum size of the SRAM mapping is limited to
* 4KB. Both of these alignment limitations could be reduced by using
* multiple regions to map the FLASH/SDRAM range.
*
* A detailed memory map for the 112KB SRAM region is as follows:
*
* 0x20000 0000: Kernel .data region. Typical size: 0.1KB
@ -74,7 +77,7 @@
* ------- ---- Padded to 4KB
* 0x20000 1000: User .data region. Size is variable.
* ------- ---- User .bss region Size is variable.
* ------- ---- Beginning of kernel heap. Size determined by
* 0x20000 2000: Beginning of kernel heap. Size determined by
* CONFIG_MM_KERNEL_HEAPSIZE.
* ------- ---- Beginning of user heap. Can vary with other settings.
* 0x20001 c000: End+1 of CPU RAM
@ -85,10 +88,12 @@ MEMORY
/* 1024Kb FLASH */
kflash (rx) : ORIGIN = 0x08000000, LENGTH = 128K
uflash (rx) : ORIGIN = 0x08020000, LENGTH = 896K
uflash (rx) : ORIGIN = 0x08020000, LENGTH = 128K
xflash (rx) : ORIGIN = 0x08040000, LENGTH = 768K
/* 112Kb of contiguous SRAM */
ksram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K
usram (rwx) : ORIGIN = 0x20001000, LENGTH = 108K
usram (rwx) : ORIGIN = 0x20001000, LENGTH = 4K
xsram (rwx) : ORIGIN = 0x20001000, LENGTH = 104K
}

View File

@ -506,7 +506,7 @@ void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
#endif
/****************************************************************************
* Name: up_signal_handler
* Name: up_signal_dispatch
*
* Description:
* In this kernel mode build, this function will be called to execute a
@ -515,11 +515,10 @@ void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
* This kernel-mode stub will then be called transfer control to the user
* mode signal handler by calling this function.
*
* Normally the a user-mode signalling handling stub will also execute
* before the ultimate signal handler is called. See
* libc/signal/signal_handler.c This function is the user-space, signal
* handler trampoline function. It is called from up_signal_handler() in
* user-mode.
* Normally the a architecture, user-mode signal handling stub will also
* execute before the ultimate signal handler is called. That stub
* function is the user-space, signal handler trampoline function. It is
* called from up_signal_dispatch() in user-mode.
*
* Inputs:
* sighand - The address user-space signal handling function
@ -528,37 +527,42 @@ void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
*
* Return:
* None. This function does not return in the normal sense. It returns
* via signal_handler_return (below)
* via an architecture specific system call made by up_signal_handler()
* (see below). However, this will look like a normal return by the
* caller of up_signal_dispatch.
*
****************************************************************************/
#if defined(CONFIG_NUTTX_KERNEL) && defined(__KERNEL__) && !defined(CONFIG_DISABLE_SIGNALS)
void up_signal_handler(_sa_sigaction_t sighand, int signo,
FAR siginfo_t *info, FAR void *ucontext) noreturn_function;
void up_signal_dispatch(_sa_sigaction_t sighand, int signo,
FAR siginfo_t *info, FAR void *ucontext);
#endif
/****************************************************************************
* Name: signal_handler_return
* Name: up_signal_handler
*
* Description:
* This function is the user-space, signal handler return function. It
* is called from the signal_handler() in user-mode. This function has the
* general prototype:
*
* void signal_handler_return(void);
*
* However, it it not prototyped here because it should be implemented as
* an inline function or macro that can be obtain by including the file
* include/arch/syscall.h.
* This function is the user-space, signal handler trampoline function that
* must be provided by architecture-specific logic. It is called from
* up_signal_dispatch() in user-mode.
*
* Inputs:
* None.
* sighand - The address user-space signal handling function
* signo, info, and ucontext - Standard arguments to be passed to the
* signal handling function.
*
* Return:
* None. This function does not return.
* None. This function does not return in the normal sense. It returns
* via an architecture specific system call.
*
****************************************************************************/
#if defined(CONFIG_NUTTX_KERNEL) && !defined(__KERNEL__) && !defined(CONFIG_DISABLE_SIGNALS)
void up_signal_handler(_sa_sigaction_t sighand, int signo,
FAR siginfo_t *info, FAR void *ucontext)
noreturn_function;
#endif
/****************************************************************************
* Name: up_allocate_heap
*

View File

@ -47,6 +47,8 @@
#include <signal.h>
#include <pthread.h>
#include <nuttx/arch.h>
#ifdef CONFIG_NUTTX_KERNEL
/****************************************************************************
@ -204,29 +206,6 @@ void task_startup(main_t entrypt, int argc, FAR char *argv[]) noreturn_function;
void pthread_startup(pthread_startroutine_t entrypt, pthread_addr_t arg);
#endif
/****************************************************************************
* Name: signal_handler
*
* Description:
* This function is the user-space, signal handler trampoline function. It
* is called from up_signal_handler() in user-mode.
*
* Inputs:
* sighand - The address user-space signal handling function
* signo, info, and ucontext - Standard arguments to be passed to the
* signal handling function.
*
* Return:
* None. This function does not return in the normal sense. It returns
* via signal_handler_return (see include/nuttx/arch.h)
*
****************************************************************************/
#if defined(CONFIG_NUTTX_KERNEL) && !defined(__KERNEL__) && !defined(CONFIG_DISABLE_SIGNALS)
void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info,
FAR void *ucontext);
#endif
#undef EXTERN
#ifdef __cplusplus
}

View File

@ -39,10 +39,6 @@ ifneq ($(CONFIG_DISABLE_SIGNALS),y)
CSRCS += sig_emptyset.c sig_fillset.c sig_addset.c sig_delset.c sig_ismember.c
ifeq ($(CONFIG_NUTTX_KERNEL),y)
CSRCS += signal_handler.c
endif
# Add the signal directory to the build
DEPPATH += --dep-path signal

View File

@ -148,8 +148,8 @@ void sig_deliver(FAR struct tcb_s *stcb)
siginfo_t info;
memcpy(&info, &sigq->info, sizeof(siginfo_t));
up_signal_handler(sigq->action.sighandler, sigq->info.si_signo,
&info, NULL);
up_signal_dispatch(sigq->action.sighandler, sigq->info.si_signo,
&info, NULL);
}
else
#endif