
This patch adapts the bootm command so that it can use an existing atags command set up by a previous bootloader.
Why do you need it?
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:
setenv atagaddr 0x80000100; bootm 0x80008000
Can't you set those atags correctly in uboot?
M
Signed-off-by: Pali Rohár pali.rohar@gmail.com
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 | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/README b/README index 9d713e8..8c3b98a 100644 --- a/README +++ b/README @@ -3584,6 +3584,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 afa0093..8366dd5 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -93,6 +93,14 @@ 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) +#define CONFIG_SETUP_ANY_TAG +#endif
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { bd_t *bd = gd->bd; @@ -125,12 +133,22 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) debug ("## Transferring control to Linux (at address %08lx) ...\n", (ulong) kernel_entry);
-#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
- defined (CONFIG_CMDLINE_TAG) || \
- defined (CONFIG_INITRD_TAG) || \
- defined (CONFIG_SERIAL_TAG) || \
- defined (CONFIG_REVISION_TAG)
- setup_start_tag (bd);
- s = getenv("atagaddr");
- if (s)
bd->bi_boot_params = simple_strtoul(s, NULL, 16);
- if (bd->bi_boot_params) {
printf("Using existing atags at %#lx\n", bd->bi_boot_params);
params = (struct tag *) bd->bi_boot_params;
while (params->hdr.size > 0)
params = tag_next(params);
- } else {
+#ifdef CONFIG_SETUP_ANY_TAG
setup_start_tag(bd);
+#endif
- }
#ifdef CONFIG_SERIAL_TAG setup_serial_tag (¶ms); #endif @@ -147,8 +165,15 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) if (images->rd_start && images->rd_end) setup_initrd_tag (bd, images->rd_start, images->rd_end); #endif
- setup_end_tag(bd);
- if (s) {
if (params->hdr.size > 0)
setup_end_tag(bd);
- } else {
+#ifdef CONFIG_SETUP_ANY_TAG
setup_end_tag(bd);
#endif
}
announce_and_cleanup();