nand_spl: read environment early, when booting from NAND using nand_spl
authorGuennadi Liakhovetski <lg@denx.de>
Mon, 18 May 2009 14:07:22 +0000 (16:07 +0200)
committerScott Wood <scottwood@freescale.com>
Tue, 7 Jul 2009 22:58:07 +0000 (17:58 -0500)
Currently, when booting from NAND using nand_spl, in the beginning the default
environment is used until later in boot process the dynamic environment is read
out. This way environment variables that must be interpreted early, like the
baudrate or "silent", cannot be modified dynamically and remain at their
default values. Fix this problem by reading out main and redundand (if used)
copies of the environment in the nand_spl code.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Scott Wood <scottwood@freescale.com>
README
common/env_nand.c
include/configs/smdk6400.h
nand_spl/nand_boot.c

diff --git a/README b/README
index 0e843372a31e1ca6d67e6316ff2c83b4572f8d48..de700bd747559895d82f51dbe34aac6435d26a01 100644 (file)
--- a/README
+++ b/README
@@ -2428,6 +2428,12 @@ to save the current settings.
        to a block boundary, and CONFIG_ENV_SIZE must be a multiple of
        the NAND devices block size.
 
+- CONFIG_NAND_ENV_DST
+
+       Defines address in RAM to which the nand_spl code should copy the
+       environment. If redundant environment is used, it will be copied to
+       CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE.
+
 - CONFIG_SYS_SPI_INIT_OFFSET
 
        Defines offset to the initial SPI buffer area in DPRAM. The
index 21bce2530669089ee25549c86a2b0401ddde6e9a..90a1c454720ae4fe5ad483cf78cddbba5b4194ec 100644 (file)
@@ -68,9 +68,11 @@ extern int default_environment_size;
 char * env_name_spec = "NAND";
 
 
-#ifdef ENV_IS_EMBEDDED
+#if defined(ENV_IS_EMBEDDED)
 extern uchar environment[];
 env_t *env_ptr = (env_t *)(&environment[0]);
+#elif defined(CONFIG_NAND_ENV_DST)
+env_t *env_ptr = (env_t *)CONFIG_NAND_ENV_DST;
 #else /* ! ENV_IS_EMBEDDED */
 env_t *env_ptr = 0;
 #endif /* ENV_IS_EMBEDDED */
@@ -102,23 +104,33 @@ uchar env_get_char_spec (int index)
  */
 int env_init(void)
 {
-#if defined(ENV_IS_EMBEDDED)
+#if defined(ENV_IS_EMBEDDED) || defined(CONFIG_NAND_ENV_DST)
        int crc1_ok = 0, crc2_ok = 0;
-       env_t *tmp_env1, *tmp_env2;
+       env_t *tmp_env1;
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+       env_t *tmp_env2;
 
-       tmp_env1 = env_ptr;
        tmp_env2 = (env_t *)((ulong)env_ptr + CONFIG_ENV_SIZE);
+       crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);
+#endif
+
+       tmp_env1 = env_ptr;
 
        crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc);
-       crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);
 
-       if (!crc1_ok && !crc2_ok)
+       if (!crc1_ok && !crc2_ok) {
+               gd->env_addr  = 0;
                gd->env_valid = 0;
-       else if(crc1_ok && !crc2_ok)
+
+               return 0;
+       } else if (crc1_ok && !crc2_ok) {
                gd->env_valid = 1;
-       else if(!crc1_ok && crc2_ok)
+       }
+#ifdef CONFIG_ENV_OFFSET_REDUND
+       else if (!crc1_ok && crc2_ok) {
                gd->env_valid = 2;
-       else {
+       else {
                /* both ok - check serial */
                if(tmp_env1->flags == 255 && tmp_env2->flags == 0)
                        gd->env_valid = 2;
@@ -132,14 +144,19 @@ int env_init(void)
                        gd->env_valid = 1;
        }
 
+       if (gd->env_valid == 2)
+               env_ptr = tmp_env2;
+       else
+#endif
        if (gd->env_valid == 1)
                env_ptr = tmp_env1;
-       else if (gd->env_valid == 2)
-               env_ptr = tmp_env2;
-#else /* ENV_IS_EMBEDDED */
+
+       gd->env_addr = (ulong)env_ptr->data;
+
+#else /* ENV_IS_EMBEDDED || CONFIG_NAND_ENV_DST */
        gd->env_addr  = (ulong)&default_environment[0];
        gd->env_valid = 1;
-#endif /* ENV_IS_EMBEDDED */
+#endif /* ENV_IS_EMBEDDED || CONFIG_NAND_ENV_DST */
 
        return (0);
 }
index cac58cf3256897d6cc012a2febac6b09aa65403d..018f576ef29b2132fac0270fca1ea855e2cc3f20 100644 (file)
 /* total memory available to uboot */
 #define CONFIG_SYS_UBOOT_SIZE          (1024 * 1024)
 
+/* Put environment copies after the end of U-Boot owned RAM */
+#define CONFIG_NAND_ENV_DST    (CONFIG_SYS_UBOOT_BASE + CONFIG_SYS_UBOOT_SIZE)
+
 #ifdef CONFIG_ENABLE_MMU
 #define CONFIG_SYS_MAPPED_RAM_BASE     0xc0000000
 #define CONFIG_BOOTCOMMAND     "nand read 0xc0018000 0x60000 0x1c0000;" \
index c7eadad1b9aa9335c5dcc4e8d7ba1db4881daa7f..be2e69c287c741b5efa570e84565a37c0c717808 100644 (file)
@@ -246,6 +246,16 @@ void nand_boot(void)
        ret = nand_load(&nand_info, CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE,
                        (uchar *)CONFIG_SYS_NAND_U_BOOT_DST);
 
+#ifdef CONFIG_NAND_ENV_DST
+       nand_load(&nand_info, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
+                 (uchar *)CONFIG_NAND_ENV_DST);
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+       nand_load(&nand_info, CONFIG_ENV_OFFSET_REDUND, CONFIG_ENV_SIZE,
+                 (uchar *)CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE);
+#endif
+#endif
+
        if (nand_chip.select_chip)
                nand_chip.select_chip(&nand_info, -1);