[U-Boot] Early malloc() summary

Graeme Russ
2012-08-09T00:55:06Z

Hi All,

While the need for early malloc() came about from the driver model and
the desire to make drivers usable before relocation, I think we can all
agree that its scope may well not be limited to use by drivers. A few
examples I can think of the top of my head include:

- pre-console buffer
- bd struct
- early env

(not that I'm advocating any of these get modified to use early malloc,
they are simply presented as examples outside the driver model)

So we all know the intent:
- have the ability to allocate memory prior to relocation

And we all know the problems:
1. Preserving allocation references accross relocation
2. Any given driver may need to use early malloc() on some boards but not
on others

He is my (hopefully final) design input on this...

1. Create a register_malloc_reloc_func() function
2. Wrap malloc() with a (gd->flags & GD_FLG_RELOC) test
3. Call reloc_early_heap() sometime between mem_malloc_init() and
enables_caches()
4. Set gd->flags |= GD_FLG_RELOC after calling reloc_early_heap()

register_malloc_reloc_func()
============================
This function registers a relocation helper function. The helper functions
will be called by reloc_early_heap(). The purpose of each helper function
is to relocate data structures from the early heap to the final heap.

int register_malloc_reloc_func(function *helper)
{
/*
* Check is already relocated - If so, no need to register the function
* as all calls to malloc() will be using the final heap anyway
*/
if (gd->flags & GD_FLG_RELOC)
return 0;

/* Add this function to the list of relocation helpers */
...blah blah blah...

return 0;
}

NOTE: It is not strictly neccessary to use register_malloc_reloc_func() if
you have some other hook in the relocation process that will call helper
functions. Yes, I'm looking at you Driver Model :). For Driver Model, maybe
the driver core will register a single function which will step through all
the driver cores and call their relocation functions. It really does not
matter (although it may if things need to be relocated in a particular
order)

malloc()
========
void *malloc(size_t size)
{
if (gd->flags & GD_FLG_RELOC)
return dl_malloc(size);

return early_malloc(size);
}

reloc_early_heap()
==================
int reloc_early_heap()
{
/* Call each funtion previously registered */
... blah blah blah ...

return 0;
}

Now there has been some discussion about the performance penalties of the
relocation process, copying the early heap twice, etc, etc.

My thought: Keep it simple for now. Worry about optimising it to death
later.

So there are my thoughts.<EOL>

<EOF>

Regards,

Graeme