diff mbox

[U-Boot,02/15] arch/arm/lib/bootm.c: Optionally use existing atags

Message ID 1324244051-25756-2-git-send-email-pali.rohar@gmail.com
State Superseded, archived
Headers show

Commit Message

Pali Rohár Dec. 18, 2011, 9:33 p.m. UTC
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:

setenv atagaddr 0x80000100; bootm 0x80008000

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
---
 README               |    2 ++
 arch/arm/lib/bootm.c |   37 ++++++++++++++++++++++++++++++-------
 2 files changed, 32 insertions(+), 7 deletions(-)
diff mbox

Patch

diff --git a/README b/README
index ff72e47..3dd5a97 100644
--- a/README
+++ b/README
@@ -3564,6 +3564,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 802e833..1d76774 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,20 @@  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);
+		printf("Using existing atags at %#x\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 (&params);
 #endif
@@ -147,8 +163,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();