[U-Boot] early_malloc outline

Tomas Hlavacek tmshlvck at gmail.com
Thu Aug 2 00:12:35 CEST 2012


Dear Wolfgang,

On Wed, Aug 1, 2012 at 9:09 PM, Wolfgang Denk <wd at denx.de> wrote:

> Hm... I have to admit that I am not really happy about such an
> "explanation".  The statement that "other guys" want something is not
> exactly an explanation of a concept that I can understand, and without
> being able to understand it, I don't buy it.

I wanted to say that this is outcome of an informal discussion with
Marek Vasut, Pavel Hermann and Viktor Krivak, who are working on
different parts of DM (and perhaps I should say that it is our school
project to implement driver model for U-Boot, which is not relevant
information to the current discussion, but it may explain why we
closely cooperate on DM among ourselves). Statements like "I/we want"
were not any notices nor decisions nor whatever final but rather
wishes or ideas (mine or from others). Although we have elaborate
outline of DM and supporting subsystems it is still subject to
changes.

> But why would 2 copies be needed?  I understand then once regular
> malloc() becomes available, you want to make sure all allocations are
> maintained using this mechanism.  But I already wonder how you are
> going to implement this - you will have to update all pointers.  How
> will you find out where these might be?
>
> Assume something like:
>
> item *foo(...)
> {
>         static item *foo_local = malloc(size1);
>         ...
>         return foo_local;
> }
>
> item *bar(..., item **ptr)
> {
>         static item *bar_local = malloc(size2);
>         ...
>         *ptr = bar_local;
>         return bar_local;
> }
>
> void some_function(...)
> {
>         item *x, *y;
>         ...
>         x = bar(..., &y);
>         baz(y);
>         ...
> }
>
> How will you later know which variables store the values from the early
> malloc calls, and how will you access these for proper relocation?
>

Each early heap (assuming we can have more than one contiguous early
heaps as Graeme suggested) has a pointer to the beginning (and it is
valid only before relocation and before caches are enabled). I can
memcpy() the used part of the early heap somewhere else and preserve
the original heap beginning pointer (I have in mind preservation of
the pointers in GD; it is implementation detail indeed, but I would
rather note this in order make sure that I am not working with false
assumption about possibility of preserving pointers like that). Then I
can compute copied_heap_address = original_address +
(copied_heap_begin - original_heap_begin).

I have to admit, that I am not familiar enough with plans for early DM
tree to know where are we going to hold tree root pointer. I think
that it could be eventually placed in GD. To your example:

#define TRANSLATE_ADDR(old_heap,new_heap,pointer) (pointer + new_heap
- old_heap)

void some_function(...)
{
        item *x, *y;
        ...
        x = bar(..., &y);
        baz(y);

	gd->x = x;
	gd->y = y;

	...

	memcpy(NEW_HEAP_ADDR, gd->old_heap_addr, heap_used_bytes);
}

void later(...)
{
	item *x = TRANSLATE_ADDR(old_heap_addr,NEW_HEAP_ADDR,gd->x);
	item *y = TRANSLATE_ADDR(old_heap_addr,NEW_HEAP_ADDR,gd->y);
}


Perhaps I can try to rewrite it into more real-life example:

void board_init_f(...)
{
	...
	struct dm_tree_node *root = malloc(sizeof(struct dm_tree_item));
	/* early_malloc() has been used in fact. */
	root->left_descendant = malloc(sizeof(struct dm_tree_item));
	gd->dm_tree_root = root;
	...

	memcpy(NEW_HEAP_ADDR,gd->early_heap,gd->early_heap_used_bytes);

	relocate_code(...);
}

void board_init_r(gd_t *id, ulong dest_addr)
{
	...
	struct dm_tree_node *root_new = TRANSLATE_ADDR(gd->early_heap,
		NEW_HEAP_ADDR, gd->root);
	root_new->left_descendant = TRANSLATE_ADDR(gd->early_heap,
		NEW_HEAP_ADDR, root_new->left_descendant);

	/* And I can rectify all the pointers in the tree just like that.
	   It should not be expensive because the tree is really
	   small at this point - 5 items max.
	   The problem is, that the root_new does not point to memory
	   obtained from dlmalloc. How could we possibily solve this? Our current
	   idea is to perform one extra round of malloc() and copying of the tree...
	*/
	...
}

Thank you for your help,
Tomas

-- 
Tomáš Hlaváček <tmshlvck at gmail.com>


More information about the U-Boot mailing list