diff options
author | adrian <adrian@FreeBSD.org> | 2016-05-23 03:51:15 +0000 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2016-05-23 03:51:15 +0000 |
commit | 4dc2bab7756669185bd2f3880ab02b0d5c53b32e (patch) | |
tree | e05eaae3e7bd960614dc3301b1c356f227177827 /sys/dev/nvram2env | |
parent | 81c5de57d49f1e89bc0f80838f0c4d0d38ba0ba5 (diff) | |
download | FreeBSD-src-4dc2bab7756669185bd2f3880ab02b0d5c53b32e.zip FreeBSD-src-4dc2bab7756669185bd2f3880ab02b0d5c53b32e.tar.gz |
[nvram2env] fix nvram2env to scan all of memory, not 1/4th
The variable "size" stores number of words (4bytes). But the loop over
memory uses size as number of bytes to scan memory. As result it fetches
only 1/4th of memory.
This patch solves this problem and nvram2env fetches all NVRAM variables.
Test plan:
Pre-requisites: any MIPS board with ASCII-based NVRAM mapped into memory
* Add "device nvram2env" into kernel configuration
* Specify hints: base is mandatory (according to nvram2env(4))
hint.nvram.0.base=0x1c7f8000 (it's valid address for Asus RT-N53 with
flags = 0x4)
* Build & load kernel with bootverbose
Actual result: only part of nvram variables are found
Expected result: all variables are found
Submitted by: Michael Zhilin <mizhka@gmail.com>
Differential Revision: https://reviews.freebsd.org/D6466
Diffstat (limited to 'sys/dev/nvram2env')
-rw-r--r-- | sys/dev/nvram2env/nvram2env.c | 98 |
1 files changed, 52 insertions, 46 deletions
diff --git a/sys/dev/nvram2env/nvram2env.c b/sys/dev/nvram2env/nvram2env.c index 4c0ce1e..a942348 100644 --- a/sys/dev/nvram2env/nvram2env.c +++ b/sys/dev/nvram2env/nvram2env.c @@ -193,10 +193,12 @@ static uint32_t read_4(struct nvram2env_softc * sc, int offset) static int nvram2env_attach(device_t dev) { - struct nvram2env_softc * sc = device_get_softc(dev); - struct nvram * nv; + struct nvram2env_softc *sc; + struct nvram *nv; char *pair, *value, *assign; - uint32_t sig, size, i; + uint32_t sig, size, i, *tmp; + + sc = device_get_softc(dev); if (sc->bst == 0 || sc->addr == 0) return (ENXIO); @@ -217,16 +219,22 @@ nvram2env_attach(device_t dev) if (sig == sc->sig || (sc->flags & NVRAM_FLAGS_UBOOT)) { - /* align and shift size to 32bit size*/ + /* align size to 32bit size*/ size += 3; - size >>= 2; + size &= ~3; - nv = malloc(size<<2, M_DEVBUF, M_WAITOK | M_ZERO); + nv = malloc(size, M_DEVBUF, M_WAITOK | M_ZERO); if (!nv) return (ENOMEM); + /* set tmp pointer to begin of NVRAM */ + tmp = (uint32_t *) nv; - for (i = 0; i < size; i ++) - ((uint32_t *)nv)[i] = read_4(sc, i<<2); + /* use read_4 to swap bytes if it's required */ + for (i = 0; i < size; i += 4) { + *tmp = read_4(sc, i); + tmp++; + } + /* now tmp pointer is end of NVRAM */ if (sc->flags & NVRAM_FLAGS_BROADCOM) { device_printf(dev, "sig = %#x\n", nv->sig); @@ -246,49 +254,47 @@ nvram2env_attach(device_t dev) else pair = (char*)nv+4; - for ( ; - (u_int32_t)pair < ((u_int32_t)nv + size - 4); - pair = pair + strlen(pair) + 1 + strlen(value) + 1 ) { + /* iterate over buffer till end. tmp points to end of NVRAM */ + for ( ; pair < (char*)tmp; + pair += strlen(pair) + strlen(value) + 2 ) { - if (pair && strlen(pair)) { + if (!pair || (strlen(pair) == 0)) + break; -#if 0 - printf("ENV: %s\n", pair); -#endif - /* hint.nvram.0. */ - assign = strchr(pair,'='); - assign[0] = '\0'; - value = assign+1; + /* hint.nvram.0. */ + assign = strchr(pair,'='); + assign[0] = '\0'; + value = assign+1; #if 1 - if (bootverbose) - printf("ENV: %s=%s\n", pair, value); + if (bootverbose) + printf("ENV: %s=%s\n", pair, value); +#else + printf("ENV: %s\n", pair); #endif - kern_setenv(pair, value); - - if (strcasecmp(pair, "WAN_MAC_ADDR") == 0) { - /* Alias for MAC address of eth0 */ - if (bootverbose) - printf("ENV: aliasing " - "WAN_MAC_ADDR to ethaddr" - " = %s\n", value); - kern_setenv("ethaddr", value); - } - else if (strcasecmp(pair, "LAN_MAC_ADDR") == 0){ - /* Alias for MAC address of eth1 */ - if (bootverbose) - printf("ENV: aliasing " - "LAN_MAC_ADDR to eth1addr" - " = %s\n", value); - kern_setenv("eth1addr", value); - } - - if (strcmp(pair, "bootverbose") == 0) - bootverbose = strtoul(value, 0, 0); - if (strcmp(pair, "boothowto" ) == 0) - boothowto = strtoul(value, 0, 0); + kern_setenv(pair, value); + + if (strcasecmp(pair, "WAN_MAC_ADDR") == 0) { + /* Alias for MAC address of eth0 */ + if (bootverbose) + printf("ENV: aliasing " + "WAN_MAC_ADDR to ethaddr" + " = %s\n", value); + kern_setenv("ethaddr", value); } - else - break; + else if (strcasecmp(pair, "LAN_MAC_ADDR") == 0){ + /* Alias for MAC address of eth1 */ + if (bootverbose) + printf("ENV: aliasing " + "LAN_MAC_ADDR to eth1addr" + " = %s\n", value); + kern_setenv("eth1addr", value); + } + + if (strcmp(pair, "bootverbose") == 0) + bootverbose = strtoul(value, 0, 0); + if (strcmp(pair, "boothowto" ) == 0) + boothowto = strtoul(value, 0, 0); + } free(nv, M_DEVBUF); } |