Restructuring of build to allow use of use-space allocators by kernel logic in the kernel build.

This commit is contained in:
Gregory Nutt 2014-09-02 11:22:09 -06:00
parent b085e084f4
commit b4438e44c5
10 changed files with 94 additions and 60 deletions

View File

@ -67,8 +67,9 @@
*
* The ARMv7 has no MPU but does have an MMU. With this MMU, it can support
* the kernel build (CONFIG_BUILD_KERNEL=y). In this configuration, there
* is again only one heap but, retaining the terminology, this is the kernel
* heap.
* is one kernel heap but multiple user heaps: One per task group. However,
* in this case, we need only be concerned about initializing the single
* kernel heap here.
*/
/****************************************************************************

View File

@ -69,13 +69,12 @@
*
* The ARMv7 has no MPU but does have an MMU. With this MMU, it can support
* the kernel build (CONFIG_BUILD_KERNEL=y). In this configuration, there
* is again only one heap but, retaining the terminology, this is the kernel
* heap.
* is one kernel heap but multiple user heaps: One per task group. However,
* in this case, we need only be concerned about initializing the single
* kernel heap here.
*/
#if defined(CONFIG_MM_USER_HEAP) && defined(CONFIG_MM_KERNEL_HEAP)
# error "Cannot support both user and kernel heaps"
#elif defined(CONFIG_MM_KERNEL_HEAP)
#if defined(CONFIG_BUILD_KERNEL)
# define MM_ADDREGION kmm_addregion
#else
# define MM_ADDREGION umm_addregion
@ -247,10 +246,10 @@
*
****************************************************************************/
#if defined(CONFIG_MM_USER_HEAP)
void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
#elif defined(CONFIG_MM_KERNEL_HEAP)
#if defined(CONFIG_BUILD_KERNEL)
void up_allocate_kheap(FAR void **heap_start, size_t *heap_size)
#else
void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
#endif
{
#if defined(CONFIG_BOOT_SDRAM_DATA)

View File

@ -760,7 +760,10 @@ uintptr_t pgalloc(uintptr_t brkaddr, unsigned int npages);
* textsize - The size (in bytes) of the .text address environment needed
* by the task. This region may be read/execute only.
* datasize - The size (in bytes) of the .data/.bss address environment
* needed by the task. This region may be read/write only.
* needed by the task. This region may be read/write only. NOTE: The
* actual size of the data region that is allocated will include a
* OS private reserved region at the beginning. The size of the
* private, reserved region is give by ARCH_DATA_RESERVE.
* addrenv - The location to return the representation of the task address
* environment.
*
@ -831,7 +834,11 @@ int up_addrenv_vtext(FAR group_addrenv_t *addrenv, FAR void **vtext);
* in the same memory region (read/write/execute) and, in this case,
* the virtual address of the data just lies at this offset into the
* common region.
* vdata - The location to return the virtual address.
* vdata - The location to return the virtual address. NOTE that the
* beginning of the data region is reserved for use by the OS. The
* returned address will be at a offset from the actual allocated base
* address to account for the OS private region. The size of that
* offset is given by ARCH_DATA_RESERVE
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.

View File

@ -89,8 +89,21 @@ extern "C"
#define kumm_trysemaphore() umm_trysemaphore()
#define kumm_givesemaphore() umm_givesemaphore()
#ifndef CONFIG_BUILD_PROTECTED
/* In the flat build, the following are declared in stdlib.h and are
#ifdef CONFIG_BUILD_PROTECTED
/* In the kernel-phase of the protected build, the these macros are defined
* in userspace.h. These macros version call into user-space via a header
* at the beginning of the user-space blob.
*/
# define kumm_malloc(s) umm_malloc(s)
# define kumm_zalloc(s) umm_zalloc(s)
# define kumm_realloc(p,s) umm_realloc(p,s)
# define kumm_memalign(a,s) umm_memalign(a,s)
# define kumm_free(p) umm_free(p)
#else
/* In the flat build (CONFIG_BUILD_FLAT) and in the kernel build
* (CONFIG_BUILD_KERNEL), the following are declared in stdlib.h and are
* directly callable.
*/
@ -100,18 +113,6 @@ extern "C"
# define kumm_memalign(a,s) memalign(a,s)
# define kumm_free(p) free(p)
#else
/* In the kernel-phase of the protected build, the these macros are defined
* in userspace.h. These macros versions call into user-space via a header
* at the beginning of the user-space blob.
*/
# define kumm_malloc(s) umm_malloc(s)
# define kumm_zalloc(s) umm_zalloc(s)
# define kumm_realloc(p,s) umm_realloc(p,s)
# define kumm_memalign(a,s) umm_memalign(a,s)
# define kumm_free(p) umm_free(p)
#endif
/* This family of allocators is used to manage kernel protected memory */
@ -164,9 +165,7 @@ extern "C"
* sched_garbagecollection().
*/
#ifdef CONFIG_MM_USER_HEAP
void sched_ufree(FAR void *address);
#endif
#if defined(CONFIG_MM_KERNEL_HEAP) && defined(__KERNEL__)
void sched_kfree(FAR void *address);

View File

@ -65,21 +65,40 @@
# define CONFIG_MM_SMALL 1
#endif
/* Decide if there is a user heap. CONFIG_MM_USER_HEAP=n does not not
* really that there is no user heap but, rather, that there is no
* user heap available from within the kernel. The user heap is
* Available if:
/* Terminology:
*
* 1. The code is begin build for kernel space and this is a FLAT build
* (CONFIG_BUILD_FLAT=y),
* 2. The code is begin build for kernel space and this is a protected
* build (CONFIG_BUILD_PROTECTED=y), OR
* 3. The code is begin build for user space.
* - Flat Build: In the flat build (CONFIG_BUILD_FLAT=y), there is only a
* single heap access with the standard allocations (malloc/free). This
* heap is referred to as the user heap. The kernel logic must
* initialize this single heap at boot time.
* - Protected build: In the protected build (CONFIG_BUILD_PROTECTED=y)
* where an MPU is used to protect a region of otherwise flat memory,
* there will be two allocators: One that allocates protected (kernel)
* memory and one that allocates unprotected (user) memory. These are
* referred to as the kernel and user heaps, respectively. Both must be
* initialized by the kernel logic at boot time.
* - Kernel Build: If the architecture has an MMU, then it may support the
* kernel build (CONFIG_BUILD_KERNEL=y). In this configuration, there
* is one kernel heap but multiple user heaps: One per task group.
* However, in this case, the kernel need only be concerned about
* initializing the single kernel heap here. User heaps will be created
* as tasks are created.
*
* These special definitions are provided:
*
* MM_KERNEL_USRHEAP_INIT
* Special kernel interfaces to the kernel user-heap are required
* for heap initialization.
* CONFIG_MM_KERNEL_HEAP
* The configuration requires a kernel heap that must initialized
* at boot-up.
*/
#undef CONFIG_MM_USER_HEAP
#if !defined(CONFIG_BUILD_KERNEL) || !defined(__KERNEL__)
# define CONFIG_MM_USER_HEAP 1
#undef MM_KERNEL_USRHEAP_INIT
#if defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)
# define MM_KERNEL_USRHEAP_INIT 1
#elif !defined(CONFIG_BUILD_KERNEL)
# define MM_KERNEL_USRHEAP_INIT 1
#endif
/* The kernel heap is never accessible from user code */
@ -243,8 +262,18 @@ extern "C"
#define EXTERN extern
#endif
#ifdef CONFIG_MM_USER_HEAP
/* This is the user heap */
#if (!defined(CONFIG_ARCH_ADDRENV) || !defined(CONFIG_BUILD_KERNEL)) && \
(defined(CONFIG_BUILD_KERNEL) && !defined(__KERNEL__))
/* User heap structure:
*
* - Flat build: In the FLAT build, the user heap structure is a globally
* accessible variable.
* - Protected build: The user heap structure is directly available only
* in user space.
* - Kernel build: There are multiple heaps, one per process. The heap
* structure is associated with the address environment and there is
* no global user heap structure.
*/
EXTERN struct mm_heap_s g_mmheap;
#endif
@ -268,7 +297,7 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart,
/* Functions contained in umm_initialize.c **********************************/
#ifdef CONFIG_MM_USER_HEAP
#ifdef MM_KERNEL_USRHEAP_INIT
void umm_initialize(FAR void *heap_start, size_t heap_size);
#endif
@ -280,13 +309,13 @@ void kmm_initialize(FAR void *heap_start, size_t heap_size);
/* Functions contained in umm_addregion.c ***********************************/
#ifdef CONFIG_MM_USER_HEAP
#ifdef MM_KERNEL_USRHEAP_INIT
void umm_addregion(FAR void *heapstart, size_t heapsize);
#endif
/* Functions contained in kmm_addregion.c ***********************************/
#ifdef CONFIG_MM_USER_HEAP
#ifdef CONFIG_MM_KERNEL_HEAP
void kmm_addregion(FAR void *heapstart, size_t heapsize);
#endif
@ -299,7 +328,7 @@ void mm_givesemaphore(FAR struct mm_heap_s *heap);
/* Functions contained in umm_sem.c ****************************************/
#ifdef CONFIG_MM_USER_HEAP
#ifdef MM_KERNEL_USRHEAP_INIT
int umm_trysemaphore(void);
void umm_givesemaphore(void);
#endif
@ -385,9 +414,7 @@ FAR void *mm_brkaddr(FAR struct mm_heap_s *heap, int region);
/* Functions contained in umm_brkaddr.c *************************************/
#ifdef CONFIG_MM_USER_HEAP
FAR void *umm_brkaddr(int region);
#endif
/* Functions contained in kmm_brkaddr.c *************************************/
@ -397,14 +424,16 @@ FAR void *kmm_brkaddr(int region);
/* Functions contained in mm_sbrk.c *****************************************/
#ifdef CONFIG_ARCH_ADDRENV
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_MM_PGALLOC) && \
defined(CONFIG_ARCH_USE_MMU)
FAR void *mm_sbrk(FAR struct mm_heap_s *heap, intptr_t incr,
uintptr_t maxbreak);
#endif
/* Functions contained in kmm_sbrk.c ****************************************/
#ifdef CONFIG_ARCH_ADDRENV
#if defined(CONFIG_MM_KERNEL_HEAP) && defined(CONFIG_ARCH_ADDRENV) && \
defined(CONFIG_MM_PGALLOC) && defined(CONFIG_ARCH_USE_MMU)
FAR void *kmm_sbrk(intptr_t incr);
#endif
@ -415,9 +444,7 @@ void mm_extend(FAR struct mm_heap_s *heap, FAR void *mem, size_t size,
/* Functions contained in umm_extend.c **************************************/
#ifdef CONFIG_MM_USER_HEAP
void umm_extend(FAR void *mem, size_t size, int region);
#endif
/* Functions contained in kmm_extend.c **************************************/

View File

@ -149,7 +149,8 @@ ssize_t write(int fd, FAR const void *buf, size_t nbytes);
/* Memory management */
#ifdef CONFIG_ARCH_ADDRENV
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_MM_PGALLOC) && \
defined(CONFIG_ARCH_USE_MMU)
FAR void *sbrk(intptr_t incr);
#endif

