Example #1
0
File: ubi.c Project: Noltari/u-boot
int ubi_volume_begin_write(char *volume, void *buf, size_t size,
	size_t full_size)
{
	int err = 1;
	int rsvd_bytes = 0;
	struct ubi_volume *vol;

	vol = ubi_find_volume(volume);
	if (vol == NULL)
		return ENODEV;

	rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad);
	if (size > rsvd_bytes) {
		printf("size > volume size! Aborting!\n");
		return EINVAL;
	}

	err = ubi_start_update(ubi, vol, full_size);
	if (err < 0) {
		printf("Cannot start volume update\n");
		return -err;
	}

	return ubi_volume_continue_write(volume, buf, size);
}
Example #2
0
File: ubi.c Project: Noltari/u-boot
static int ubi_volume_continue_write(char *volume, void *buf, size_t size)
{
	int err = 1;
	struct ubi_volume *vol;

	vol = ubi_find_volume(volume);
	if (vol == NULL)
		return ENODEV;

	err = ubi_more_update_data(ubi, vol, buf, size);
	if (err < 0) {
		printf("Couldnt or partially wrote data\n");
		return -err;
	}

	if (err) {
		size = err;

		err = ubi_check_volume(ubi, vol->vol_id);
		if (err < 0)
			return -err;

		if (err) {
			ubi_warn(ubi, "volume %d on UBI device %d is corrupt",
				 vol->vol_id, ubi->ubi_num);
			vol->corrupted = 1;
		}

		vol->checked = 1;
		ubi_gluebi_updated(vol);
	}

	return 0;
}
Example #3
0
static int ubi_remove_vol(char *volume)
{
	int err, reserved_pebs, i;
	struct ubi_volume *vol;

	vol = ubi_find_volume(volume);
	if (vol == NULL)
		return ENODEV;

	if (!strncmp(vol->name, "Factory", 7)) {
		printf("Remove volume %s is inhibited\n", vol->name);
		return EROFS;
	}
	printf("Remove UBI volume %s (id %d)\n", vol->name, vol->vol_id);

	if (ubi->ro_mode) {
		printf("It's read-only mode\n");
		err = EROFS;
		goto out_err;
	}

	err = ubi_change_vtbl_record(ubi, vol->vol_id, NULL);
	if (err) {
		printf("Error changing Vol tabel record err=%x\n", err);
		goto out_err;
	}
	reserved_pebs = vol->reserved_pebs;
	for (i = 0; i < vol->reserved_pebs; i++) {
		err = ubi_eba_unmap_leb(ubi, vol, i);
		if (err)
			goto out_err;
	}

	kfree(vol->eba_tbl);
	ubi->volumes[vol->vol_id]->eba_tbl = NULL;
	ubi->volumes[vol->vol_id] = NULL;

	ubi->rsvd_pebs -= reserved_pebs;
	ubi->avail_pebs += reserved_pebs;
	i = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs;
	if (i > 0) {
		i = ubi->avail_pebs >= i ? i : ubi->avail_pebs;
		ubi->avail_pebs -= i;
		ubi->rsvd_pebs += i;
		ubi->beb_rsvd_pebs += i;
		if (i > 0)
			ubi_msg("reserve more %d PEBs", i);
	}
	ubi->vol_count -= 1;

	return 0;
out_err:
	ubi_err("cannot remove volume %s, error %d", volume, err);
	if (err < 0)
		err = -err;
	return err;
}
Example #4
0
static int ubi_volume_write(char *volume, void *buf, size_t size)
{
	int err = 1;
	int rsvd_bytes = 0;
	struct ubi_volume *vol;

	vol = ubi_find_volume(volume);
	if (vol == NULL)
		return ENODEV;

	rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad);
	if (size < 0 || size > rsvd_bytes) {
		printf("size > volume size! Aborting!\n");
		return EINVAL;
	}

	if (!strncmp(vol->name, "Factory", 7) && (!size || size != rsvd_bytes)) {
		printf("Partial write to volume %s is inhibited\n", vol->name);
		return EROFS;
	}

	err = ubi_start_update(ubi, vol, size);
	if (err < 0) {
		printf("Cannot start volume update\n");
		return -err;
	}

	err = ubi_more_update_data(ubi, vol, buf, size);
	if (err < 0) {
		printf("Couldnt or partially wrote data\n");
		return -err;
	}

	if (err) {
		size = err;

		err = ubi_check_volume(ubi, vol->vol_id);
		if (err < 0)
			return -err;

		if (err) {
			ubi_warn("volume %d on UBI device %d is corrupted",
					vol->vol_id, ubi->ubi_num);
			vol->corrupted = 1;
		}

		vol->checked = 1;
		ubi_gluebi_updated(vol);
	}

	printf("\n0x%x bytes written to volume %s\n", size, volume);

	return 0;
}
Example #5
0
static int ubi_volume_read(char *volume, char *buf, size_t size, size_t offset)
{
	int err, lnum, off, len, tbuf_size;
	void *tbuf;
	unsigned long long tmp;
	struct ubi_volume *vol;
	loff_t offp = 0;

	vol = ubi_find_volume(volume);
	if (vol == NULL)
		return ENODEV;

	offp = offset;
	printf("Read 0x%x bytes from volume [%s] offset 0x%x to %p\n", size, volume, offset, buf);

	if (vol->updating) {
		printf("updating");
		return EBUSY;
	}
	if (vol->upd_marker) {
		printf("damaged volume, update marker is set");
		return EBADF;
	}
	if (offp == vol->used_bytes)
		return 0;

	if (size == 0) {
		printf("No size specified -> Using max size (0x%lx)\n", (long)vol->used_bytes);
		size = vol->used_bytes;
	}

	if (vol->corrupted)
		printf("read from corrupted volume %d", vol->vol_id);
	if (offp + size > vol->used_bytes)
		size = vol->used_bytes - offp;

	tbuf_size = vol->usable_leb_size;
	if (size < tbuf_size)
		tbuf_size = ALIGN(size, ubi->min_io_size);
	tbuf = malloc(tbuf_size);
	if (!tbuf) {
		printf("NO MEM\n");
		return ENOMEM;
	}
	len = size > tbuf_size ? tbuf_size : size;

	tmp = offp;
	off = do_div(tmp, vol->usable_leb_size);
	lnum = tmp;
	do {
		if (off + len >= vol->usable_leb_size)
			len = vol->usable_leb_size - off;

		err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0);
		if (err) {
			printf("read err %x\n", err);
			err = -err;
			break;
		}
		off += len;
		if (off == vol->usable_leb_size) {
			lnum += 1;
			off -= vol->usable_leb_size;
		}

		size -= len;
		offp += len;

		memcpy(buf, tbuf, len);

		buf += len;
		len = size > tbuf_size ? tbuf_size : size;
	} while (size);

	free(tbuf);
	debug("\n0x%x bytes read from volume %s\n", size, volume);

	return err;
}
Example #6
0
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*/
}
Example #7
0
int saveenv(void)
{
#if defined(CONFIG_CMD_UBI)
	int ret;
	char cmd_buf[30];
	ssize_t len;
	size_t size;
	char *res;
	struct mtd_device *dev;
	struct part_info *part;
	char last_ubi_partname[32];
	char last_sb_name[32];
	u8 pnum;
	
	memset(last_ubi_partname, 0, 32);
	memset(last_sb_name, 0, 32);
	ubi_get_part_name(last_ubi_partname);
	ubifs_get_sb_name(last_sb_name);
			
	if(find_dev_and_part(env_partition, &dev, &pnum, &part))
	{
		printf("Partition %s not found!\n", env_partition);
		printf("save env fail\n");
		return 1;
	}
	
	if(!ubi_find_volume(ENV_VOL_NAME))
	{
		sprintf(cmd_buf, "ubi part %s", env_partition);
		if(run_command(cmd_buf, 0) == -1)
			return 1;
	}
	if(!ubi_leb_sz)
		ubi_leb_sz = ubi_get_leb_size();
	
	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);
	if (len < 0) {
		printf("Cannot export environment\n");
		return 1;
	}
	env_new.crc = crc32_env_ubi(0, env_new.data, ENV_SIZE);
	//printf("saveenv crc = %X\n", env_new.crc);

	if(ubi_find_volume(ENV_VOL_NAME))
	{
		printf("Write Env to %X...\n", CONFIG_ENV_OFFSET);
		ret = writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new);
		if (ret) {
			puts("Failed\n");
			return ret;
		}
		printf("Write Backup Env to %X...\n", CONFIG_ENV_OFFSET + ubi_leb_sz);
		ret = writeenv(CONFIG_ENV_OFFSET + ubi_leb_sz, (u_char *) &env_new);
		if (ret)
		{
			puts("Backup Failed\n");
			return ret;
		}
	}
	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 = %0xX\n", ENV_VOL_NAME, env_partition, env_vol_sz);
			return ret;
		}
		ubi_leb_sz = ubi_get_leb_size();

	    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);

		ret = writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new);
        if (ret) {
			puts("Failed\n");
            return ret;
        }
		ret = writeenv(CONFIG_ENV_OFFSET + ubi_leb_sz, (u_char *) &env_new);
		if (ret)
		{
			puts("Backup Failed\n");
			return ret;
		}
	}
	if(last_ubi_partname[0]){
		sprintf(cmd_buf, "ubi part %s", last_ubi_partname);
		if(run_command(cmd_buf, 0) == -1){
			printf("restore ubi part %s failed\n", last_ubi_partname);
			return -1;
		}	
	}
	if(last_sb_name[0]){
		sprintf(cmd_buf, "ubifsmount %s", last_sb_name);
		if(run_command(cmd_buf, 0) == -1){
			printf("remount volume %s failed\n", last_sb_name);
			return -1;
		}
	}
	puts("done\n");
	return ret;
#else
	return 0;
#endif
}