[U-Boot] [PATCH v2 01/11] arm: Optionally use existing atags in bootm.c

Marek Vasut
2012-04-28T22:15:23Z

Dear Pali Roh?r,

> This patch adapts the bootm command so that it can use an existing atags
> command set up by a previous bootloader. If the environment variable
> "atagaddr" is unset, bootm behaves as normal. If "atagaddr" is set, bootm
> will use atags address from environment variable and also append new boot
> args (if specified in u-boot). For example, if a previous boot loader
> already set up the atags struct at 0x80000100:

Won't it be easier to create a preprocessing function that'd fill gd properly,
so uboot can generate the atags through standard means then?

>
> setenv atagaddr 0x80000100; bootm 0x80008000
>
> Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
> ---
> Changes since v1:
> - Rebased on u-boot master
>
> Changes since original version:
> - Added info to README file
> - Added local define CONFIG_SETUP_ANY_TAG
> - Fixed compile warning
> - Fixed commit message
> - Check if atagaddr is not NULL
>
> README | 2 ++
> arch/arm/lib/bootm.c | 60
> ++++++++++++++++++++++++++++++++------------------ 2 files changed, 40
> insertions(+), 22 deletions(-)
>
> diff --git a/README b/README
> index 43074cf..60ad9c2 100644
> --- a/README
> +++ b/README
> @@ -3687,6 +3687,8 @@ Some configuration options can be set using
> Environment Variables.
>
> List of environment variables (most likely not complete):
>
> + atagaddr - bootm will use ATAGs struct from specified address (arm only)
> +
> baudrate - see CONFIG_BAUDRATE
>
> bootdelay - see CONFIG_BOOTDELAY
> diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
> index 599547d..0f3c97b 100644
> --- a/arch/arm/lib/bootm.c
> +++ b/arch/arm/lib/bootm.c
> @@ -42,6 +42,10 @@ DECLARE_GLOBAL_DATA_PTR;
> defined(CONFIG_INITRD_TAG) || \
> defined(CONFIG_SERIAL_TAG) || \
> defined(CONFIG_REVISION_TAG)
> + #define CONFIG_SETUP_ANY_TAG
> +#endif
> +
> +#ifdef CONFIG_SETUP_ANY_TAG
> static struct tag *params;
> #endif
>
> @@ -106,11 +110,7 @@ static void announce_and_cleanup(void)
> cleanup_before_linux();
> }
>
> -#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
> - defined(CONFIG_CMDLINE_TAG) || \
> - defined(CONFIG_INITRD_TAG) || \
> - defined(CONFIG_SERIAL_TAG) || \
> - defined(CONFIG_REVISION_TAG)
> +#ifdef CONFIG_SETUP_ANY_TAG
> static void setup_start_tag (bd_t *bd)
> {
> params = (struct tag *)bd->bi_boot_params;
> @@ -217,11 +217,7 @@ void setup_revision_tag(struct tag **in_params)
> }
> #endif
>
> -#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
> - defined(CONFIG_CMDLINE_TAG) || \
> - defined(CONFIG_INITRD_TAG) || \
> - defined(CONFIG_SERIAL_TAG) || \
> - defined(CONFIG_REVISION_TAG)
> +#ifdef CONFIG_SETUP_ANY_TAG
> static void setup_end_tag(bd_t *bd)
> {
> params->hdr.tag = ATAG_NONE;
> @@ -280,13 +276,23 @@ static void boot_prep_linux(bootm_headers_t *images)
> } else
> #endif
> {
> -#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
> - defined(CONFIG_CMDLINE_TAG) || \
> - defined(CONFIG_INITRD_TAG) || \
> - defined(CONFIG_SERIAL_TAG) || \
> - defined(CONFIG_REVISION_TAG)
> + char *atagaddr = getenv("atagaddr");
> debug("using: ATAGS\n");
> - setup_start_tag(gd->bd);
> +
> + if (atagaddr)
> + gd->bd->bi_boot_params = simple_strtoul(atagaddr, NULL,
16);
> +
> + if (gd->bd->bi_boot_params) {
> + printf("Using existing atags at %#lx\n", gd->bd-
>bi_boot_params);
> +
> + params = (struct tag *) gd->bd->bi_boot_params;
> + while (params->hdr.size > 0)
> + params = tag_next(params);
> + } else {
> +#ifdef CONFIG_SETUP_ANY_TAG
> + setup_start_tag(gd->bd);
> +#endif
> + }
> #ifdef CONFIG_SERIAL_TAG
> setup_serial_tag(&params);
> #endif
> @@ -297,18 +303,28 @@ static void boot_prep_linux(bootm_headers_t *images)
> setup_revision_tag(&params);
> #endif
> #ifdef CONFIG_SETUP_MEMORY_TAGS
> - setup_memory_tags(gd->bd);
> + if (!atagaddr)
> + setup_memory_tags(gd->bd);
> #endif
> #ifdef CONFIG_INITRD_TAG
> if (images->rd_start && images->rd_end)
> setup_initrd_tag(gd->bd, images->rd_start,
> images->rd_end);
> #endif
> - setup_end_tag(gd->bd);
> -#else /* all tags */
> - printf("FDT and ATAGS support not compiled in - hanging\n");
> - hang();
> -#endif /* all tags */
> + if (atagaddr) {
> + if (params->hdr.size > 0)
> + setup_end_tag(gd->bd);
> + } else {
> +#ifdef CONFIG_SETUP_ANY_TAG
> + setup_end_tag(gd->bd);
> +#endif
> + }
> +#ifndef CONFIG_SETUP_ANY_TAG
> + if (!atagaddr) {
> + printf("FDT and ATAGS support not compiled in -
hanging\n");
> + hang();
> + }
> +#endif
> }
> }