/* * The legacy NAND code saved the environment in the first NAND * device i.e., nand_dev_desc + 0. This is also the behaviour using * the new NAND code. */ void env_relocate_spec (void) { #if !defined(ENV_IS_EMBEDDED) int ret; char buf[CONFIG_ENV_SIZE]; #if defined(CONFIG_ENV_OFFSET_OOB) ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset); /* * If unable to read environment offset from NAND OOB then fall through * to the normal environment reading code below */ if (!ret) { printf("Found Environment offset in OOB..\n"); } else { set_default_env("!no env offset in OOB"); return; } #endif ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf); if (ret) { set_default_env("!readenv() failed"); return; } env_import(buf, 1); #endif /* ! ENV_IS_EMBEDDED */ }
int do_nand_env_oob(cmd_tbl_t *cmdtp, nand_info_t *nand, int argc, char * const argv[]) { int ret; uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)]; char *cmd = argv[1]; if (!strcmp(cmd, "get")) { ret = get_nand_env_oob(nand, &nand_env_oob_offset); if (ret) return 1; printf("0x%08lx\n", nand_env_oob_offset); } else if (!strcmp(cmd, "set")) { ulong addr; size_t dummy_size; struct mtd_oob_ops ops; if (argc < 3) goto usage; if (arg_off_size(argc - 2, argv + 2, nand, &addr, &dummy_size) < 0) { printf("Offset or partition name expected\n"); return 1; } if (nand->oobavail < ENV_OFFSET_SIZE) { printf("Insufficient available OOB bytes:\n" "%d OOB bytes available but %d required for " "env.oob support\n", nand->oobavail, ENV_OFFSET_SIZE); return 1; } if ((addr & (nand->erasesize - 1)) != 0) { printf("Environment offset must be block-aligned\n"); return 1; } ops.datbuf = NULL; ops.mode = MTD_OOB_AUTO; ops.ooboffs = 0; ops.ooblen = ENV_OFFSET_SIZE; ops.oobbuf = (void *) oob_buf; oob_buf[0] = ENV_OOB_MARKER; oob_buf[1] = addr / nand->erasesize; ret = nand->write_oob(nand, ENV_OFFSET_SIZE, &ops); if (ret) { printf("Error writing OOB block 0\n"); return ret; } ret = get_nand_env_oob(nand, &nand_env_oob_offset); if (ret) { printf("Error reading env offset in OOB\n"); return ret; } if (addr != nand_env_oob_offset) { printf("Verification of env offset in OOB failed: " "0x%08lx expected but got 0x%08lx\n", addr, nand_env_oob_offset); return 1; } } else { goto usage; } return ret; usage: cmd_usage(cmdtp); return 1; }
int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[]) { int ret; uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)]; nand_info_t *nand = &nand_info[0]; char *cmd = argv[1]; if (CONFIG_SYS_MAX_NAND_DEVICE == 0 || !nand->name) { puts("no devices available\n"); return 1; } set_dev(0); if (!strcmp(cmd, "get")) { ret = get_nand_env_oob(nand, &nand_env_oob_offset); if (ret) return 1; printf("0x%08lx\n", nand_env_oob_offset); } else if (!strcmp(cmd, "set")) { loff_t addr; loff_t maxsize; struct mtd_oob_ops ops; int idx = 0; if (argc < 3) goto usage; /* We don't care about size, or maxsize. */ if (arg_off(argv[2], &idx, &addr, &maxsize, &maxsize)) { puts("Offset or partition name expected\n"); return 1; } if (idx != 0) { puts("Partition not on first NAND device\n"); return 1; } if (nand->oobavail < ENV_OFFSET_SIZE) { printf("Insufficient available OOB bytes:\n" "%d OOB bytes available but %d required for " "env.oob support\n", nand->oobavail, ENV_OFFSET_SIZE); return 1; } if ((addr & (nand->erasesize - 1)) != 0) { printf("Environment offset must be block-aligned\n"); return 1; } ops.datbuf = NULL; ops.mode = MTD_OOB_AUTO; ops.ooboffs = 0; ops.ooblen = ENV_OFFSET_SIZE; ops.oobbuf = (void *) oob_buf; oob_buf[0] = ENV_OOB_MARKER; oob_buf[1] = addr / nand->erasesize; ret = nand->write_oob(nand, ENV_OFFSET_SIZE, &ops); if (ret) { printf("Error writing OOB block 0\n"); return ret; } ret = get_nand_env_oob(nand, &nand_env_oob_offset); if (ret) { printf("Error reading env offset in OOB\n"); return ret; } if (addr != nand_env_oob_offset) { printf("Verification of env offset in OOB failed: " "0x%08llx expected but got 0x%08lx\n", (unsigned long long)addr, nand_env_oob_offset); return 1; } } else { goto usage; } return ret; usage: return CMD_RET_USAGE; }
void env_relocate_spec (void) { #if defined(CONFIG_CMD_UBI) #if !defined(ENV_IS_EMBEDDED) int ret, i, readfrombackup; char cmd_buf[30]; struct mtd_device *dev; struct part_info *part; uint32_t crc; size_t size; env_t *ep; u8 pnum; #if defined(CONFIG_ENV_OFFSET_OOB) ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset); /* * If unable to read environment offset from NAND OOB then fall through * to the normal environment reading code below */ if (!ret) { printf("Found Environment offset in OOB..\n"); } else { set_default_env("!no env offset in OOB"); return; } #endif //get mtdpart string from pni set_default_env("!set default for mtdparts"); #if (ENABLE_MODULE_NAND_FLASH == 1) drvNAND_GetMtdParts(mtdstr); #endif #if (ENABLE_MODULE_SPI_NAND_FLASH == 1) MDrv_SPINAND_GetMtdParts(mtdstr); #endif setenv("mtdparts", mtdstr); setenv("mtdids", IdsStr); mtdparts_init(); if(find_dev_and_part(env_partition, &dev, &pnum, &part)) { printf("Partition %s not found!\n", env_partition); printf("read env fail\n"); return; } if(!ubi_find_volume(ENV_VOL_NAME)) { sprintf(cmd_buf, "ubi part %s", env_partition); if(run_command(cmd_buf, 0) == -1) return; } if(!ubi_leb_sz) ubi_leb_sz = ubi_get_leb_size(); if(!env_vol_sz) env_vol_sz = (ubi_get_avai_peb() - 1) * ubi_leb_sz; if(cfg_env_offset == 0) { MsApiChunkHeader_GetValue(CH_UBOOT_ENVIRONMENT_ROM_OFFSET,&cfg_env_offset); ubi_get_volume_size(ENV_VOL_NAME, &size); cfg_env_offset = size - (cfg_env_offset*ubi_leb_sz); } //find ENV volume readfrombackup = 0; if(ubi_find_volume(ENV_VOL_NAME)) { for(i = 0 ;i < CONFIG_ENV_BLOCK_NUM; i ++) { ret = readenv(CONFIG_ENV_OFFSET + i * ubi_leb_sz, (u_char *)gbuf); if (ret) { if(i < (CONFIG_ENV_BLOCK_NUM - 1)) { printf("Read ENV fail, Read Backup ENV\n"); readfrombackup = 1; continue; } else { printf("Read Backup ENV Failed\n"); return; } } ep = (env_t*) gbuf; memcpy(&crc, &ep->crc, sizeof(crc)); // printf("Calc crc %X, Read crc %X\n", crc32(0, ep->data, ENV_SIZE), crc); if(crc32_env_ubi(0, ep->data, ENV_SIZE) == crc) { env_import(gbuf, 0); break; } else { if(i < (CONFIG_ENV_BLOCK_NUM - 1)) { printf("Read ENV crc error, Read Backup ENV\n"); readfrombackup = 1; } else { printf("Read Backup ENV crc error\n"); return; } } } } else { printf("Found no %s Volume\n Create %s volume\n", ENV_VOL_NAME, ENV_VOL_NAME); ret = ubi_create_vol(ENV_VOL_NAME, env_vol_sz, 1); if(ret) printf("create %s volume in %s partition fail with size = 0x%X\n", ENV_VOL_NAME, env_partition, env_vol_sz); ubi_leb_sz = ubi_get_leb_size(); ubi_get_volume_size(ENV_VOL_NAME, &size); MsApiChunkHeader_GetValue(CH_UBOOT_ENVIRONMENT_ROM_OFFSET,&cfg_env_offset); cfg_env_offset = size - (cfg_env_offset*ubi_leb_sz); } //restore data from backup if(readfrombackup == 1) { ret = saveenv(); if(ret) printf("restore data fail\n"); } #endif /* ! ENV_IS_EMBEDDED */ #else set_default_env("!set default for NAND program"); #endif /* ! CONFIG_CMD_UBI*/ }