Commit 785881f775252940185e10fbb2d5299c9ffa6bce

Authored by Joe Hershberger
Committed by Tom Rini
1 parent 2b74433f36

env: Add redundant env support to UBI env

Allow the user to specify two UBI volumes to use for the environment

Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>

Showing 4 changed files with 129 additions and 0 deletions Side-by-side Diff

... ... @@ -3563,6 +3563,12 @@
3563 3563 Define this to the name of the volume that you want to store the
3564 3564 environment in.
3565 3565  
  3566 + - CONFIG_ENV_UBI_VOLUME_REDUND:
  3567 +
  3568 + Define this to the name of another volume to store a second copy of
  3569 + the environment in. This will enable redundant environments in UBI.
  3570 + It is assumed that both volumes are in the same MTD partition.
  3571 +
3566 3572 - CONFIG_UBI_SILENCE_MSG
3567 3573 - CONFIG_UBIFS_SILENCE_MSG
3568 3574  
... ... @@ -47,6 +47,9 @@
47 47 }
48 48  
49 49 #ifdef CONFIG_CMD_SAVEENV
  50 +#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  51 +static unsigned char env_flags;
  52 +
50 53 int saveenv(void)
51 54 {
52 55 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
53 56  
... ... @@ -67,7 +70,56 @@
67 70 }
68 71  
69 72 env_new->crc = crc32(0, env_new->data, ENV_SIZE);
  73 + env_new->flags = ++env_flags; /* increase the serial */
70 74  
  75 + if (gd->env_valid == 1) {
  76 + puts("Writing to redundant UBI... ");
  77 + if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
  78 + (void *)env_new, CONFIG_ENV_SIZE)) {
  79 + printf("\n** Unable to write env to %s:%s **\n",
  80 + CONFIG_ENV_UBI_PART,
  81 + CONFIG_ENV_UBI_VOLUME_REDUND);
  82 + return 1;
  83 + }
  84 + } else {
  85 + puts("Writing to UBI... ");
  86 + if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
  87 + (void *)env_new, CONFIG_ENV_SIZE)) {
  88 + printf("\n** Unable to write env to %s:%s **\n",
  89 + CONFIG_ENV_UBI_PART,
  90 + CONFIG_ENV_UBI_VOLUME);
  91 + return 1;
  92 + }
  93 + }
  94 +
  95 + puts("done\n");
  96 +
  97 + gd->env_valid = gd->env_valid == 2 ? 1 : 2;
  98 +
  99 + return 0;
  100 +}
  101 +#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
  102 +int saveenv(void)
  103 +{
  104 + ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  105 + ssize_t len;
  106 + char *res;
  107 +
  108 + res = (char *)&env_new->data;
  109 + len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
  110 + if (len < 0) {
  111 + error("Cannot export environment: errno = %d\n", errno);
  112 + return 1;
  113 + }
  114 +
  115 + if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
  116 + printf("\n** Cannot find mtd partition \"%s\"\n",
  117 + CONFIG_ENV_UBI_PART);
  118 + return 1;
  119 + }
  120 +
  121 + env_new->crc = crc32(0, env_new->data, ENV_SIZE);
  122 +
71 123 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
72 124 CONFIG_ENV_SIZE)) {
73 125 printf("\n** Unable to write env to %s:%s **\n",
74 126  
75 127  
... ... @@ -78,10 +130,74 @@
78 130 puts("done\n");
79 131 return 0;
80 132 }
  133 +#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
81 134 #endif /* CONFIG_CMD_SAVEENV */
82 135  
  136 +#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
83 137 void env_relocate_spec(void)
84 138 {
  139 + ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
  140 + ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
  141 + int crc1_ok = 0, crc2_ok = 0;
  142 + env_t *ep, *tmp_env1, *tmp_env2;
  143 +
  144 + tmp_env1 = (env_t *)env1_buf;
  145 + tmp_env2 = (env_t *)env2_buf;
  146 +
  147 + if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
  148 + printf("\n** Cannot find mtd partition \"%s\"\n",
  149 + CONFIG_ENV_UBI_PART);
  150 + set_default_env(NULL);
  151 + return;
  152 + }
  153 +
  154 + if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
  155 + CONFIG_ENV_SIZE)) {
  156 + printf("\n** Unable to read env from %s:%s **\n",
  157 + CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
  158 + }
  159 +
  160 + if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, (void *)tmp_env2,
  161 + CONFIG_ENV_SIZE)) {
  162 + printf("\n** Unable to read redundant env from %s:%s **\n",
  163 + CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
  164 + }
  165 +
  166 + crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc;
  167 + crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc;
  168 +
  169 + if (!crc1_ok && !crc2_ok) {
  170 + set_default_env("!bad CRC");
  171 + return;
  172 + } else if (crc1_ok && !crc2_ok) {
  173 + gd->env_valid = 1;
  174 + } else if (!crc1_ok && crc2_ok) {
  175 + gd->env_valid = 2;
  176 + } else {
  177 + /* both ok - check serial */
  178 + if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
  179 + gd->env_valid = 2;
  180 + else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
  181 + gd->env_valid = 1;
  182 + else if (tmp_env1->flags > tmp_env2->flags)
  183 + gd->env_valid = 1;
  184 + else if (tmp_env2->flags > tmp_env1->flags)
  185 + gd->env_valid = 2;
  186 + else /* flags are equal - almost impossible */
  187 + gd->env_valid = 1;
  188 + }
  189 +
  190 + if (gd->env_valid == 1)
  191 + ep = tmp_env1;
  192 + else
  193 + ep = tmp_env2;
  194 +
  195 + env_flags = ep->flags;
  196 + env_import((char *)ep, 0);
  197 +}
  198 +#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
  199 +void env_relocate_spec(void)
  200 +{
85 201 ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
86 202  
87 203 if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
... ... @@ -101,4 +217,5 @@
101 217  
102 218 env_import(buf, 1);
103 219 }
  220 +#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
include/environment.h
... ... @@ -103,6 +103,9 @@
103 103 # ifndef CONFIG_ENV_UBI_VOLUME
104 104 # error "Need to define CONFIG_ENV_UBI_VOLUME when using CONFIG_ENV_IS_IN_UBI"
105 105 # endif
  106 +# if defined(CONFIG_ENV_UBI_VOLUME_REDUND)
  107 +# define CONFIG_SYS_REDUNDAND_ENVIRONMENT
  108 +# endif
106 109 # ifndef CONFIG_ENV_SIZE
107 110 # error "Need to define CONFIG_ENV_SIZE when using CONFIG_ENV_IS_IN_UBI"
108 111 # endif
... ... @@ -1149,6 +1149,9 @@
1149 1149 } else if (DEVTYPE(dev_current) == MTD_DATAFLASH &&
1150 1150 DEVTYPE(!dev_current) == MTD_DATAFLASH) {
1151 1151 environment.flag_scheme = FLAG_BOOLEAN;
  1152 + } else if (DEVTYPE(dev_current) == MTD_UBIVOLUME &&
  1153 + DEVTYPE(!dev_current) == MTD_UBIVOLUME) {
  1154 + environment.flag_scheme = FLAG_INCREMENTAL;
1152 1155 } else {
1153 1156 fprintf (stderr, "Incompatible flash types!\n");
1154 1157 return -1;