コード例 #1
0
ファイル: env_nand.c プロジェクト: Aorjoa/bootloader
/*
 * 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 */
}
コード例 #2
0
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;
}
コード例 #3
0
ファイル: cmd_nand.c プロジェクト: tojoevan/u-boot
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;
}
コード例 #4
0
ファイル: env_ubi.c プロジェクト: Scorpio92/mstar6a918
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*/
}