Add a pre-relocation malloc() implementation
v2 cover Add a pre-relocation malloc() implementation
There has been talk on and off of a pre-relocation malloc() implementation. Driver model needs this so that it can work before relocation.
A previous implementation was sent in a v1 series.
This implementation works by allocating space on the stack. The benefit is that boards do not need to specify the address of the malloc() area, only the size. The down-side is that due to the way board_init_f() is called, architecture-specific code needs to be used to allocate the space.
No clever algorithms are used to allocate space, free() is a nop and realloc() is not supported. This fits well with the desire to avoid wasting space on bucket tables and the hassle of supporting BSS data before relocation. We don't expect 'churn' in the pre-relocation case - we just want to allocate small amounts of memory temporarily.
After relocation a new malloc() pool is created and the old one is lost, although pointers into it will survive the immediate process of relocation.
Implementations are provided for sandbox and arm.
A related change is made to the early init for each arch to make this work.
Changes in v2:
- Tidy up commit message typo
Simon Glass (9):
Remove form-feeds from dlmalloc.c
arm: Set up global data before board_init_f()
sandbox: Set up global data before board_init_f() Add a simple malloc() implementation for pre-relocation
arm: Support pre-relocation malloc()
exynos: Enable pre-relocation malloc()
sandbox: Support pre-relocation malloc()
sandbox: config: Enable pre-relocation malloc()
sandbox: Always enable malloc debug
README | 16 ++++++++ arch/arm/include/asm/config.h | 2 - arch/arm/lib/crt0.S | 11 +++++ arch/sandbox/cpu/start.c | 8 ++++ arch/sandbox/include/asm/config.h | 1 - common/board_f.c | 12 ++++++ common/board_r.c | 4 ++ common/dlmalloc.c | 85 ++++++++++++++++++++++++++++----------- include/asm-generic/global_data.h | 5 +++ include/configs/exynos5-dt.h | 4 +- include/configs/sandbox.h | 5 ++- lib/asm-offsets.c | 3 ++ 12 files changed, 127 insertions(+), 29 deletions(-)
Signature · 1 line
2.0.0.526.g5318336
PATCH v2 1/9 Remove form-feeds from dlmalloc.c
These don't really serve any purpose in the modern age. On the other hand they show up as annoying control characters in my editor, which then happily removes them.
I believe we can drop these characters from the file.
---
Changes in v2:
- Tidy up commit message typo
common/dlmalloc.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-)
common/dlmalloc.c +23 -23
@@ -220,7 +220,7 @@*/ - +/* Preliminaries */
@@ -1132,7 +1132,7 @@ gAllocatedSize))#endif - +/* Type declarations
@@ -1272,7 +1272,7 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+serviced via calls to mmap, and then later released via munmap. */ - +/* sizes, alignments */ #define SIZE_SZ (sizeof(INTERNAL_SIZE_T))
@@ -1297,7 +1297,7 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+#define aligned_OK (m) (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0) - +/* Physical chunk operations
@@ -1332,7 +1332,7 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+#define chunk_at_offset (p, s) ((mchunkptr)(((char*)(p)) + (s))) - +/* Dealing with use bits
@@ -1371,7 +1371,7 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ (((mchunkptr)(((char *)(p)) + (s)))->size &= ~(PREV_INUSE )) - +/* Dealing with size fields
@@ -1394,7 +1394,7 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+#define set_foot (p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s)) - +/*
@@ -1566,7 +1566,7 @@ void mem_malloc_init(ulong start, ulong size)#define is_small_request (nb) (nb < MAX_SMALLBIN_SIZE - SMALLBIN_WIDTH) - +/* To help compensate for the large number of bins, a one-level index
@@ -1590,7 +1590,7 @@ void mem_malloc_init(ulong start, ulong size)#define clear_binblock (ii) (binblocks_w = (mbinptr)(binblocks_r & ~(idx2binblock(ii)))) - +/* Other static bookkeeping data */
@@ -1628,7 +1628,7 @@ static unsigned int max_n_mmaps = 0;static unsigned long max_mmapped_mem =0 ;#endif - +/* Debugging support
@@ -1769,7 +1769,7 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;#define check_malloced_chunk (P ,N )#endif - +/* Macro-based internal utilities
@@ -1841,7 +1841,7 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s; (last_remainder->fd = last_remainder->bk = last_remainder) - +/* Routines dealing with mmap(). */
@@ -1972,7 +1972,7 @@ static mchunkptr mremap_chunk(p, new_size) mchunkptr p; size_t new_size;#endif /* HAVE_MMAP */ - +/* Extend the top-most chunk by obtaining memory from system.
@@ -2089,7 +2089,7 @@ static void malloc_extend_top(nb) INTERNAL_SIZE_T nb; } - +/* Main public routines */
@@ -2396,7 +2396,7 @@ Void_t* mALLOc(bytes) size_t bytes; } - +/*
@@ -2513,7 +2513,7 @@ void fREe(mem) Void_t* mem; } - +/*
@@ -2750,7 +2750,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes; } - +/*
@@ -2868,7 +2868,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes; } - +/*
@@ -2975,7 +2975,7 @@ void cfree(mem) Void_t *mem; }#endif - +/*
@@ -3056,7 +3056,7 @@ int malloc_trim(pad) size_t pad; } } - +/* malloc_usable_size:
@@ -3092,7 +3092,7 @@ size_t malloc_usable_size(mem) Void_t* mem; } - +/* Utility to update current_mallinfo for malloc_stats and mallinfo() */
@@ -3136,7 +3136,7 @@ static void malloc_update_mallinfo() }#endif /* DEBUG */ - +/*
@@ -3183,7 +3183,7 @@ struct mallinfo mALLINFo()#endif /* DEBUG */ - +/* mallopt:
Signature · 1 line
2.0.0.526.g5318336
PATCH v2 2/9 arm: Set up global data before board_init_f()
In reply to Simon GlassAt present arm defines CONFIG_SYS_GENERIC_GLOBAL_DATA, meaning that the global_data pointer is set up in board_init_f(). However it is actually set up before this, it just isn't zeroed.
If we zero the global data before calling board_init_f() then we don't need to define CONFIG_SYS_GENERIC_GLOBAL_DATA.
Make this change to simplify the init process.
---
Changes in v2: None
arch/arm/include/asm/config.h | 2 -- arch/arm/lib/crt0.S | 7 +++++++ 2 files changed, 7 insertions(+), 2 deletions(-)
arch/arm/include/asm/config.h +0 -2
@@ -7,8 +7,6 @@#ifndef _ASM_CONFIG_H_#define _ASM_CONFIG_H_ -#define CONFIG_SYS_GENERIC_GLOBAL_DATA -#define CONFIG_LMB #define CONFIG_SYS_BOOT_RAMDISK_HIGH
arch/arm/lib/crt0.S +7 -0
@@ -67,9 +67,16 @@ ENTRY(_main) ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ + mov r2, sp sub sp, sp, #GD_SIZE /* allocate one GD above SP */ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ mov r9, sp /* GD is above SP */ + mov r1, r9 + mov r0, #0 +clr_gd: cmp r1, r2 /* while not at end of BSS */ + strlo r0, [r1] /* clear 32-bit BSS word */ + addlo r1, r1, #4 /* move to next */ + blo clr_gd mov r0, #0 bl board_init_f
Signature · 1 line
2.0.0.526.g5318336
PATCH v2 2/9 arm: Set up global data before board_init_f()
Hello Simon,
Quoted 9 lines · Simon Glass
At present arm defines
CONFIG_SYS_GENERIC_GLOBAL_DATA, meaning that theglobal_datapointer is set up inboard_init_f(). However it is actually set up before this, it just isn't zeroed.If we zero the global data before calling
board_init_f()then we don't need to defineCONFIG_SYS_GENERIC_GLOBAL_DATA.Make this change to simplify the init process.
Quoted 8 lines
Signed-off-by Simon Glass <[email protected]>---
Changes in v2: None
arch/arm/include/asm/config.h | 2 -- arch/arm/lib/crt0.S | 7 +++++++ 2 files changed, 7 insertions(+), 2 deletions(-)
First of all, good idea.. I missed v1 apparently.
arch/arm/include/asm/config.h line 11
Quoted 10 lines
arch/arm/include/asm/config.h +0
-2@@ -7,8 +7,6 @@#ifndef _ASM_CONFIG_H_#define _ASM_CONFIG_H_ -#define CONFIG_SYS_GENERIC_GLOBAL_DATA -
This bricks aarch64 I guess.
Quoted 10 lines
arch/arm/include/asm/config.h +0
-0#define CONFIG_LMB #define CONFIG_SYS_BOOT_RAMDISK_HIGH arch/arm/lib/crt0.S +0
-0@@ -67,9 +67,16 @@ ENTRY(_main) ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif
arch/arm/lib/crt0.S ENTRY(_main) · line 78
Quoted 10 lines
arch/arm/lib/crt0.S +6
-0bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ + mov r2, sp sub sp, sp, #GD_SIZE /* allocate one GD above SP */ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ mov r9, sp /* GD is above SP */ + mov r1, r9 + mov r0, #0 +clr_gd: cmp r1, r2 /* while not at end of BSS */ + strlo r0, [r1] /* clear 32-bit BSS word */ + addlo r1, r1, #4 /* move to next */
The comment should be updated, it is not BSS which is cleared.
arch/arm/lib/crt0.S ENTRY(_main) · line 82
Quoted 4 lines
arch/arm/lib/crt0.S +1
-0+ blo clr_gd mov r0, #0 bl board_init_f
The mov r0, #0 for the argument could be removed, but at least deserves a comment if you do so.
Regards,
Jeroen
PATCH v2 2/9 arm: Set up global data before board_init_f()
Hi Jeroen,
Quoted 27 lines · Jeroen Hofstee
Hello Simon,
Quoted 10 lines · Simon Glass
At present arm defines
CONFIG_SYS_GENERIC_GLOBAL_DATA, meaning that theglobal_datapointer is set up inboard_init_f(). However it is actually set up before this, it just isn't zeroed.If we zero the global data before calling
board_init_f()then we don't need to defineCONFIG_SYS_GENERIC_GLOBAL_DATA.Make this change to simplify the init process.
Quoted 8 lines
Signed-off-by Simon Glass <[email protected]>---
Changes in v2: None
arch/arm/include/asm/config.h | 2 -- arch/arm/lib/crt0.S | 7 +++++++ 2 files changed, 7 insertions(+), 2 deletions(-)First of all, good idea.. I missed v1 apparently.
Quoted 12 lines
arch/arm/include/asm/config.h line 10
Quoted 9 lines
arch/arm/include/asm/config.h +0
-1@@ -7,8 +7,6 @@#ifndef _ASM_CONFIG_H_#define _ASM_CONFIG_H_ -#define CONFIG_SYS_GENERIC_GLOBAL_DATA -This bricks aarch64 I guess.
I'll see if I can add it there also.
Quoted 16 lines
Quoted 16 lines
arch/arm/include/asm/config.h +0
-0#define CONFIG_LMB #define CONFIG_SYS_BOOT_RAMDISK_HIGH diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.Sindex dfc2de9..bbf3e41 100644
arch/arm/lib/crt0.S +2
-0@@ -67,9 +67,16 @@ ENTRY(_main) ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ + mov r2, sp sub sp, sp, #GD_SIZE /* allocate one GD above SP */ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ mov r9, sp /* GD is above SP */ + mov r1, r9
Quoted 8 lines
arch/arm/lib/crt0.S ENTRY(_main) · line 78
Quoted 5 lines
arch/arm/lib/crt0.S +4
-0+ mov r0, #0 +clr_gd: cmp r1, r2 /* while not at end of BSS */ + strlo r0, [r1] /* clear 32-bit BSS word */ + addlo r1, r1, #4 /* move to next */The comment should be updated, it is not BSS which is cleared.
Yes I have a new version which I'm testing and will send when ready.
Quoted 9 lines
arch/arm/lib/crt0.S ENTRY(_main) · line 81
Quoted 5 lines
arch/arm/lib/crt0.S +1
-0+ blo clr_gd mov r0, #0 bl board_init_fThe mov r0, #0 for the argument could be removed, but at least deserves a comment if you do so.
OK, I'll add that too.
Regards,
Simon
PATCH v2 2/9 arm: Set up global data before board_init_f()
Hello Simon,
Quoted 14 lines · Simon Glass
Hi Jeroen,
Quoted 11 lines · Jeroen Hofstee
arch/arm/include/asm/config.h line 10
Quoted 9 lines
arch/arm/include/asm/config.h +0
-1@@ -7,8 +7,6 @@#ifndef _ASM_CONFIG_H_#define _ASM_CONFIG_H_ -#define CONFIG_SYS_GENERIC_GLOBAL_DATA -This bricks aarch64 I guess.
Quoted 1 line
I'll see if I can add it there also.
If you manage actually boot an virtual aarch64 board (with console), could you report how you did it. I gave up at the fifth loader or something bl3.3?
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
arch/arm/include/asm/config.h +0
-0#define CONFIG_LMB #define CONFIG_SYS_BOOT_RAMDISK_HIGH diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.Sindex dfc2de9..bbf3e41 100644
arch/arm/lib/crt0.S +0
-0@@ -67,9 +67,16 @@ ENTRY(_main) ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif
Quoted 8 lines
Quoted 8 lines
arch/arm/lib/crt0.S ENTRY(_main)
Quoted 8 lines
arch/arm/lib/crt0.S +4
-0bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ + mov r2, sp sub sp, sp, #GD_SIZE /* allocate one GD above SP */ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ mov r9, sp /* GD is above SP */ + mov r1, r9 + mov r0, #0 +clr_gd: cmp r1, r2 /* while not at end of BSS
nitpicking, personal taste I guess: could you hit enter after the clr_gd label?
Quoted 9 lines
Quoted 8 lines
arch/arm/lib/crt0.S ENTRY(_main) · line 82
Quoted 5 lines
arch/arm/lib/crt0.S +1
-0+ blo clr_gd mov r0, #0 bl board_init_fThe mov r0, #0 for the argument could be removed, but at least deserves a comment if you do so.
OK, I'll add that too.
I leave that up to you.
Regards,
Jeroen
PATCH v2 2/9 arm: Set up global data before board_init_f()
Hi Jeroen,
Quoted 23 lines · Jeroen Hofstee
Hello Simon,
Quoted 19 lines · Simon Glass
Hi Jeroen,
Quoted 14 lines · Jeroen Hofstee
arch/arm/include/asm/config.h line 10
Quoted 11 lines
arch/arm/include/asm/config.h +0
-1@@ -7,8 +7,6 @@#ifndef _ASM_CONFIG_H_#define _ASM_CONFIG_H_ -#define CONFIG_SYS_GENERIC_GLOBAL_DATA -This bricks aarch64 I guess.
Quoted 6 lines
Quoted 1 line
I'll see if I can add it there also.
If you manage actually boot an virtual aarch64 board (with console), could you report how you did it. I gave up at the fifth loader or something bl3.3?
Have not managed, I might wait for real hardware...
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
arch/arm/include/asm/config.h +0
-0#define CONFIG_LMB #define CONFIG_SYS_BOOT_RAMDISK_HIGH diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.Sindex dfc2de9..bbf3e41 100644
arch/arm/lib/crt0.S +1
-0@@ -67,9 +67,16 @@ ENTRY(_main) ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ + mov r2, sp sub sp, sp, #GD_SIZE /* allocate one GD above SP */ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
arch/arm/lib/crt0.S +3
-0mov r9, sp /* GD is above SP */ + mov r1, r9 + mov r0, #0 +clr_gd: cmp r1, r2 /* while not at end ofBSS
nitpicking, personal taste I guess: could you hit enter after the
clr_gdlabel?
OK
Regards,
Simon
PATCH v2 3/9 sandbox: Set up global data before board_init_f()
In reply to Simon GlassAt present sandbox defines CONFIG_SYS_GENERIC_GLOBAL_DATA, meaning that the global_data pointer is set up in board_init_f().
If we set up and zero the global data before calling board_init_f() then we don't need to define CONFIG_SYS_GENERIC_GLOBAL_DATA.
Make this change to simplify the init process.
---
Changes in v2: None
arch/sandbox/cpu/start.c | 5 +++++ arch/sandbox/include/asm/config.h | 1 - 2 files changed, 5 insertions(+), 1 deletion(-)
arch/sandbox/cpu/start.c +5 -0
@@ -6,6 +6,7 @@#include <common.h> #include <os.h> #include <asm/getopt.h> +#include <asm/io.h> #include <asm/sections.h> #include <asm/state.h>
@@ -218,6 +219,7 @@ SANDBOX_CMDLINE_OPT_SHORT(terminal, 't', 1,int main (int argc,char *argv[]) {struct sandbox_state *state; +gd_t data;int ret; ret =state_init ();
@@ -236,6 +238,9 @@ int main(int argc, char *argv[])if (state->ram_buf_rm && state->ram_buf_fname)os_unlink (state->ram_buf_fname); +memset (&data,'\0' ,sizeof (data)); + gd = &data; +/* Do pre- and post-relocation init */ board_init_f (0 );
arch/sandbox/include/asm/config.h +0 -1
@@ -7,7 +7,6 @@#ifndef _ASM_CONFIG_H_#define _ASM_CONFIG_H_ -#define CONFIG_SYS_GENERIC_GLOBAL_DATA #define CONFIG_SANDBOX_ARCH /* Used by drivers/spi/sandbox_spi.c and arch/sandbox/include/asm/state.h */
Signature · 1 line
2.0.0.526.g5318336
PATCH v2 4/9 Add a simple malloc() implementation for pre-relocation
In reply to Simon GlassIf we are to have driver model before relocation we need to support some way of calling memory allocation routines.
The standard malloc() is pretty complicated:
1. It uses some BSS memory for its state, and BSS is not available before relocation
2. It supports algorithms for reducing memory fragmentation and improving performace of free(). Before relocation we could happily just not support free().
3. It includes about 4KB of code (Thumb 2) and 1KB of data. However since this has been loaded anyway this is not really a problem.
The simplest way to support pre-relocation malloc() is to reserve an area of memory and allocate it in increasing blocks as needed. This implementation does this.
To enable it, you need to define the size of the malloc() pool as described in the README. It will be located above the pre-relocation stack on supported architectures.
Note that this implementation is only useful on machines which have some memory available before dram_init() is called - this includes those that do no DRAM init (like tegra) and those that do it in SPL (quite a few boards). Enabling driver model preior to relocation for the rest of the boards is left for a later exercise.
---
Changes in v2: None
README | 13 +++++++++++++ common/board_f.c | 12 ++++++++++++ common/board_r.c | 4 ++++ common/dlmalloc.c | 35 +++++++++++++++++++++++++++++++++++ include/asm-generic/global_data.h | 5 +++++ lib/asm-offsets.c | 3 +++ 6 files changed, 72 insertions(+)
README +13 -0
@@ -3716,6 +3716,19 @@ Configuration Settings: - CONFIG_SYS_MALLOC_LEN: Size of DRAM reserved for malloc() use. +- CONFIG_SYS_MALLOC_F_LEN + Size of the malloc() pool for use before relocation. If + this is defined, then a very simple malloc() implementation + will become available before relocation. The address is just + below the global data, and the stack is moved down to make + space. + + This feature allocates regions with increasing addresses + within the region. calloc() is supported, but realloc() + is not available. free() is supported but does nothing. + The memory will be freed (or in fact just forgotton) when + U-Boot relocates itself. + - CONFIG_SYS_BOOTM_LEN: Normally compressed uImages are limited to an uncompressed size of 8 MBytes. If this is not enough,
common/board_f.c +12 -0
@@ -776,6 +776,17 @@ static int mark_bootstage(void)return 0 ; } +static int initf_malloc (void ) +{ +#ifdef CONFIG_SYS_MALLOC_F_LEN +assert (gd->malloc_base);/* Set up by crt0.S */ + gd->malloc_limit = gd->malloc_base +CONFIG_SYS_MALLOC_F_LEN ; + gd->malloc_ptr =0 ; +#endif + +return 0 ; +} + static init_fnc_t init_sequence_f[] = {#ifdef CONFIG_SANDBOX setup_ram_buf,
@@ -833,6 +844,7 @@ static init_fnc_t init_sequence_f[] = { sdram_adjust_866, init_timebase, #endif + initf_malloc, init_baud_rate,/* initialze baudrate settings */ serial_init,/* serial communications setup */ console_init_f, /* stage 1 init of console */
common/board_r.c +4 -0
@@ -259,6 +259,10 @@ static int initr_malloc(void) {ulong malloc_start; +#ifdef CONFIG_SYS_MALLOC_F_LEN +debug ("Pre-reloc malloc() used %#lx bytes (%ld KB)\n" , gd->malloc_ptr, + gd->malloc_ptr /1024 ); +#endif /* The malloc area is immediately below the monitor copy in DRAM */ malloc_start = gd->relocaddr -TOTAL_MALLOC_LEN ; mem_malloc_init((ulong)map_sysmem(malloc_start, TOTAL_MALLOC_LEN),
common/dlmalloc.c +35 -0
@@ -930,6 +930,8 @@ struct mallinfo mALLINFo();#endif /* 0 */ /* Moved to malloc.h */ #include <malloc.h> +#include <asm/io.h> +#ifdef DEBUG #if __STD_Cstatic void malloc_update_mallinfo (void );
@@ -2174,6 +2176,20 @@ Void_t* mALLOc(bytes) size_t bytes;INTERNAL_SIZE_T nb; +#ifdef CONFIG_SYS_MALLOC_F_LEN +if (!(gd->flags &GD_FLG_RELOC )) { +ulong new_ptr; +void *ptr; + + new_ptr = gd->malloc_ptr + bytes; +if (new_ptr > gd->malloc_limit) +panic ("Out of pre-reloc memory" ); + ptr =map_sysmem (gd->malloc_base + gd->malloc_ptr, bytes); + gd->malloc_ptr =ALIGN (new_ptr,sizeof (new_ptr)); +return ptr; + } +#endif +/* check if mem_malloc_init() was run */ if ((mem_malloc_start ==0 ) && (mem_malloc_end ==0 )) {/* not initialized yet */
@@ -2437,6 +2453,12 @@ void fREe(mem) Void_t* mem;mchunkptr fwd;/* misc temp for linking */ int islr;/* track whether merging with last_remainder */ +#ifdef CONFIG_SYS_MALLOC_F_LEN +/* free() is a no-op - all the memory will be freed on relocation */ +if (!(gd->flags &GD_FLG_RELOC )) +return ; +#endif +if (mem ==NULL )/* free(0) has no effect */ return ;
@@ -2588,6 +2610,13 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;/* realloc of null is supposed to be same as malloc */ if (oldmem ==NULL )return mALLOc (bytes); +#ifdef CONFIG_SYS_MALLOC_F_LEN +if (!(gd->flags &GD_FLG_RELOC )) { +/* This is harder to support and should not be needed */ +panic ("pre-reloc realloc() is not supported" ); + } +#endif + newp = oldp =mem2chunk (oldmem); newsize = oldsize =chunksize (oldp);
@@ -2933,6 +2962,12 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;return NULL ; else { +#ifdef CONFIG_SYS_MALLOC_F_LEN +if (!(gd->flags &GD_FLG_RELOC )) { +MALLOC_ZERO (mem, sz); +return mem; + } +#endif p =mem2chunk (mem);/* Two optional cases in which clearing not necessary */
include/asm-generic/global_data.h +5 -0
@@ -85,6 +85,11 @@ typedef struct global_data {#endif unsigned long timebase_h;unsigned long timebase_l; +#ifdef CONFIG_SYS_MALLOC_F_LEN +unsigned long malloc_base;/* base address of early malloc() */ +unsigned long malloc_limit;/* limit address */ +unsigned long malloc_ptr;/* current address */ +#endif struct arch_global_data arch; /* architecture-specific data */ } gd_t;#endif
lib/asm-offsets.c +3 -0
@@ -28,6 +28,9 @@ int main(void)DEFINE (GD_SIZE ,sizeof (struct global_data ));DEFINE (GD_BD , offsetof(struct global_data , bd)); +#ifdef CONFIG_SYS_MALLOC_F_LEN +DEFINE (GD_MALLOC_BASE , offsetof(struct global_data , malloc_base)); +#endif #if defined(CONFIG_ARM )
Signature · 1 line
2.0.0.526.g5318336
PATCH v2 4/9 Add a simple malloc() implementation for pre-relocation
Hi Simon,
Nice to see this being tackled after all the DM discussions I got involved
in a long time ago (in a galaxy far far away...)
I think we can save a few bytes and simplify the code if we define only the
base address and current pointer in global_data.h
#ifdef CONFIG_SYS_MALLOC_F_LEN
unsigned long malloc_base; /* limit address */
unsigned long malloc_ptr; /* current address */
#endif
common/board_f.c static int mark_bootstage(void) · line 785
Quoted 7 lines · Simon Glass
common/board_f.c +7
-0+static int initf_malloc (void ) +{ +#ifdef CONFIG_SYS_MALLOC_F_LEN +assert (gd->malloc_base);/* Set up by crt0.S */ + gd->malloc_limit = gd->malloc_base +CONFIG_SYS_MALLOC_F_LEN ; + gd->malloc_ptr =0 ; +#endif
#ifdef CONFIG_SYS_MALLOC_F_LEN assert(gd->malloc_base); /* Set up by crt0.S */ gd->malloc_ptr= gd->malloc_base;
#endif
Quoted 10 lines
common/board_f.c +4
-0+ +return 0 ; +} +common/board_r.c +0
-0
common/board_r.c static int initr_malloc(void) · line 266
Quoted 8 lines
common/board_r.c +4
-0@@ -259,6 +259,10 @@ static int initr_malloc(void) {ulong malloc_start; +#ifdef CONFIG_SYS_MALLOC_F_LEN +debug ("Pre-reloc malloc() used %#lx bytes (%ld KB)\n" , gd->malloc_ptr, + gd->malloc_ptr /1024 ); +#endif
Use (gd->malloc_ptr - gd->malloc_base) to calculate the size
Quoted 4 lines
common/board_r.c +4
-0+#ifdef CONFIG_SYS_MALLOC_F_LEN +if (!(gd->flags &GD_FLG_RELOC )) { +ulong new_ptr; +void *ptr;
common/board_r.c static int initr_malloc(void)
Quoted 10 lines
common/board_r.c +10
-0+ + new_ptr = gd->malloc_ptr + bytes; +if (new_ptr > gd->malloc_limit) +panic ("Out of pre-reloc memory" ); + ptr =map_sysmem (gd->malloc_base + gd->malloc_ptr, bytes); + gd->malloc_ptr =ALIGN (new_ptr,sizeof (new_ptr)); + return ptr; + } +#endif +
#ifdef CONFIG_SYS_MALLOC_F_LEN
if (!(gd->flags & GD_FLG_RELOC)) {
ulong curr_ptr;
curr_ptr = gd->malloc_ptr;
gd->malloc_ptr = ALIGN(gd->malloc_ptr + bytes,
sizeof(gd->malloc_ptr));
if (gd->malloc_ptr >= (gd->malloc_base + CONFIG_SYS_MALLOC_F_LEN))
panic("Out of pre-reloc memory");
return map_sysmem(curr_ptr, bytes);#endif
Regards,
Graeme
PATCH v2 5/9 arm: Support pre-relocation malloc()
In reply to Simon GlassAdd support for re-relocation malloc() in arm's start-up code.
---
Changes in v2: None
README | 3 +++ arch/arm/lib/crt0.S | 4 ++++ 2 files changed, 7 insertions(+)
README +3 -0
@@ -3729,6 +3729,9 @@ Configuration Settings: The memory will be freed (or in fact just forgotton) when U-Boot relocates itself. + Pre-relocation malloc() is only supported on ARM at present + but is fairly easy to enable for other archs. + - CONFIG_SYS_BOOTM_LEN: Normally compressed uImages are limited to an uncompressed size of 8 MBytes. If this is not enough,
arch/arm/lib/crt0.S +4 -0
@@ -77,6 +77,10 @@ clr_gd: cmp r1, r2 /* while not at end of BSS */ strlo r0, [r1] /* clear 32-bit BSS word */ addlo r1, r1, #4 /* move to next */ blo clr_gd +#if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SPL_BUILD) + sub sp, sp, #CONFIG_SYS_MALLOC_F_LEN + str sp, [r9, #GD_MALLOC_BASE] +#endif mov r0, #0 bl board_init_f
Signature · 1 line
2.0.0.526.g5318336
PATCH v2 6/9 exynos: Enable pre-relocation malloc()
In reply to Simon GlassEnable this feature to support driver model before relocation.
---
Changes in v2: None
include/configs/exynos5-dt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/configs/exynos5-dt.h +2 -2
@@ -63,7 +63,8 @@#define INFORM2_OFFSET 0x808#define INFORM3_OFFSET 0x80c -/* Size of malloc() pool */ +/* Size of malloc() pool before and after relocation */ +#define CONFIG_SYS_MALLOC_F_LEN (1 << 10)#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (4 << 20))/* select serial console configuration */
@@ -158,7 +159,6 @@#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000)#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x3E00000) -#define CONFIG_RD_LVL #define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE
Signature · 1 line
2.0.0.526.g5318336
PATCH v2 7/9 sandbox: Support pre-relocation malloc()
In reply to Simon GlassSet up and zero global data before board_init_f() is called so that we can remove the need for CONFIG_SYS_GENERIC_GLOBAL_DATA.
---
Changes in v2: None
README | 4 ++-- arch/sandbox/cpu/start.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-)
README +2 -2
@@ -3729,8 +3729,8 @@ Configuration Settings: The memory will be freed (or in fact just forgotton) when U-Boot relocates itself. - Pre-relocation malloc() is only supported on ARM at present - but is fairly easy to enable for other archs. + Pre-relocation malloc() is only supported on ARM and sandbox + at present but is fairly easy to enable for other archs. - CONFIG_SYS_BOOTM_LEN: Normally compressed uImages are limited to an
arch/sandbox/cpu/start.c +3 -0
@@ -240,6 +240,9 @@ int main(int argc, char *argv[])memset (&data,'\0' ,sizeof (data)); gd = &data; +#ifdef CONFIG_SYS_MALLOC_F_LEN + gd->malloc_base =CONFIG_MALLOC_F_ADDR ; +#endif /* Do pre- and post-relocation init */ board_init_f (0 );
Signature · 1 line
2.0.0.526.g5318336
PATCH v2 8/9 sandbox: config: Enable pre-relocation malloc()
In reply to Simon GlassEnable this for sandbox so that we will be able to use driver model before relocation.
---
Changes in v2: None
include/configs/sandbox.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
include/configs/sandbox.h +4 -1
@@ -16,6 +16,8 @@#endif +#define CONFIG_MALLOC_F_ADDR 0x0010000 +#define CONFIG_IO_TRACE #define CONFIG_CMD_IOTRACE
@@ -68,8 +70,9 @@#define CONFIG_EFI_PARTITION /* -* Size of malloc() pool, although we don't actually use this yet. +* Size of malloc() pool, before and after relocation */ +#define CONFIG_SYS_MALLOC_F_LEN (1 << 10)#define CONFIG_SYS_MALLOC_LEN (32 << 20)/* 32MB */ #define CONFIG_SYS_HUSH_PARSER
Signature · 1 line
2.0.0.526.g5318336
PATCH v2 9/9 sandbox: Always enable malloc debug
In reply to Simon GlassTun on DEBUG in malloc(). This adds code space and slows things down but for sandbox this is acceptable. We gain the ability to check for memory leaks in tests.
---
Changes in v2: None
common/dlmalloc.c | 4 ++++ 1 file changed, 4 insertions(+)
common/dlmalloc.c +4 -0
@@ -1,5 +1,9 @@#include <common.h> +#ifdef CONFIG_SANDBOX +#define DEBUG +#endif +#if 0 /* Moved to malloc.h */ /* ---------- To make a malloc.h, start cutting here ------------ */
Signature · 1 line
2.0.0.526.g5318336