diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-09-10 15:55:36 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-09-10 15:55:36 -0600 |
commit | 7b3a98b2ec57f8c56a1669b818d03dfcd1a84fb2 (patch) | |
tree | 776264ed920f68eed300648dffe198e286495000 /nuttx/binfmt | |
parent | 22c64f6c542675d4865d2a013468089c92f43869 (diff) | |
download | nuttx-7b3a98b2ec57f8c56a1669b818d03dfcd1a84fb2.tar.gz nuttx-7b3a98b2ec57f8c56a1669b818d03dfcd1a84fb2.tar.bz2 nuttx-7b3a98b2ec57f8c56a1669b818d03dfcd1a84fb2.zip |
Add logic to initialize the per-process user heap when each user process is started
Diffstat (limited to 'nuttx/binfmt')
-rw-r--r-- | nuttx/binfmt/binfmt_execmodule.c | 40 | ||||
-rw-r--r-- | nuttx/binfmt/libelf/libelf.h | 6 | ||||
-rw-r--r-- | nuttx/binfmt/libelf/libelf_addrenv.c | 8 | ||||
-rw-r--r-- | nuttx/binfmt/libelf/libelf_load.c | 18 | ||||
-rw-r--r-- | nuttx/binfmt/libnxflat/libnxflat.h | 2 | ||||
-rw-r--r-- | nuttx/binfmt/libnxflat/libnxflat_addrenv.c | 15 |
6 files changed, 65 insertions, 24 deletions
diff --git a/nuttx/binfmt/binfmt_execmodule.c b/nuttx/binfmt/binfmt_execmodule.c index 1afb4e8b3..b9a1dde79 100644 --- a/nuttx/binfmt/binfmt_execmodule.c +++ b/nuttx/binfmt/binfmt_execmodule.c @@ -48,6 +48,7 @@ #include <nuttx/arch.h> #include <nuttx/kmalloc.h> +#include <nuttx/mm.h> #include <nuttx/binfmt/binfmt.h> #include "sched/sched.h" @@ -164,9 +165,9 @@ int exec_module(FAR const struct binary_s *binp) goto errout; } - /* Instantiate the address environment containing the destructors */ - #ifdef CONFIG_ARCH_ADDRENV + /* Instantiate the address environment containing the user heap */ + ret = up_addrenv_select(&binp->addrenv, &oldenv); if (ret < 0) { @@ -174,9 +175,18 @@ int exec_module(FAR const struct binary_s *binp) err = -ret; goto errout_with_tcb; } + + /* Initialize the user heap */ + + umm_initialize((FAR void *)CONFIG_ARCH_HEAP_VBASE, + up_addrenv_heapsize(&binp->addrenv)); #endif - /* Allocate the stack for the new task (always from the user heap) */ + /* Allocate the stack for the new task. + * + * REVISIT: This allocation is currently always from the user heap. That + * will need to change if/when we want to support dynamic stack allocation. + */ stack = (FAR uint32_t*)kumm_malloc(binp->stacksize); if (!stack) @@ -185,18 +195,6 @@ int exec_module(FAR const struct binary_s *binp) goto errout_with_addrenv; } - /* Restore the address environment */ - -#ifdef CONFIG_ARCH_ADDRENV - ret = up_addrenv_restore(&oldenv); - if (ret < 0) - { - bdbg("ERROR: up_addrenv_select() failed: %d\n", ret); - err = -ret; - goto errout_with_stack; - } -#endif - /* Initialize the task */ ret = task_init((FAR struct tcb_s *)tcb, binp->filename, binp->priority, @@ -262,6 +260,18 @@ int exec_module(FAR const struct binary_s *binp) goto errout_with_stack; } +#ifdef CONFIG_ARCH_ADDRENV + /* Restore the address environment of the caller */ + + ret = up_addrenv_restore(&oldenv); + if (ret < 0) + { + bdbg("ERROR: up_addrenv_select() failed: %d\n", ret); + err = -ret; + goto errout_with_stack; + } +#endif + return (int)pid; errout_with_stack: diff --git a/nuttx/binfmt/libelf/libelf.h b/nuttx/binfmt/libelf/libelf.h index 4304e64f2..58ec757b8 100644 --- a/nuttx/binfmt/libelf/libelf.h +++ b/nuttx/binfmt/libelf/libelf.h @@ -283,6 +283,8 @@ int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo); * for the ELF image (read/execute). * datasize - The size (in bytes) of the .bss/.data address environment * needed for the ELF image (read/write). + * heapsize - The initial size (in bytes) of the heap address environment + * needed by the task. This region may be read/write only. * * Returned Value: * Zero (OK) on success; a negated errno value on failure. @@ -290,13 +292,13 @@ int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo); ****************************************************************************/ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize, - size_t datasize); + size_t datasize, size_t heapsize); /**************************************************************************** * Name: elf_addrenv_select * * Description: - * Temporarity select the task's address environemnt. + * Temporarily select the task's address environemnt. * * Input Parameters: * loadinfo - Load state information diff --git a/nuttx/binfmt/libelf/libelf_addrenv.c b/nuttx/binfmt/libelf/libelf_addrenv.c index 08beed008..6b3be4306 100644 --- a/nuttx/binfmt/libelf/libelf_addrenv.c +++ b/nuttx/binfmt/libelf/libelf_addrenv.c @@ -80,6 +80,8 @@ * for the ELF image (read/execute). * datasize - The size (in bytes) of the .bss/.data address environment * needed for the ELF image (read/write). + * heapsize - The initial size (in bytes) of the heap address environment + * needed by the task. This region may be read/write only. * * Returned Value: * Zero (OK) on success; a negated errno value on failure. @@ -87,7 +89,7 @@ ****************************************************************************/ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize, - size_t datasize) + size_t datasize, size_t heapsize) { #ifdef CONFIG_ARCH_ADDRENV FAR void *vtext; @@ -96,7 +98,7 @@ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize, /* Create an address environment for the new ELF task */ - ret = up_addrenv_create(textsize, datasize, &loadinfo->addrenv); + ret = up_addrenv_create(textsize, datasize, heapsize, &loadinfo->addrenv); if (ret < 0) { bdbg("ERROR: up_addrenv_create failed: %d\n", ret); @@ -145,7 +147,7 @@ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize, * * Description: * Release the address environment previously created by - * elf_addrenv_create(). This function is called only under certain error + * elf_addrenv_alloc(). This function is called only under certain error * conditions after the module has been loaded but not yet started. * After the module has been started, the address environment will * automatically be freed when the module exits. diff --git a/nuttx/binfmt/libelf/libelf_load.c b/nuttx/binfmt/libelf/libelf_load.c index 5fd4ce570..75ecb30fc 100644 --- a/nuttx/binfmt/libelf/libelf_load.c +++ b/nuttx/binfmt/libelf/libelf_load.c @@ -49,6 +49,7 @@ #include <errno.h> #include <debug.h> +#include <nuttx/addrenv.h> #include <nuttx/binfmt/elf.h> #include "libelf.h" @@ -62,7 +63,11 @@ #define ELF_ALIGNDOWN(a) ((unsigned long)(a) & ~ELF_ALIGN_MASK) #ifndef MAX -#define MAX(x,y) ((x) > (y) ? (x) : (y)) +# define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif + +#ifndef MIN +# define MIN(x,y) ((x) < (y) ? (x) : (y)) #endif /**************************************************************************** @@ -229,6 +234,7 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo) int elf_load(FAR struct elf_loadinfo_s *loadinfo) { + size_t heapsize; int ret; bvdbg("loadinfo: %p\n", loadinfo); @@ -247,9 +253,17 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo) elf_elfsize(loadinfo); + /* Determine the heapsize to allocate */ + +#ifdef CONFIG_ARCH_STACK_DYNAMIC + heapsize = ARCH_HEAP_SIZE; +#else + heapsize = MIN(ARCH_HEAP_SIZE, CONFIG_ELF_STACKSIZE); +#endif + /* Allocate (and zero) memory for the ELF file. */ - ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize); + ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize, heapsize); if (ret < 0) { bdbg("ERROR: elf_addrenv_alloc() failed: %d\n", ret); diff --git a/nuttx/binfmt/libnxflat/libnxflat.h b/nuttx/binfmt/libnxflat/libnxflat.h index fc3826295..32d82df74 100644 --- a/nuttx/binfmt/libnxflat/libnxflat.h +++ b/nuttx/binfmt/libnxflat/libnxflat.h @@ -116,7 +116,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize) * * Description: * Release the address environment previously created by - * nxflat_addrenv_create(). This function is called only under certain + * nxflat_addrenv_alloc(). This function is called only under certain * error conditions after the module has been loaded but not yet * started. After the module has been started, the address environment * will automatically be freed when the module exits. diff --git a/nuttx/binfmt/libnxflat/libnxflat_addrenv.c b/nuttx/binfmt/libnxflat/libnxflat_addrenv.c index fb3dbe09a..c7e82f537 100644 --- a/nuttx/binfmt/libnxflat/libnxflat_addrenv.c +++ b/nuttx/binfmt/libnxflat/libnxflat_addrenv.c @@ -52,6 +52,10 @@ * Pre-Processor Definitions ****************************************************************************/ +#ifndef MIN +# define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif + /**************************************************************************** * Private Constant Data ****************************************************************************/ @@ -88,6 +92,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize) #ifdef CONFIG_ARCH_ADDRENV FAR void *vdata; save_addrenv_t oldenv; + size_t heapsize; int ret; #endif @@ -103,9 +108,17 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize) } #ifdef CONFIG_ARCH_ADDRENV + /* Determine the heapsize to allocate */ + +#ifdef CONFIG_ARCH_STACK_DYNAMIC + heapsize = ARCH_HEAP_SIZE; +#else + heapsize = MIN(loadinfo->stacksize, ARCH_HEAP_SIZE); +#endif + /* Create a D-Space address environment for the new NXFLAT task */ - ret = up_addrenv_create(envsize, &loadinfo->addrenv); + ret = up_addrenv_create(0, envsize, heapsize, &loadinfo->addrenv); if (ret < 0) { bdbg("ERROR: up_addrenv_create failed: %d\n", ret); |