Commit 785881f775252940185e10fbb2d5299c9ffa6bce
Committed by
Tom Rini
1 parent
2b74433f36
Exists in
master
and in
53 other branches
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
README
... | ... | @@ -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 |
common/env_ubi.c
... | ... | @@ -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 |
tools/env/fw_env.c
... | ... | @@ -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; |