+#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
+void env_relocate_spec(void)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
+ ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
+ int crc1_ok = 0, crc2_ok = 0;
+ env_t *ep, *tmp_env1, *tmp_env2;
+
+ tmp_env1 = (env_t *)env1_buf;
+ tmp_env2 = (env_t *)env2_buf;
+
+ if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
+ printf("\n** Cannot find mtd partition \"%s\"\n",
+ CONFIG_ENV_UBI_PART);
+ set_default_env(NULL);
+ return;
+ }
+
+ if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
+ CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to read env from %s:%s **\n",
+ CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
+ }
+
+ if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, (void *)tmp_env2,
+ CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to read redundant env from %s:%s **\n",
+ CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
+ }
+
+ 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) {
+ set_default_env("!bad CRC");
+ return;
+ } else if (crc1_ok && !crc2_ok) {
+ gd->env_valid = 1;
+ } else if (!crc1_ok && crc2_ok) {
+ gd->env_valid = 2;
+ } else {
+ /* both ok - check serial */
+ if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
+ gd->env_valid = 2;
+ else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
+ gd->env_valid = 1;
+ else if (tmp_env1->flags > tmp_env2->flags)
+ gd->env_valid = 1;
+ else if (tmp_env2->flags > tmp_env1->flags)
+ gd->env_valid = 2;
+ else /* flags are equal - almost impossible */
+ gd->env_valid = 1;
+ }
+
+ if (gd->env_valid == 1)
+ ep = tmp_env1;
+ else
+ ep = tmp_env2;
+
+ env_flags = ep->flags;
+ env_import((char *)ep, 0);
+}
+#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */