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.ro...@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
>       }
>  }
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to