1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
|
commit 4099235d80474025bb86b75caddbb6c25f573d9b
Author: John Klug <john.klug@multitech.com>
Date: Wed Apr 12 12:50:36 2017 -0500
Parameters for defaults come mostly from u-boot header files
diff --git a/src/u_boot.c b/src/u_boot.c
index e240475..9480471 100644
--- a/src/u_boot.c
+++ b/src/u_boot.c
@@ -33,8 +33,16 @@
#include <fcntl.h>
#include <zlib.h>
-
+#include <u-boot/config.h>
#include "u_boot.h"
+#include "mtd_erase_all.h"
+
+#define XMK_STR(x) #x
+#define MK_STR(x) XMK_STR(x)
+
+#define DUMMY_MAC "00:00:00:00:00:00"
+
+#define EMPTY_CRC 0xf9137807
static int tokcmp(const char *cmd, const char *pattern) {
int len = strlen(cmd);
@@ -46,8 +54,10 @@ static int tokcmp(const char *cmd, const char *pattern) {
}
#define ENV_HEADER_SIZE (sizeof(uint32_t) + sizeof(uint8_t))
-#define ENV_DATA_SIZE (MTD_SIZE - ENV_HEADER_SIZE)
+#define ENV_DATA_SIZE (CONFIG_ENV_SIZE - ENV_HEADER_SIZE)
+#define DO_WRITE_ENV 1
+#define SKIP_WRITE_ENV 0
struct environment {
uint32_t crc;
uint8_t flags;
@@ -64,6 +74,8 @@ static int write_uboot_env(const char *device, struct environment *env)
error("mtd_erase_all %s failed", device);
return -1;
}
+ if(env == NULL)
+ return 0;
fd = open(device, O_WRONLY);
if (fd < 0) {
@@ -144,7 +156,7 @@ static int cmd_printenv(struct environment *env, int argc, char **argv)
return true;
}
-static int cmd_setenv(struct environment *env, int argc, char **argv)
+static int cmd_setenv(struct environment *env, int argc, char **argv, int do_write)
{
int tmp;
char *var;
@@ -166,7 +178,7 @@ static int cmd_setenv(struct environment *env, int argc, char **argv)
var = env->data;
while (*var) {
if (!strncmp(var, name, name_len) && var[name_len] == '=') {
- dbg("found variable (%s) at %lld", var, (long long int) var);
+ dbg("found variable (%s) at %p", var, var);
cp = next_var(var);
while (*cp) {
@@ -213,18 +225,19 @@ static int cmd_setenv(struct environment *env, int argc, char **argv)
}
env->crc = crc32(0, (uint8_t *) env->data, sizeof(env->data));
- dbg("crc: 0x%08X", env->crc);
+ dbg("Calculated crc (to be stored): 0x%08X", env->crc);
env->flags = 0;
- tmp = write_uboot_env(MTD_ENV1, env);
- if (tmp < 0) {
- dbg("write_uboot_env %s failed with %d", MTD_ENV1, tmp);
- }
- tmp = write_uboot_env(MTD_ENV2, env);
- if (tmp < 0) {
- dbg("write_uboot_env %s failed with %d", MTD_ENV1, tmp);
+ if(do_write == DO_WRITE_ENV) {
+ tmp = write_uboot_env(MTD_ENV1, env);
+ if (tmp < 0) {
+ dbg("write_uboot_env %s failed with %d", MTD_ENV1, tmp);
+ }
+ tmp = write_uboot_env(MTD_ENV2, env);
+ if (tmp < 0) {
+ dbg("write_uboot_env %s failed with %d", MTD_ENV1, tmp);
+ }
}
-
return true;
}
@@ -238,7 +251,7 @@ static void print_version(const char *name) {
}
static void usage(FILE *out) {
- fprintf(out, "Usage: u-boot { printenv [ name ] | setenv name [ value ] }\n");
+ fprintf(out, "Usage: u-boot { printenv [ name ] | setenv name [ value ] | clearenv }\n");
fprintf(out, "\n");
}
@@ -252,6 +265,7 @@ int main(int argc, char *argv[]) {
struct environment *env2;
uint32_t crc1_ok;
uint32_t crc2_ok;
+ uint32_t crc1_calc, crc2_calc;
if (argc <= 1) {
usage(stderr);
@@ -301,12 +315,18 @@ int main(int argc, char *argv[]) {
error("read_uboot_env failed");
return 1;
}
- dbg("env1 crc: 0x%08X", env1->crc);
+ dbg("env1 stored crc: 0x%08X", env1->crc);
dbg("env1 flags: %d", env1->flags);
- if (crc32(0, (uint8_t *) env1->data, sizeof(env1->data)) == env1->crc) {
+ crc1_calc = crc32(0, (uint8_t *) env1->data, sizeof(env1->data));
+ if (crc1_calc == env1->crc) {
crc1_ok = 1;
} else {
- error("crc does not match on primary env");
+ dbg("env1 stored crc 0x%x, calculated crc 0x%x",env1->crc,crc1_calc);
+ if ((env1->crc != 0xffffffff) || (crc1_calc != EMPTY_CRC))
+ error("crc does not match on env1");
+ else
+ dbg("uninitialized env1");
+
crc1_ok = 0;
}
@@ -315,20 +335,130 @@ int main(int argc, char *argv[]) {
error("read_uboot_env failed");
return 1;
}
- dbg("env2 crc: 0x%08X", env2->crc);
+ dbg("env2 stored crc: 0x%08X", env2->crc);
dbg("env2 flags: %d", env2->flags);
- if (crc32(0, (uint8_t *) env2->data, sizeof(env2->data)) == env2->crc) {
+ crc2_calc = crc32(0, (uint8_t *) env2->data, sizeof(env2->data));
+ if (crc2_calc == env2->crc) {
crc2_ok = 1;
} else {
- error("crc does not match on redundant env");
+ dbg("env2 stored crc 0x%x, calculated crc 0x%x",env2->crc,crc2_calc);
+ if ((env2->crc != 0xffffffff) || (crc2_calc != EMPTY_CRC) )
+ error("crc does not match on env2");
+ else
+ dbg("uninitialized env2");
crc2_ok = 0;
}
- if (!crc1_ok && !crc2_ok) {
- error("both environments are bad: loading DEFAULT_ENV");
+ if (!crc1_ok && !crc2_ok && (env1->crc == 0xffffffff) &&
+ (env2->crc == 0xffffffff) && (crc1_calc == EMPTY_CRC) &&
+ (crc2_calc == EMPTY_CRC) ) {
+ int mp_fd = open(MAC_PATH, O_RDONLY);
+ int len,retval;
+ char *p;
+ char *genarg[2];
+ char number[128];
+
+ fputs("WARNING: Flash is in initial state, so use defaults\n",stderr);
env = env1;
env->flags = 0;
memcpy(env->data, DEFAULT_ENV, sizeof(DEFAULT_ENV));
+ /* Now need to find the MAC address */
+ if (mp_fd == -1) {
+ perror("Cannot open: " MAC_PATH);
+ exit(1);
+ }
+
+ len = sizeof DUMMY_MAC - 1; /* remove null from count */
+ p = malloc(len+1);
+ retval = read(mp_fd,p,len);
+ dbg("Mac read of %d returned %d",len,retval);
+ if(retval != len) {
+ if(retval == -1) {
+ perror("Failed to read: " MAC_PATH);
+ exit(1);
+ }
+ if (retval != len) {
+ fprintf(stderr,"%s: Only read %d characters of %d for the MAC address\n",
+ MAC_PATH,retval,len);
+ fprintf(stderr,"%s: Read %*.*s\n",MAC_PATH,retval,retval,p);
+ exit(1);
+ }
+ }
+ p[len] = 0;
+ genarg[0] = "ethaddr";
+ genarg[1] = p;
+ if (cmd_setenv(env,2,genarg,SKIP_WRITE_ENV) == false)
+ exit(1);
+ free(p);
+ genarg[1] = number;
+
+#ifdef CONFIG_BAUDRATE
+ genarg[0] = "baudrate";
+ sprintf(number,"%lld",(long long)(CONFIG_BAUDRATE));
+ if (cmd_setenv(env,2,genarg,SKIP_WRITE_ENV) == false)
+ exit(1);
+#endif
+#ifdef CONFIG_BOOTDELAY
+ genarg[0] = "bootdelay";
+ sprintf(number,"%lld",(long long)(CONFIG_BOOTDELAY));
+ if (cmd_setenv(env,2,genarg,SKIP_WRITE_ENV) == false)
+ exit(1);
+#endif
+#ifdef CONFIG_LOADADDR
+ genarg[0] = "loadaddr";
+ sprintf(number,"0x%llx",(long long)(CONFIG_LOADADDR));
+ if (cmd_setenv(env,2,genarg,SKIP_WRITE_ENV) == false)
+ exit(1);
+#endif
+#ifdef CONFIG_HOSTNAME
+ genarg[0] = "hostname";
+ genarg[1] = MK_STR(CONFIG_HOSTNAME);
+ if (cmd_setenv(env,2,genarg,SKIP_WRITE_ENV) == false)
+ exit(1);
+#endif
+#ifdef CONFIG_IPADDR
+ genarg[0] = "ipaddr";
+ genarg[1] = MK_STR(CONFIG_IPADDR);
+ if (cmd_setenv(env,2,genarg,SKIP_WRITE_ENV) == false)
+ exit(1);
+#endif
+#ifdef CONFIG_SERVERIP
+ genarg[0] = "serverip";
+ genarg[1] = MK_STR(CONFIG_SERVERIP);
+ if (cmd_setenv(env,2,genarg,SKIP_WRITE_ENV) == false)
+ exit(1);
+#endif
+#ifdef CONFIG_NETMASK
+ genarg[0] = "netmask";
+ genarg[1] = MK_STR(CONFIG_NETMASK);
+ if (cmd_setenv(env,2,genarg,SKIP_WRITE_ENV) == false)
+ exit(1);
+#endif
+#ifdef CONFIG_EXTRA_ENV_SETTINGS
+ p = env->data;
+ while((p = next_var(p)) && *p);
+ len = (p - env->data);
+ if (len + sizeof CONFIG_EXTRA_ENV_SETTINGS < ENV_DATA_SIZE)
+ memcpy(env->data + len,CONFIG_EXTRA_ENV_SETTINGS,sizeof CONFIG_EXTRA_ENV_SETTINGS);
+ else
+ fprintf(stderr,"Default memory settings overflow. Current size %d, CONFIG_EXTRA_ENV_SETTINGS size %d, Maximum %d\n",
+ len,sizeof CONFIG_EXTRA_ENV_SETTINGS,ENV_DATA_SIZE);
+#endif
+#ifdef CONFIG_BOOTARGS
+ genarg[0] = "bootargs";
+ genarg[1] = CONFIG_BOOTARGS;
+ if (cmd_setenv(env,2,genarg,SKIP_WRITE_ENV) == false)
+ exit(1);
+#endif
+#ifdef CONFIG_BOOTCOMMAND
+ genarg[0] = "bootcmd";
+ genarg[1] = CONFIG_BOOTCOMMAND;
+ if (cmd_setenv(env,2,genarg,SKIP_WRITE_ENV) == false)
+ exit(1);
+#endif
+ } else if (!crc1_ok && !crc2_ok) {
+ error("both environments are bad: not loading DEFAULT_ENV");
+ exit(1);
} else if (crc1_ok && !crc2_ok) {
env = env1;
} else if (!crc1_ok && crc2_ok) {
@@ -352,7 +482,10 @@ int main(int argc, char *argv[]) {
if (!tokcmp(cmd, "printenv")) {
err = cmd_printenv(env, argc, argv);
} else if (!tokcmp(cmd, "setenv")) {
- err = cmd_setenv(env, argc, argv);
+ err = cmd_setenv(env, argc, argv, DO_WRITE_ENV);
+ } else if (!tokcmp(cmd, "clearenv")) {
+ (void)write_uboot_env(MTD_ENV1, NULL);
+ (void)write_uboot_env(MTD_ENV2, NULL);
} else {
usage(stderr);
exit(1);
|