Date: Mon, 23 May 2016 03:51:15 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r300446 - head/sys/dev/nvram2env Message-ID: <201605230351.u4N3pFZF055074@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Mon May 23 03:51:15 2016 New Revision: 300446 URL: https://svnweb.freebsd.org/changeset/base/300446 Log: [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 Modified: head/sys/dev/nvram2env/nvram2env.c Modified: head/sys/dev/nvram2env/nvram2env.c ============================================================================== --- head/sys/dev/nvram2env/nvram2env.c Mon May 23 03:47:44 2016 (r300445) +++ head/sys/dev/nvram2env/nvram2env.c Mon May 23 03:51:15 2016 (r300446) @@ -193,10 +193,12 @@ static uint32_t read_4(struct nvram2env_ 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); + 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); + 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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605230351.u4N3pFZF055074>