Provide a place where the loader can patch the binary, such that it executes a
command string from RAM. We use this for automated installs, where we can thus
use the same u-boot binary for all stages.

include/configs/neo1973.h: new option CFG_PREBOOT_OVERRIDE to allow setting of
  the preboot command in memory
cpu/arm920t/start.S: added variable "preboot_override" at known location
  (_start+0x40)
common/main.c (main_loop): if preboot_override is set, execute the command
  string found there
common/env_common.c (env_relocate):  if preboot_override is set, always use the
  default environment

- Werner Almesberger <werner@openmoko.org>

Index: u-boot/cpu/arm920t/start.S
===================================================================
--- u-boot.orig/cpu/arm920t/start.S
+++ u-boot/cpu/arm920t/start.S
@@ -77,6 +77,14 @@ _fiq:			.word fiq
  *************************************************************************
  */
 
+
+/* Must follow the .balign above, so we get a well-known address ! */
+#ifdef CFG_PREBOOT_OVERRIDE
+.globl	preboot_override
+preboot_override:
+	.word	0
+#endif
+
 #ifdef CONFIG_S3C2410_NAND_BOOT
 .globl	booted_from_nand
 booted_from_nand:
Index: u-boot/include/configs/neo1973_gta01.h
===================================================================
--- u-boot.orig/include/configs/neo1973_gta01.h
+++ u-boot/include/configs/neo1973_gta01.h
@@ -207,6 +207,7 @@
 #define	CFG_ENV_IS_IN_NAND	1
 #define CFG_ENV_SIZE		0x4000		/* 16k Total Size of Environment Sector */
 #define CFG_ENV_OFFSET_OOB    1               /* Location of ENV stored in block 0 OOB */
+#define	CFG_PREBOOT_OVERRIDE	1	/* allow preboot from memory */
 
 #define NAND_MAX_CHIPS		1
 #define CFG_NAND_BASE		0x4e000000
Index: u-boot/common/main.c
===================================================================
--- u-boot.orig/common/main.c
+++ u-boot/common/main.c
@@ -85,6 +85,11 @@ int do_mdm_init = 0;
 extern void mdm_init(void); /* defined in board.c */
 #endif
 
+#ifdef CFG_PREBOOT_OVERRIDE
+extern char *preboot_override;
+#endif
+
+
 /***************************************************************************
  * Watch for 'delay' seconds for autoboot stop or autoboot delay string.
  * returns: 0 -  no key string, allow autoboot
@@ -306,8 +311,8 @@ void main_loop (void)
 	char *s;
 	int bootdelay;
 #endif
-#ifdef CONFIG_PREBOOT
-	char *p;
+#if defined(CONFIG_PREBOOT) || defined(CFG_PREBOOT_OVERRIDE)
+	char *p = NULL;
 #endif
 #ifdef CONFIG_BOOTCOUNT_LIMIT
 	unsigned long bootcount = 0;
@@ -364,8 +369,23 @@ void main_loop (void)
 	install_auto_complete();
 #endif
 
+#if defined(CONFIG_PREBOOT) || defined(CFG_PREBOOT_OVERRIDE)
 #ifdef CONFIG_PREBOOT
-	if ((p = getenv ("preboot")) != NULL) {
+	p = getenv ("preboot");
+#endif
+#ifdef CFG_PREBOOT_OVERRIDE
+	if (preboot_override) {
+		/* for convenience, preboot_override may end in \n, not \0 */
+		p = strchr(preboot_override, '\n');
+		if (p)
+			*p = 0;
+		/* make sure we can overwrite the load area if we want to */
+		p = strdup(preboot_override);
+		/* clean the image in case we want to flash it */
+		preboot_override = NULL;
+	}
+#endif /* CFG_PREBOOT_OVERRIDE */
+	if (p) {
 # ifdef CONFIG_AUTOBOOT_KEYED
 		int prev = disable_ctrlc(1);	/* disable Control C checking */
 # endif
@@ -381,7 +401,7 @@ void main_loop (void)
 		disable_ctrlc(prev);	/* restore Control C checking */
 # endif
 	}
-#endif /* CONFIG_PREBOOT */
+#endif /* CONFIG_PREBOOT || CFG_PREBOOT_OVERRIDE */
 
 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
 	s = getenv ("bootdelay");
Index: u-boot/common/env_common.c
===================================================================
--- u-boot.orig/common/env_common.c
+++ u-boot/common/env_common.c
@@ -37,6 +37,10 @@
 # define SHOW_BOOT_PROGRESS(arg)
 #endif
 
+#ifdef CFG_PREBOOT_OVERRIDE
+extern char *preboot_override;
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef CONFIG_AMIGAONEG3SE
@@ -234,7 +238,14 @@ void env_relocate (void)
 		puts ("*** Warning - bad CRC, using default environment\n\n");
 		SHOW_BOOT_PROGRESS (-1);
 #endif
+	}
+
+#ifdef CFG_PREBOOT_OVERRIDE
+	if (preboot_override)
+		gd->env_valid = 0;
+#endif
 
+	if (gd->env_valid == 0) {
 		if (sizeof(default_environment) > ENV_SIZE)
 		{
 			puts ("*** Error - default environment is too large\n\n");
