diff options
-rw-r--r-- | configure.in | 11 | ||||
-rw-r--r-- | src/u_boot.c | 179 |
2 files changed, 163 insertions, 27 deletions
diff --git a/configure.in b/configure.in index 8fdc9ef..d023d38 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ AC_INIT([src/u_boot.c]) -AM_INIT_AUTOMAKE([u-boot], [0.0.1]) +AM_INIT_AUTOMAKE([u-boot], [0.0.2]) AM_CONFIG_HEADER([config.h]) AC_PROG_CC @@ -18,9 +18,12 @@ AC_CHECK_LIB([z], [crc32], [], AC_MSG_ERROR([libz is required])) AC_DEFINE([DEBUG], 0, [set to 1 to enable debug]) AC_DEFINE([MTD_ENV1], "/dev/mtd3", [set to the first u-boot env mtd]) AC_DEFINE([MTD_ENV2], "/dev/mtd4", [set to the second (redundant) u-boot env mtd]) -AC_DEFINE([MTD_SIZE], 0x20000, [size of u-boot env mtd]) -AC_DEFINE([DEFAULT_ENV], ["bootargs=mem=64M console=ttyS0,115200 root=/dev/mtdblock8 ro rootfstype=jffs2\0" "bootcmd=nboot.jffs2 ${loadaddr} 0 ${kernel_addr}; bootm ${loadaddr}\0" "bootdelay=3\0" "baudrate=115200\0" "ethaddr=00:D0:A0:02:0D:E1\0" "ipaddr=192.168.2.1\0" "serverip=192.168.2.2\0" "netmask=255.255.255.0\0" "hostname=AT91SAM9G20\0" "loadaddr=0x21400000\0" "kernel_addr=0x000A0000\0" "\0"] -, [default env if corrupt]) + +AC_DEFINE([MAC_PATH],["/sys/devices/platform/mts-io/mac-eth"], [MAC_PATH for defining ethaddr= in boot environment]) + +AC_DEFINE_UNQUOTED([DEFAULT_ENV], + [$(cat ../DEFAULT_ENV.cfg | tr -d '\n')], + [default environment values]) AC_OUTPUT([Makefile src/Makefile]) 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); |