static int do_info(nvram_handle_t *nvram) { nvram_header_t *hdr = nvram_header(nvram); /* CRC8 over the last 11 bytes of the header and data bytes */ uint8_t crc = hndcrc8((unsigned char *) &hdr[0] + NVRAM_CRC_START_POSITION, hdr->len - NVRAM_CRC_START_POSITION, 0xff); /* Show info */ printf("Magic: 0x%08X\n", hdr->magic); printf("Length: 0x%08X\n", hdr->len); printf("Offset: 0x%08X\n", nvram->offset); printf("CRC8: 0x%02X (calculated: 0x%02X)\n", hdr->crc_ver_init & 0xFF, crc); printf("Version: 0x%02X\n", (hdr->crc_ver_init >> 8) & 0xFF); printf("SDRAM init: 0x%04X\n", (hdr->crc_ver_init >> 16) & 0xFFFF); printf("SDRAM config: 0x%04X\n", hdr->config_refresh & 0xFFFF); printf("SDRAM refresh: 0x%04X\n", (hdr->config_refresh >> 16) & 0xFFFF); printf("NCDL values: 0x%08X\n\n", hdr->config_ncdl); printf("%i bytes used / %i bytes available (%.2f%%)\n", hdr->len, NVRAM_SPACE - hdr->len, (100.00 / (double)NVRAM_SPACE) * (double)hdr->len); return 0; }
/* (Re)initialize the hash table. */ static int _nvram_rehash(nvram_handle_t *h) { nvram_header_t *header = nvram_header(h); char buf[] = "0xXXXXXXXX", *name, *value, *eq; /* (Re)initialize hash table */ _nvram_free(h); /* Parse and set "name=value\0 ... \0\0" */ name = (char *) &header[1]; for (; *name; name = value + strlen(value) + 1) { if (!(eq = strchr(name, '='))) break; *eq = '\0'; value = eq + 1; nvram_set(h, name, value); *eq = '='; } /* Set special SDRAM parameters */ if (!nvram_get(h, "sdram_init")) { sprintf(buf, "0x%04X", (uint16_t)(header->crc_ver_init >> 16)); nvram_set(h, "sdram_init", buf); }
/* Open NVRAM and obtain a handle. */ nvram_handle_t * _nvram_open(const char *file, int rdonly) { int fd; char *mtd = NULL; nvram_handle_t *h; nvram_header_t *header = NULL; if( (fd = open(file ? file : mtd, O_RDWR)) > -1 ) { char *mmap_area = (char *) mmap( NULL, nvram_erase_size, PROT_READ | PROT_WRITE, ( rdonly == NVRAM_RO ) ? MAP_PRIVATE : MAP_SHARED, fd, 0); if( mmap_area != MAP_FAILED ) { if((h = (nvram_handle_t *) malloc(sizeof(nvram_handle_t))) != NULL) { h->fd = fd; h->mmap = mmap_area; h->length = nvram_erase_size; header = nvram_header(h); _nvram_rehash(h); return h; } } } return NULL; }
int nvram_commit(nvram_handle_t *h) { nvram_header_t *header = nvram_header(h); char *init, *config, *refresh, *ncdl; char *ptr, *end; int i; nvram_tuple_t *t; nvram_header_t tmp; uint8_t crc; /* Regenerate header */ header->magic = NVRAM_MAGIC; header->crc_ver_init = (NVRAM_VERSION << 8); if (!(init = hash_nvram_get(h, "sdram_init")) || !(config = hash_nvram_get(h, "sdram_config")) || !(refresh = hash_nvram_get(h, "sdram_refresh")) || !(ncdl = hash_nvram_get(h, "sdram_ncdl"))) { header->crc_ver_init |= SDRAM_INIT << 16; header->config_refresh = SDRAM_CONFIG; header->config_refresh |= SDRAM_REFRESH << 16; header->config_ncdl = 0; } else { header->crc_ver_init |= (strtoul(init, NULL, 0) & 0xffff) << 16; header->config_refresh = strtoul(config, NULL, 0) & 0xffff; header->config_refresh |= (strtoul(refresh, NULL, 0) & 0xffff) << 16; header->config_ncdl = strtoul(ncdl, NULL, 0); } /* Clear data area */ ptr = (char *) header + sizeof(nvram_header_t); memset(ptr, 0xFF, NVRAM_SPACE - sizeof(nvram_header_t)); memset(&tmp, 0, sizeof(nvram_header_t)); /* Leave space for a double NUL at the end */ end = (char *) header + NVRAM_SPACE - 2; /* Write out all tuples */ for (i = 0; i < NVRAM_ARRAYSIZE(h->nvram_hash); i++) { for (t = h->nvram_hash[i]; t; t = t->next) { if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end) break; ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1; } } /* End with a double NULL and pad to 4 bytes */ *ptr = '\0'; ptr++; if( (int)ptr % 4 ) memset(ptr, 0, 4 - ((int)ptr % 4)); ptr++; /* Set new length */ header->len = NVRAM_ROUNDUP(ptr - (char *) header, 4); /* Little-endian CRC8 over the last 11 bytes of the header */ tmp.crc_ver_init = header->crc_ver_init; tmp.config_refresh = header->config_refresh; tmp.config_ncdl = header->config_ncdl; crc = hndcrc8((unsigned char *) &tmp + NVRAM_CRC_START_POSITION, sizeof(nvram_header_t) - NVRAM_CRC_START_POSITION, 0xff); /* Continue CRC8 over data bytes */ crc = hndcrc8((unsigned char *) &header[0] + sizeof(nvram_header_t), header->len - sizeof(nvram_header_t), crc); /* Set new CRC8 */ header->crc_ver_init |= crc; /* Write out */ msync(h->mmap, h->length, MS_SYNC); fsync(h->fd); /* Reinitialize hash table */ return _nvram_rehash(h); }