[U-Boot] [PATCH 2/3 V2] common: Implement support for linker-generated arrays

Joe Hershberger joe.hershberger at gmail.com
Sat Sep 29 03:45:17 CEST 2012


Hi Marek,

On Tue, Sep 25, 2012 at 11:11 AM, Marek Vasut <marex at denx.de> wrote:
> This patch adds support for linker-generated array. These arrays
> are a generalization of the U-Boot command declaration approach.
>
> Basically, the idea is to generate an array, where elements of the
> array are statically initialized at compiler time and each element
> is declared separatelly at different place. Such array though can
> later be accessed and used via special accessor.
>
> The actual implementation relies on placing any variable that is to
> represent an element of LG-array into subsection of .u_boot_list
> linker section . Once compiled, it is possible to dump all symbols
> placed in .u_boot_list section and generate appropriate bounds for
> each subsection of the .u_boot_list section. Each such subsection
> this contains .__start and .__end entries at the begining and end
> respecitively.
>
> This allows for simple run-time traversing of the array, since the
> symbols are properly defined.
>
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Joe Hershberger <joe.hershberger at gmail.com>
> Cc: Mike Frysinger <vapier at gentoo.org>
> ---
>  include/linker_lists.h |  124 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 124 insertions(+)
>  create mode 100644 include/linker_lists.h
>
> V2: Don't define the variable twice in ll_entry_declare()
>
> diff --git a/include/linker_lists.h b/include/linker_lists.h
> new file mode 100644
> index 0000000..27ae40b
> --- /dev/null
> +++ b/include/linker_lists.h

[...]

> +/**
> + * ll_entry_count() - Return the number of elements in linker-generated array
> + * _type:      Data type of the entry
> + * _section_u: Subsection of u_boot_list in which this entry is placed
> + *             (with underscores instead of dots)
> + *
> + * This function returns the number of elements of a linker-generated array
> + * placed into subsection of .u_boot_list section specified by _section_u
> + * argument. The result is of an unsigned int type.
> + *
> + * Example of usage:
> + *
> + * int i;
> + * const unsigned int count = ll_entry_count(struct my_sub_cmd, cmd_sub);
> + * struct my_sub_cmd *msc = ll_entry_start(struct my_sub_cmd, cmd_sub);
> + * for (i = 0; i < count; i++) {
> + *     printf("Entry %i, x=%i y=%i\n", i, msc->x, msc->y);
> + *     msc++;
> + * }
> + */
> +#define ll_entry_count(_type, _section_u)                              \
> +       ({                                                              \
> +               extern _type _u_boot_list_##_section_u##__start;        \
> +               extern _type _u_boot_list_##_section_u##__end;          \
> +               unsigned int _ll_result =                               \
> +                       &_u_boot_list_##_section_u##__end -             \
> +                       &_u_boot_list_##_section_u##__start;            \
> +               _ll_result;                                             \
> +       })

While ll_entry_count is great and all, it is more natural to compare
your list pointer to The End (tm) or not.  It would make client code
capable of being cleaner if you also include ll_entry_end() as well.

Thanks,
-Joe


More information about the U-Boot mailing list