View File

@ -41,7 +41,8 @@
#include <nuttx/mm.h>
#if defined(CONFIG_MM_KERNEL_HEAP) && defined(CONFIG_ARCH_ADDRENV)
#if defined(CONFIG_MM_KERNEL_HEAP) && defined(CONFIG_ARCH_ADDRENV) && \
defined(CONFIG_MM_PGALLOC) && defined(CONFIG_ARCH_USE_MMU)
/****************************************************************************
* Pre-processor Definitions
@ -88,4 +89,4 @@ FAR void *kmm_sbrk(intptr_t incr)
return mm_sbrk(&g_kmmheap, incr, UINTPTR_MAX);
}
#endif /* CONFIG_MM_USER_HEAP && CONFIG_ARCH_ADDRENV */
#endif /* CONFIG_MM_KERNEL_HEAP && CONFIG_ARCH_ADDRENV && ... */

View File

@ -47,7 +47,8 @@
#include <nuttx/mm.h>
#include <nuttx/pgalloc.h>
#ifdef CONFIG_ARCH_ADDRENV
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_MM_PGALLOC) && \
defined(CONFIG_ARCH_USE_MMU)
/****************************************************************************
* Pre-processor Definitions
@ -163,4 +164,4 @@ errout:
set_errno(err);
return (FAR void *)-1;
}
#endif /* CONFIG_ARCH_ADDRENV */
#endif /* CONFIG_ARCH_ADDRENV && CONFIG_MM_PGALLOC && CONFIG_ARCH_USE_MMU */

View File

@ -350,7 +350,7 @@ void os_start(void)
FAR void *heap_start;
size_t heap_size;
#ifdef CONFIG_MM_USER_HEAP
#ifdef MM_KERNEL_USRHEAP_INIT
/* Get the user-mode heap from the platform specific code and configure
* the user-mode memory allocator.
*/

View File

@ -82,7 +82,6 @@
*
************************************************************************/
#ifdef CONFIG_MM_USER_HEAP
void sched_ufree(FAR void *address)
{
irqstate_t flags;
@ -123,7 +122,6 @@ void sched_ufree(FAR void *address)
kumm_givesemaphore();
}
}
#endif
#ifdef CONFIG_MM_KERNEL_HEAP
void sched_kfree(FAR void *address)