Exemple #1
0
unsigned long  sunxi_flash_part_read(int dev_num, unsigned long start, lbaint_t blkcnt, void *dst)
{
	uint offset;

	offset = sunxi_partition_get_offset(dev_num);
	if(!offset)
	{
		printf("sunxi flash error: cant get part %d offset\n", dev_num);

		return 0;
	}
	start += offset;
#ifdef DEBUG
    printf("nand try to read from %x, length %x block\n", (int )start, (int )blkcnt);
#endif
#ifdef DEBUG
    int ret;

    ret = sunxi_flash_read((uint)start, (uint )blkcnt, dst);
    printf("read result = %d\n", ret);

	return ret;
#else
    return sunxi_flash_read((uint)start, (uint )blkcnt, dst);
#endif
}
Exemple #2
0
static void flash_env_relocate_spec(int workmode)
{
#if !defined(ENV_IS_EMBEDDED)
	char buf[CONFIG_ENV_SIZE];
	u32 start;

	if((workmode & WORK_MODE_PRODUCT) && (!(workmode & WORK_MODE_UPDATE)))
	{
		flash_use_efex_env();
	}
	else
	{
		start = sunxi_partition_get_offset_byname(CONFIG_SUNXI_ENV_PARTITION);
		if(!start){
			printf("fail to find part named %s\n", CONFIG_SUNXI_ENV_PARTITION);
			use_default();
			return;
		}

		if(!sunxi_flash_read(start, CONFIG_ENV_SIZE/512, buf))
		{
			use_default();
			return;
		}
		env_import(buf, 1);
	}

#endif
}
Exemple #3
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
uint toc1_item_read_rootcertif(void * p_dest, u32 buff_len)
{
	u32 to_read_blk_start = 0;
	u32 to_read_blk_sectors = 0;
	s32 ret = 0;
	struct sbrom_toc1_item_info *p_toc_item = toc1_item;

	if( buff_len  < p_toc_item->data_len )
	{
		printf("PANIC : toc1_item_read_rootcertif() error --1--,buff error\n");

		return 0;
	}

	to_read_blk_start   = (p_toc_item->data_offset)>>9;
	to_read_blk_sectors = (p_toc_item->data_len + 0x1ff)>>9;

	ret = sunxi_flash_read(to_read_blk_start, to_read_blk_sectors, p_dest);
	if(ret != to_read_blk_sectors)
	{
		printf("PANIC: toc1_item_read_rootcertif() error --2--, read error\n");

		return 0;
	}

	return ret*512;
}
/*
************************************************************************************************************
*
*                                             function
*
*    name          :	usb-recovery 写入misc分区对应的命令
*
*    parmeters     :
*
*    return        :
*
*    note          :	[email protected]
*
*
************************************************************************************************************
*/
int write_usb_recovery_to_misc(void)
{
	u32   misc_offset = 0;
	char  misc_args[2048];
	static struct bootloader_message *misc_message;
	int ret;

	memset(misc_args, 0x0, 2048);
	misc_message = (struct bootloader_message *)misc_args;

	misc_offset = sunxi_partition_get_offset_byname("misc");
	if(!misc_offset)
	{
		printf("no misc partition\n");
		return 0;
	}
	ret = sunxi_flash_read(misc_offset, 2048/512, misc_args);
	if (!ret)
	{
		printf("error: read misc partition\n");
		return 0;
	}
	strcpy(misc_message->command, "usb-recovery");
	sunxi_flash_write(misc_offset, 2048/512, misc_args);
	return 0;
}
Exemple #5
0
int android_misc_flash_check(void) {

    loff_t misc_offset = 0, misc_size = 0;
    size_t count = sizeof(misc_message);

    sunxi_partition_get_info_byname("misc", &misc_offset, &misc_size);
    if(!misc_offset || !misc_size) {
        sunxi_partition_get_info_byname("MISC", &misc_offset, &misc_size);
        if(!misc_offset || !misc_size) {
            puts("no misc partition is found\n");
            return 0;
        }
    }

    uint blk_start, blk_cnt, n;
    //struct mmc *mmc = find_mmc_device(mmc_card_no);

    //blk_start = ALIGN(misc_offset, mmc->read_bl_len) / mmc->read_bl_len;
    //blk_cnt   = ALIGN(count, mmc->read_bl_len) / mmc->read_bl_len;

    //n = mmc->block_dev.block_read(mmc_card_no, blk_start,
    //	blk_cnt, (uchar *)&misc_message);
    sunxi_flash_read(misc_offset, count, (void *)&misc_message);

#ifdef DEBUG
    printf("misc.command  : %s\n", misc_message.command);
    printf("misc.status   : %s\n", misc_message.status);
    printf("misc.recovery : %s\n", misc_message.recovery);
#endif
    if(!strcmp(misc_message.command, "boot-recovery")) {
        /* there is a recovery command */
        printf("find boot recovery\n");
        setenv("bootcmd", "run setargs boot_recovery");
        puts("Recovery detected, will boot recovery\n");
        /* android recovery will clean the misc */
    }

    if(!strcmp(misc_message.command, "boot-fastboot")) {
        /* there is a fastboot command */
        setenv("bootcmd", "run setargs boot_fastboot");
        puts("Fastboot detected, will enter fastboot\n");
        /* clean the misc partition ourself */
        memset(&misc_message, 0, sizeof(misc_message));
        sunxi_flash_write(misc_offset, count, (void *)&misc_message);
        //n = mmc->block_dev.block_write(mmc_card_no, blk_start,
        //	blk_cnt, (uchar *)&misc_message);

    }

    return 0;
}
Exemple #6
0
int sunxi_flash_read_bootlogo(u32 start, int buf, const char *part_name)
{
	int ret;
	u32 rblock;
	u32 start_block = start;
	void *addr;
	
	addr = (void *)buf;
	start_block = sunxi_partition_get_offset_byname((const char *)part_name);
	rblock = sunxi_partition_get_size_byname((const char *)part_name);
    ret = sunxi_flash_read(start_block, rblock, (void *)addr);
	if(ret != 0) {
		printf("read bootlogo partition successful,start_block=0x%x,rblock=0x%x ,ret=%d\n",start_block,rblock,ret);
	}
	else {
		printf("read bootlogo partition fail,start_block=0x%x,rblock=0x%x ,ret=%d\n",start_block,rblock,ret);
	}

	return ret;
}
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
int check_android_misc(void)
{
	int   mode;
	int	  pmu_value;
	u32   misc_offset = 0;
	char  misc_args[2048];
	char  misc_fill[2048];
	char  boot_commond[128];
	static struct bootloader_message *misc_message;

	if(uboot_spare_head.boot_data.work_mode != WORK_MODE_BOOT)
	{
		return 0;
	}
	if(gd->force_shell)
	{
		char delaytime[8];

		sprintf(delaytime, "%d", 3);
		setenv("bootdelay", delaytime);
	}
    //if enter debug mode,set loglevel = 8
    check_debug_mode();

   memset(boot_commond, 0x0, 128);
	strcpy(boot_commond, getenv("bootcmd"));
	printf("base bootcmd=%s\n", boot_commond);
	//判断存储介质
	if((uboot_spare_head.boot_data.storage_type == 1) || (uboot_spare_head.boot_data.storage_type == 2))
	{
		sunxi_str_replace(boot_commond, "setargs_nand", "setargs_mmc");
		printf("bootcmd set setargs_mmc\n");
	}
	else
	{
		printf("bootcmd set setargs_nand\n");
	}
	misc_message = (struct bootloader_message *)misc_args;
	memset(misc_args, 0x0, 2048);
	memset(misc_fill, 0xff, 2048);
	mode = detect_other_boot_mode();
	if(mode == ANDROID_NULL_MODE)
	{
		pmu_value = axp_probe_pre_sys_mode();
		if(pmu_value == PMU_PRE_FASTBOOT_MODE)
		{
			puts("PMU : ready to enter fastboot mode\n");
			strcpy(misc_message->command, "bootloader");
		}
		else if(pmu_value == PMU_PRE_RECOVERY_MODE)
		{
			puts("PMU : ready to enter recovery mode\n");
			strcpy(misc_message->command, "boot-recovery");
		}
		else
		{
			misc_offset = sunxi_partition_get_offset_byname("misc");
			debug("misc_offset = %x\n",misc_offset);
			if(!misc_offset)
			{
				printf("no misc partition is found\n");
			}
			else
			{
				printf("misc partition found\n");
				sunxi_flash_read(misc_offset, 2048/512, misc_args); //read misc partition data
			}
		}
	}
	else if(mode == ANDROID_RECOVERY_MODE)
	{
		strcpy(misc_message->command, "boot-recovery");
	}
	else if( mode == ANDROID_FASTBOOT_MODE)
	{
		strcpy(misc_message->command, "bootloader");
	}
	//最终统一判断命令
	if(!loglel_change_flag)   //add by young,if you want to enter debug_mode ,so do enter boot_normal
	{
		if(!strcmp(misc_message->command, "efex"))
		{
			/* there is a recovery command */
			puts("find efex cmd\n");
			sunxi_flash_write(misc_offset, 2048/512, misc_fill);
			sunxi_board_run_fel();

			return 0;
		}

		if(!strcmp(misc_message->command, "boot-resignature"))
		{
			puts("find boot-resignature cmd\n");
			sunxi_flash_write(misc_offset, 2048/512, misc_fill);
			sunxi_oem_op_lock(SUNXI_LOCKING, NULL, 1);
		}
		else if(!strcmp(misc_message->command, "boot-recovery"))
		{
			if(!strcmp(misc_message->recovery, "sysrecovery"))
			{
				puts("recovery detected, will sprite recovery\n");
				strncpy(boot_commond, "sprite_recovery", sizeof("sprite_recovery"));
				sunxi_flash_write(misc_offset, 2048/512, misc_fill);
			}
			else
			{
				puts("Recovery detected, will boot recovery\n");
				sunxi_str_replace(boot_commond, "boot_normal", "boot_recovery");
			}
			/* android recovery will clean the misc */
		}
		else if(!strcmp(misc_message->command, "bootloader"))
		{
			puts("Fastboot detected, will boot fastboot\n");
			sunxi_str_replace(boot_commond, "boot_normal", "boot_fastboot");
			if(misc_offset)
				sunxi_flash_write(misc_offset, 2048/512, misc_fill);
		}
		else if(!strcmp(misc_message->command, "usb-recovery"))
		{
			puts("Recovery detected, will usb recovery\n");
			sunxi_str_replace(boot_commond, "boot_normal", "boot_recovery");
		}
	}
	if(!strcmp(misc_message->command ,"debug_mode"))
	{
		puts("debug_mode detected ,will enter debug_mode");
		if(!change_to_debug_mode())
		{
			check_debug_mode();
		}
			sunxi_flash_write(misc_offset,2048/512,misc_fill);
	}
	setenv("bootcmd", boot_commond);

	printf("to be run cmd=%s\n", boot_commond);
	return 0;

}
Exemple #8
0
static int sbromsw_toc1_traverse(void)
{
	sbrom_toc1_item_group item_group;
	int ret;
	uint len, i;
	u8 buffer[SUNXI_X509_CERTIFF_MAX_LEN];

	sunxi_certif_info_t  root_certif;
	sunxi_certif_info_t  sub_certif;
	u8  hash_of_file[256];
	//u8  hash_in_certif[256];

	//u8  key_certif_extension[260];
	//u8  content_certif_key[520];
	int out_to_ns;

	toc1_item_traverse();

	printf("probe root certif\n");
	sunxi_ss_open();

	memset(buffer, 0, SUNXI_X509_CERTIFF_MAX_LEN);
	len = toc1_item_read_rootcertif(buffer, SUNXI_X509_CERTIFF_MAX_LEN);
	if(!len)
	{
		printf("%s error: cant read rootkey certif\n", __func__);

		return -1;
	}
	if(sunxi_certif_verify_itself(&root_certif, buffer, len))
	{
		printf("certif invalid: root certif verify itself failed\n");

		return -1;
	}
	do
	{
		memset(&item_group, 0, sizeof(sbrom_toc1_item_group));
		ret = toc1_item_probe_next(&item_group);
		if(ret < 0)
		{
			printf("sbromsw_toc1_traverse err in toc1_item_probe_next\n");

			return -1;
		}
		else if(ret == 0)
		{
			printf("sbromsw_toc1_traverse find out all items\n");

			return 0;
		}
		if(item_group.bin_certif)
		{
			memset(buffer, 0, SUNXI_X509_CERTIFF_MAX_LEN);
			len = toc1_item_read(item_group.bin_certif, buffer, SUNXI_X509_CERTIFF_MAX_LEN);
			if(!len)
			{
				printf("%s error: cant read content key certif\n", __func__);

				return -1;
			}
			//证书内容进行自校验,确保没有被替换
			if(sunxi_certif_verify_itself(&sub_certif, buffer, len))
			{
				printf("%s error: cant verify the content certif\n", __func__);

				return -1;
			}
//			printf("key n:\n");
//			ndump(sub_certif.pubkey.n, sub_certif.pubkey.n_len);
//			printf("key e:\n");
//			ndump(sub_certif.pubkey.e, sub_certif.pubkey.e_len);
			//每当发现一个公钥证书,即在根证书中寻找匹配项目,找不到则认为有错误
			for(i=0;i<root_certif.extension.extension_num;i++)
			{
				if(!strcmp((const char *)root_certif.extension.name[i], item_group.bin_certif->name))
				{
					printf("find %s key stored in root certif\n", item_group.bin_certif->name);

					if(memcmp(root_certif.extension.value[i], sub_certif.pubkey.n+1, sub_certif.pubkey.n_len-1))
					{
						printf("%s key n is incompatible\n", item_group.bin_certif->name);
						printf(">>>>>>>key in rootcertif<<<<<<<<<<\n");
						ndump(root_certif.extension.value[i], sub_certif.pubkey.n_len-1);
						printf(">>>>>>>key in certif<<<<<<<<<<\n");
						ndump(sub_certif.pubkey.n+1, sub_certif.pubkey.n_len-1);

						return -1;
					}
					if(memcmp(root_certif.extension.value[i] + sub_certif.pubkey.n_len-1, sub_certif.pubkey.e, sub_certif.pubkey.e_len))
					{
						printf("%s key e is incompatible\n", item_group.bin_certif->name);
						printf(">>>>>>>key in rootcertif<<<<<<<<<<\n");
						ndump(root_certif.extension.value[i] + sub_certif.pubkey.n_len-1, sub_certif.pubkey.e_len);
						printf(">>>>>>>key in certif<<<<<<<<<<\n");
						ndump(sub_certif.pubkey.e, sub_certif.pubkey.e_len);

						return -1;
					}
					break;
				}
			}
			if(i==root_certif.extension.extension_num)
			{
				printf("cant find %s key stored in root certif", item_group.bin_certif->name);

				return -1;
			}
		}

		if(item_group.binfile)
		{
			//读出bin文件内容到内存
			len = sunxi_flash_read(item_group.binfile->data_offset/512, (item_group.binfile->data_len+511)/512, (void *)item_group.binfile->run_addr);
			//len = sunxi_flash_read(item_group.binfile->data_offset/512, (item_group.binfile->data_len+511)/512, (void *)0x2a000000);
			if(!len)
			{
				printf("%s error: cant read bin file\n", __func__);

				return -1;
			}
			//计算文件hash
			memset(hash_of_file, 0, sizeof(hash_of_file));
			ret = sunxi_sha_calc(hash_of_file, sizeof(hash_of_file), (u8 *)item_group.binfile->run_addr, item_group.binfile->data_len);
			//ret = sunxi_sha_calc(hash_of_file, sizeof(hash_of_file), (u8 *)0x2a000000, item_group.binfile->data_len);
			if(ret)
			{
				printf("sunxi_sha_calc: calc sha256 with hardware err\n");

				return -1;
			}
			//使用内容证书的扩展项,和文件hash进行比较
			//开始比较文件hash(小机端阶段计算得到)和证书hash(PC端计算得到)
			if(memcmp(hash_of_file, sub_certif.extension.value[0], 32))
			{
				printf("hash compare is not correct\n");
				printf(">>>>>>>hash of file<<<<<<<<<<\n");
				ndump(hash_of_file, 32);
				printf(">>>>>>>hash in certif<<<<<<<<<<\n");
				ndump(sub_certif.extension.value[0], 32);

				return -1;
			}

			printf("ready to run %s\n", item_group.binfile->name);
			if(strcmp(item_group.binfile->name, "u-boot"))
			{
				out_to_ns = 0;
			}
			else
			{
				out_to_ns = 1;
			}
			go_exec(item_group.binfile->run_addr, CONFIG_TOC0_CONFIG_ADDR, out_to_ns);
		}
	}
	while(1);

	return 0;
}
Exemple #9
0
DRESULT disk_read_fs (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Sector address (LBA) */
	DWORD count		/* Number of sectors to read (1..128) */
)
{
#ifndef CONFIG_ALLWINNER
	DRESULT res;
#endif
	int result;
	unsigned int start_block;
#ifndef CONFIG_ALLWINNER
	switch (pdrv) {
	case ATA :
		// translate the arguments here

		result = ATA_disk_read(buff, sector, count);

		// translate the reslut code here

		return res;

	case MMC :
		// translate the arguments here

		result = MMC_disk_read(buff, sector, count);

		// translate the reslut code here

		return res;

	case USB :
		// translate the arguments here

		result = USB_disk_read(buff, sector, count);

		// translate the reslut code here

		return res;
	}
	return RES_PARERR;
#else
//	result = sunxi_test_mmc_read(sector+0x12000, count, buff);
	start_block = sunxi_partition_get_offset_byname(PART_NAME[pdrv]);
	if (!start_block)
	{
		printf("[disk_read_fs] no the partition\n");
		return RES_ERROR;
	}
//	printf("read part %s\n", PART_NAME[pdrv]);
//	result = sunxi_test_nand_read((unsigned int)(sector+start_block),(unsigned int)count,buff);
	result = sunxi_flash_read(sector+start_block,count, buff);
	if(!result)
	{
		printf("read all error: start=%lx, addr=0x%x count=0x%x\n", sector, (unsigned int)buff,(unsigned int)count);

		return 1;
	}
	return RES_OK;
#endif
}
Exemple #10
0
int sunxi_keydata_burn_by_usb(void)
{
	char buffer[512];
#ifdef   CONFIG_SUNXI_SECURE_STORAGE
#ifndef  SUNXI_SECURESTORAGE_TEST_ERASE
	int  data_len;
#endif
#endif
	int  ret;
	uint burn_private_start, burn_private_len;
	int workmode = uboot_spare_head.boot_data.work_mode;

	int if_need_burn_key=0;

	ret = script_parser_fetch("target", "burn_key", &if_need_burn_key, 1);
	if((ret) || (if_need_burn_key != 1))
	{
		return 0;
	}

	if(workmode != WORK_MODE_BOOT)		//非启动模式,不执行
	{
		puts("out of usb burn from boot: not boot mode\n");

		return 0;
	}
	if(gd->vbus_status == SUNXI_VBUS_NOT_EXIST)	//vbus不存在,不执行
	{
		puts("out of usb burn from boot: without usb\n");

		return 0;
	}
	if(gd->power_step_level == BATTERY_RATIO_TOO_LOW_WITH_DCIN)
	{
		puts("out of usb burn from boot: not enough energy\n");

		return 0;
	}
	memset(buffer, 0, 512);
#ifdef CONFIG_SUNXI_SECURE_STORAGE
	if(sunxi_secure_storage_init())
#endif
	{
		printf("sunxi secure storage is not supported\n");
		burn_private_start = sunxi_partition_get_offset_byname("private");
		burn_private_len   = sunxi_partition_get_size_byname("private");

		if(!burn_private_start)
		{
			printf("private partition is not exist\n");

			return -1;
		}
		else
		{
			ret = sunxi_flash_read(burn_private_start + burn_private_len - (8192+512)/512, 1, buffer);
			if(ret != 1)
			{
				printf("cant read private part\n");

				return -1;
			}
			if(!strcmp(buffer, "key_burned"))
			{
				printf("find key burned flag\n");

				return 0;
			}
		}
	}
#ifdef CONFIG_SUNXI_SECURE_STORAGE
	else
	{
#ifndef SUNXI_SECURESTORAGE_TEST_ERASE
		ret = sunxi_secure_storage_read("key_burned_flag", buffer, 512, &data_len);
		if(ret)
		{
			printf("sunxi secure storage has no flag\n");
		}
		else
		{
			if(!strcmp(buffer, "key_burned"))
			{
				printf("wrn: data has clean\n");
				return 0;
			}
		}
#else
		if(!sunxi_secure_storage_erase_data_only("key_burned_flag"))
			sunxi_secure_storage_exit();

		return 0;
#endif
	}
#endif
	return do_burn_from_boot(NULL, 0, 0, NULL);
}
static int signature_verify(const char *part_name)
{
	unsigned int tmp_start;
	unsigned int summary1, summary2;
	unsigned int s_value[4], h_value[4];
	unsigned char buffer[HASH_BUFFER_BYTES];
	unsigned int read_bytes;

	memset(buffer, 0, HASH_BUFFER_BYTES);
	//计算hash值
	prepareCryptTable();		//准备hash表
	//获取签名
	printf("ras init\n");
	rsa_init();
	printf("ras start\n");

	if(!strcmp("boot", part_name))
	{
		tmp_start = sunxi_partition_get_offset_byname(part_name);

		printf("find part %s\n", part_name);
		read_bytes = sizeof(struct fastboot_boot_img_hdr);
		if(!sunxi_flash_read(tmp_start, (read_bytes + 511)/512, buffer))
		{
			printf("signature0 read flash sig1 err\n");

			return -1;
		}
		summary1 = HashString(buffer, 1, read_bytes);	//1类hash
		read_bytes = sizeof(struct image_header);
		if(!sunxi_flash_read(tmp_start + CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE/512, (read_bytes + 511)/512, buffer))
		{
			printf("signature0 read flash sig2 err\n");

			return -1;
		}
		summary1 = HashString(buffer, 1, read_bytes);	//1类hash

		//获取保存的签名
		if(!sunxi_flash_read(tmp_start, 2, buffer))
		{
			printf("signature0 read flash sig3 err\n");

			return -1;
		}
		s_value[0] = *(unsigned int *)(buffer + 608);
		s_value[1] = *(unsigned int *)(buffer + 612);
		s_value[2] = *(unsigned int *)(buffer + 616);
		s_value[3] = *(unsigned int *)(buffer + 620);

		rsa_decrypt( s_value, 4, h_value );

		summary2 = (h_value[0]<<0) | (h_value[1]<<8) | (h_value[2]<<16) | (h_value[3]<<24);
#if 0
		for(j=0;j<4;j++)
		{
			printf("s_value[%d] = %x\n", j, s_value[j]);
		}
		for(j=0;j<4;j++)
		{
			printf("h_value[%d] = %x\n", j, h_value[j]);
		}
#endif
		printf("summary by hash %x\n", summary1);
		printf("summary by rsa %x\n", summary2);
		if(summary1 != summary2)
		{
			printf("boot signature invalid\n");

			return -1;
		}
	}
	else if(!strcmp("system", part_name))
	{
		struct ext4_super_block  *sblock;

		tmp_start = sunxi_partition_get_offset_byname(part_name);
		printf("find part %s\n", part_name);

		printf("find system part\n");
		HashString_init();

		read_bytes = sizeof(struct ext4_super_block);
		if(!sunxi_flash_read(tmp_start + CFG_SUPER_BLOCK_SECTOR, (read_bytes + 511)/512, buffer))
		{
			printf("signature1 read flash sig1 err\n");

			return -1;
		}
		sblock = (struct ext4_super_block *)buffer;
#if 0
		{
			int k;
			printf("s_inodes_count        = %x\n", sblock->s_inodes_count);
			printf("s_blocks_count_lo     = %x\n", sblock->s_blocks_count_lo);
			printf("s_r_blocks_count_lo   = %x\n", sblock->s_r_blocks_count_lo);
			printf("s_free_blocks_count_lo= %x\n", sblock->s_free_blocks_count_lo);
			printf("s_free_inodes_count   = %x\n", sblock->s_free_inodes_count);
			printf("s_first_data_block    = %x\n", sblock->s_first_data_block);
			printf("s_log_block_size      = %x\n", sblock->s_log_block_size);
			printf("s_log_cluster_size    = %x\n", sblock->s_log_cluster_size);
			printf("s_blocks_per_group    = %x\n", sblock->s_blocks_per_group);
			printf("s_clusters_per_group  = %x\n", sblock->s_clusters_per_group);
			printf("s_inodes_per_group    = %x\n", sblock->s_inodes_per_group);
			printf("s_mtime               = %x\n", sblock->s_mtime);
			printf("s_wtime               = %x\n", sblock->s_wtime);
			printf("s_mnt_count           = %x\n", sblock->s_mnt_count);
			printf("s_max_mnt_count       = %x\n", sblock->s_max_mnt_count);
			printf("s_magic               = %x\n", sblock->s_magic);
			printf("s_state               = %x\n", sblock->s_state);
			printf("s_errors              = %x\n", sblock->s_errors);
			printf("s_minor_rev_level     = %x\n", sblock->s_minor_rev_level);
			printf("s_lastcheck           = %x\n", sblock->s_lastcheck);
			printf("s_checkinterval       = %x\n", sblock->s_checkinterval);
			printf("s_creator_os          = %x\n", sblock->s_creator_os);
			printf("s_rev_level           = %x\n", sblock->s_rev_level);
			printf("s_def_resuid          = %x\n", sblock->s_def_resuid);
			printf("s_def_resgid          = %x\n", sblock->s_def_resgid);

			printf("s_first_ino           = %x\n", sblock->s_first_ino);
			printf("s_inode_size          = %x\n", sblock->s_inode_size);
			printf("s_block_group_nr      = %x\n", sblock->s_block_group_nr);
			printf("s_feature_compat      = %x\n", sblock->s_feature_compat);
			printf("s_feature_incompat    = %x\n", sblock->s_feature_incompat);
			printf("s_feature_ro_compat   = %x\n", sblock->s_feature_ro_compat);
			for(k=0;k<16;k++)
			{
				printf("s_uuid[%d]        = %x\n", k, sblock->s_uuid[k]);
			}
			for(k=0;k<16;k++)
			{
				printf("s_volume_name[%d] = %x\n", k, sblock->s_volume_name[k]);
			}
			for(k=0;k<64;k++)
			{
				printf("s_last_mounted[%d]= %x\n", k, sblock->s_last_mounted[k]);
			}
			printf("s_algorithm_usage_bitmap= %x\n", sblock->s_algorithm_usage_bitmap);

			printf("s_prealloc_blocks     = %x\n", sblock->s_prealloc_blocks);
			printf("s_prealloc_dir_blocks = %x\n", sblock->s_prealloc_dir_blocks);
			printf("s_reserved_gdt_blocks = %x\n", sblock->s_reserved_gdt_blocks);

			for(k=0;k<16;k++)
			{
				printf("s_journal_uuid[%d]= %x\n", k, sblock->s_journal_uuid[k]);
			}
			printf("s_journal_inum        = %x\n", sblock->s_journal_inum);
			printf("s_journal_dev         = %x\n", sblock->s_journal_dev);
			printf("s_last_orphan         = %x\n", sblock->s_last_orphan);
			for(k=0;k<16;k++)
			{
				printf("s_hash_seed[%d]   = %x\n", k, sblock->s_hash_seed[k]);
			}
			printf("s_def_hash_version    = %x\n", sblock->s_def_hash_version);
			printf("s_jnl_backup_type     = %x\n", sblock->s_jnl_backup_type);
			printf("s_desc_size           = %x\n", sblock->s_desc_size);
			printf("s_default_mount_opts  = %x\n", sblock->s_default_mount_opts);
			printf("s_first_meta_bg       = %x\n", sblock->s_first_meta_bg);
			printf("s_mkfs_time           = %x\n", sblock->s_mkfs_time);
			for(k=0;k<17;k++)
			{
				printf("s_jnl_blocks[%d]  = %x\n", k, sblock->s_jnl_blocks[k]);
			}

			printf("s_blocks_count_hi     = %x\n", sblock->s_blocks_count_hi);
			printf("s_r_blocks_count_hi   = %x\n", sblock->s_r_blocks_count_hi);
			printf("s_free_blocks_count_hi= %x\n", sblock->s_free_blocks_count_hi);
			printf("s_min_extra_isize     = %x\n", sblock->s_min_extra_isize);
			printf("s_want_extra_isize    = %x\n", sblock->s_want_extra_isize);
			printf("s_flags               = %x\n", sblock->s_flags);

			printf("s_raid_stride         = %x\n", sblock->s_raid_stride);
			printf("s_mmp_update_interval = %x\n", sblock->s_mmp_update_interval);
			printf("s_mmp_block           = %x\n", sblock->s_mmp_block);
			printf("s_raid_stripe_width   = %x\n", sblock->s_raid_stripe_width);
			printf("s_log_groups_per_flex = %x\n", sblock->s_log_groups_per_flex);
			printf("s_reserved_char_pad   = %x\n", sblock->s_reserved_char_pad);

			printf("s_reserved_pad        = %x\n", sblock->s_reserved_pad);
			printf("s_kbytes_written      = %x\n", sblock->s_kbytes_written);
			printf("s_snapshot_inum       = %x\n", sblock->s_snapshot_inum);
			printf("s_snapshot_id         = %x\n", sblock->s_snapshot_id);
			printf("s_snapshot_r_blocks_count= %x\n", sblock->s_snapshot_r_blocks_count);
			printf("s_snapshot_list       = %x\n", sblock->s_snapshot_list);
		}
#endif
		sblock->s_mtime     = CFG_SUPER_BLOCK_STAMP_VALUE;
		sblock->s_mnt_count = CFG_SUPER_BLOCK_STAMP_VALUE & 0xffff;
		memset(sblock->s_last_mounted, 0, 64);
		summary1 = HashString(buffer, 1, (unsigned int)&(((struct ext4_super_block *)0)->s_snapshot_list));	//1类hash

		//获取保存的签名
		if(!sunxi_flash_read(tmp_start, 2, buffer))
		{
			printf("signature1 read flash sig3 err\n");

			return -1;
		}
		s_value[0] = *(unsigned int *)(buffer + 1000 - 10 * 4 + 0);
		s_value[1] = *(unsigned int *)(buffer + 1000 - 10 * 4 + 4);
		s_value[2] = *(unsigned int *)(buffer + 1000 - 10 * 4 + 8);
		s_value[3] = *(unsigned int *)(buffer + 1000 - 10 * 4 + 12);

		rsa_decrypt( s_value, 4, h_value );
		summary2 = (h_value[0]<<0) | (h_value[1]<<8) | (h_value[2]<<16) | (h_value[3]<<24);
#if 0
		for(j=0;j<4;j++)
		{
			printf("s_value[%d] = %x\n", j, s_value[j]);
		}
		for(j=0;j<4;j++)
		{
			printf("h_value[%d] = %x\n", j, h_value[j]);
		}
#endif
		printf("summary by hash %x\n", summary1);
		printf("summary by rsa %x\n", summary2);
		if(summary1 != summary2)
		{
			printf("system signature invalid\n");

			return -1;
		}
	}

	return 0;
}
Exemple #12
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
static int __download_normal_part(dl_one_part_info *part_info,  uchar *source_buff)
{
	uint partstart_by_sector;		//分区起始扇区
	uint tmp_partstart_by_sector;

	s64  partsize_by_byte;			//分区大小(字节单位)

	s64  partdata_by_byte;			//需要下载的分区数据(字节单位)
	s64  tmp_partdata_by_bytes;

	uint onetime_read_sectors;		//一次读写的扇区数
	uint first_write_bytes;

	uint imgfile_start;				//分区数据所在的扇区
	uint tmp_imgfile_start;

	u8 *down_buffer       = source_buff + SPRITE_CARD_HEAD_BUFF;

	int  partdata_format;

	int  ret = -1;
	//*******************************************************************
	//获取分区起始扇区
	tmp_partstart_by_sector = partstart_by_sector = part_info->addrlo;
	//获取分区大小,字节数
	partsize_by_byte     = part_info->lenlo;
	partsize_by_byte   <<= 9;
	//打开分区镜像
	imgitemhd = Img_OpenItem(imghd, "RFSFAT16", (char *)part_info->dl_filename);
	if(!imgitemhd)
	{
		printf("sunxi sprite error: open part %s failed\n", part_info->dl_filename);

		return -1;
	}
	//获取分区镜像字节数
	partdata_by_byte = Img_GetItemSize(imghd, imgitemhd);
	if (partdata_by_byte <= 0)
	{
		printf("sunxi sprite error: fetch part len %s failed\n", part_info->dl_filename);

		goto __download_normal_part_err1;
	}
	printf("partdata hi 0x%x\n", (uint)(partdata_by_byte>>32));
	printf("partdata lo 0x%x\n", (uint)partdata_by_byte);
	//如果分区数据超过分区大小
	if(partdata_by_byte > partsize_by_byte)
	{
		printf("sunxi sprite: data size 0x%x is larger than part %s size 0x%x\n", (uint)(partdata_by_byte/512), part_info->dl_filename, (uint)(partsize_by_byte/512));

		goto __download_normal_part_err1;
	}
	//准备读取分区镜像数据
	tmp_partdata_by_bytes = partdata_by_byte;
	if(tmp_partdata_by_bytes >= SPRITE_CARD_ONCE_DATA_DEAL)
	{
		onetime_read_sectors = SPRITE_CARD_ONCE_SECTOR_DEAL;
		first_write_bytes    = SPRITE_CARD_ONCE_DATA_DEAL;
	}
	else
	{
		onetime_read_sectors = (tmp_partdata_by_bytes + 511)>>9;
		first_write_bytes    = (uint)tmp_partdata_by_bytes;
	}
	//开始获取分区数据
	imgfile_start = Img_GetItemStart(imghd, imgitemhd);
	if(!imgfile_start)
	{
		printf("sunxi sprite err : cant get part data imgfile_start %s\n", part_info->dl_filename);

		goto __download_normal_part_err1;
	}
	tmp_imgfile_start = imgfile_start;
	//读出第一笔固件中的分区数据,大小为buffer字节数
	if(sunxi_flash_read(tmp_imgfile_start, onetime_read_sectors, down_buffer) != onetime_read_sectors)
	{
		printf("sunxi sprite error : read sdcard block %d, total %d failed\n", tmp_imgfile_start, onetime_read_sectors);

		goto __download_normal_part_err1;
	}
	//下一个要读出的数据
	tmp_imgfile_start += onetime_read_sectors;
	//尝试查看是否sparse格式
    partdata_format = unsparse_probe((char *)down_buffer, first_write_bytes, partstart_by_sector);		//判断数据格式
    if(partdata_format != ANDROID_FORMAT_DETECT)
    {
    	//写入第一笔数据
    	if(sunxi_sprite_write(tmp_partstart_by_sector, onetime_read_sectors, down_buffer) != onetime_read_sectors)
		{
			printf("sunxi sprite error: download rawdata error %s\n", part_info->dl_filename);

			goto __download_normal_part_err1;
		}
    	tmp_partdata_by_bytes   -= first_write_bytes;
		tmp_partstart_by_sector += onetime_read_sectors;

		while(tmp_partdata_by_bytes >= SPRITE_CARD_ONCE_DATA_DEAL)
		{
			//继续读出固件中的分区数据,大小为buffer字节数
			if(sunxi_flash_read(tmp_imgfile_start, SPRITE_CARD_ONCE_SECTOR_DEAL, down_buffer) != SPRITE_CARD_ONCE_SECTOR_DEAL)
			{
				printf("sunxi sprite error : read sdcard block %d, total %d failed\n", tmp_imgfile_start, SPRITE_CARD_ONCE_SECTOR_DEAL);

				goto __download_normal_part_err1;
			}
			//写入flash
			if(sunxi_sprite_write(tmp_partstart_by_sector, SPRITE_CARD_ONCE_SECTOR_DEAL, down_buffer) != SPRITE_CARD_ONCE_SECTOR_DEAL)
			{
				printf("sunxi sprite error: download rawdata error %s, start 0x%x, sectors 0x%x\n", part_info->dl_filename, tmp_partstart_by_sector, SPRITE_CARD_ONCE_SECTOR_DEAL);

				goto __download_normal_part_err1;
			}
			tmp_imgfile_start       += SPRITE_CARD_ONCE_SECTOR_DEAL;
			tmp_partdata_by_bytes   -= SPRITE_CARD_ONCE_DATA_DEAL;
			tmp_partstart_by_sector += SPRITE_CARD_ONCE_SECTOR_DEAL;
		}
		if(tmp_partdata_by_bytes > 0)
		{
			uint rest_sectors = (tmp_partdata_by_bytes + 511)>>9;
			//继续读出固件中的分区数据,大小为buffer字节数
			if(sunxi_flash_read(tmp_imgfile_start, rest_sectors, down_buffer) != rest_sectors)
			{
				printf("sunxi sprite error : read sdcard block %d, total %d failed\n", tmp_imgfile_start, rest_sectors);

				goto __download_normal_part_err1;
			}
			//写入flash
			if(sunxi_sprite_write(tmp_partstart_by_sector, rest_sectors, down_buffer) != rest_sectors)
			{
				printf("sunxi sprite error: download rawdata error %s, start 0x%x, sectors 0x%x\n", part_info->dl_filename, tmp_partstart_by_sector, rest_sectors);

				goto __download_normal_part_err1;
			}
		}
    }
Exemple #13
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
static int sunxi_pburn_state_loop(void  *buffer)
{
	static struct umass_bbb_cbw_t  *cbw;
	static struct umass_bbb_csw_t  csw;
	static uint pburn_flash_start = 0;
	//static uint pburn_flash_sectors = 0;
	int    ret;
	sunxi_ubuf_t *sunxi_ubuf = (sunxi_ubuf_t *)buffer;

	switch(sunxi_usb_pburn_status)
	{
		case SUNXI_USB_PBURN_IDLE:
			if(sunxi_ubuf->rx_ready_for_data == 1)
			{
				sunxi_usb_pburn_status = SUNXI_USB_PBURN_SETUP;
			}

			break;

		case SUNXI_USB_PBURN_SETUP:

			sunxi_usb_dbg("SUNXI_USB_PBURN_SETUP\n");

			if(sunxi_ubuf->rx_req_length != sizeof(struct umass_bbb_cbw_t))
			{
				printf("sunxi usb error: received bytes 0x%x is not equal cbw struct size 0x%zx\n", sunxi_ubuf->rx_req_length, sizeof(struct umass_bbb_cbw_t));

				sunxi_ubuf->rx_ready_for_data = 0;
				sunxi_usb_pburn_status = SUNXI_USB_PBURN_IDLE;

				break;
			}

			cbw = (struct umass_bbb_cbw_t *)sunxi_ubuf->rx_req_buffer;
			if(CBWSIGNATURE != cbw->dCBWSignature)
			{
				printf("sunxi usb error: the cbw signature 0x%x is bad, need 0x%x\n", cbw->dCBWSignature, CBWSIGNATURE);

				sunxi_ubuf->rx_ready_for_data = 0;
				sunxi_usb_pburn_status = SUNXI_USB_PBURN_IDLE;

				break;
			}

			csw.dCSWSignature = CSWSIGNATURE;
			csw.dCSWTag 	  = cbw->dCBWTag;

#if defined(SUNXI_USB_30)
			sunxi_usb_pburn_status_enable = 1;
#endif
			sunxi_usb_dbg("usb cbw command = 0x%x\n", cbw->CBWCDB[0]);

			switch(cbw->CBWCDB[0])
	  		{
#ifdef  CONFIG_SUNXI_SECURE_STORAGE
				case 0xf0:			//自定义命令,用于烧录用户数据
	  				sunxi_usb_dbg("usb burn secure storage data\n");
	  				printf("usb command = %d\n", cbw->CBWCDB[1]);
	  				switch(cbw->CBWCDB[1])
	  				{
	  					case 0:				//握手
	  					{
	  						__usb_handshake_sec_t  *handshake = (__usb_handshake_sec_t *)trans_data.base_send_buffer;

                            memset(handshake, 0, sizeof(__usb_handshake_sec_t));
							strcpy(handshake->magic, "usb_burn_handshake");
							sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;

		  					trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_sec_t));

							sunxi_usb_burn_from_boot_setup = 1;

							private_data_ext_buff = (u8 *)malloc(4 * 1024 * 1024);
							if(private_data_ext_buff == NULL)
							{
								printf("there is no memorfy to store all user key data\n");

								csw.bCSWStatus = -1;
							}
							else
		  					{
		  						csw.bCSWStatus = 0;
		  						sunxi_usb_burn_from_boot_handshake = 1;
		  					}
		  					private_data_ext_buff_step = private_data_ext_buff;
						}
						break;

						case 1:				//小机端接收数据
						{
							trans_data.recv_size = cbw->dCBWDataTransferLength;

                            sunxi_usb_pburn_write_enable = 0;
							sunxi_udc_start_recv_by_dma(private_data_ext_buff_step, trans_data.recv_size);	//start dma to receive data

							printf("recv_size=%d\n", trans_data.recv_size);
							sunxi_dump(private_data_ext_buff, trans_data.recv_size);

					        sunxi_usb_pburn_status = SUNXI_USB_PBURN_RECEIVE_NULL;
						}
						break;

						case 2:             //工具端声明数据传输已经完毕,要求获取烧录状态
						{
							__usb_handshake_ext_t  *handshake = (__usb_handshake_ext_t *)trans_data.base_send_buffer;

							memset(handshake, 0, sizeof(__usb_handshake_ext_t));
							//strcpy(handshake->magic, "usb_burn_receive_data_all");
							sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;

							printf("recv_size=%d\n", trans_data.recv_size);
							sunxi_dump(private_data_ext_buff, trans_data.recv_size);

							int ret = __sunxi_burn_key(private_data_ext_buff, trans_data.recv_size);

		  					trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_ext_t));
		  					//开始根据数据类型进行烧录动作

		  					if(!ret)	//数据烧写成功
		  					{
		  						strcpy(handshake->magic, "usb_burn_success");
		  						csw.bCSWStatus = 0;
		  					}
		  					else	//数据烧写失败
		  					{
		  						strcpy(handshake->magic, "usb_burn_error");
		  						csw.bCSWStatus = -1;
		  					}
		  					if(private_data_ext_buff)
		  					{
		  						free(private_data_ext_buff);
		  					}
						}
						break;

//						case 3:             //小机端读取每个key
//						{
//							uint start, sectors;
//							uint offset;
//
//							start   = *(int *)(cbw->CBWCDB + 4);		//读数据的偏移量
//							sectors = *(int *)(cbw->CBWCDB + 8);		//扇区数;
//
//							trans_data.send_size 	   = min(cbw->dCBWDataTransferLength, sectors * 512);
//							trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
//
//							offset = burn_private_start;
//							ret = sunxi_flash_read(start + offset, sectors, trans_data.base_send_buffer);
//							if(!ret)
//							{
//								printf("sunxi flash read err: start,0x%x sectors 0x%x\n", start, sectors);
//
//								csw.bCSWStatus = 1;
//							}
//							else
//							{
//								csw.bCSWStatus = 0;
//							}
//
//							sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;
//						}
//						break;

						case 4:				//关闭usb
						{
							__usb_handshake_ext_t  *handshake = (__usb_handshake_ext_t *)trans_data.base_send_buffer;

                            memset(handshake, 0, sizeof(__usb_handshake_ext_t));
							strcpy(handshake->magic, "usb_burn_finish");

							trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_ext_t));

							sunxi_udc_send_data((void *)trans_data.act_send_buffer, trans_data.send_size);

		  					csw.bCSWStatus = 0;

		  					sunxi_usb_pburn_status = SUNXI_USB_PBURN_EXIT;

						}
						break;

						case 5:
						{
							__usb_handshake_ext_t  *handshake = (__usb_handshake_ext_t *)trans_data.base_send_buffer;

							memset(handshake, 0, sizeof(__usb_handshake_ext_t));
							strcpy(handshake->magic, "usb_burn_saved");

							trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_ext_t));

		  					csw.bCSWStatus = 0;

		  					sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;
		  					if(sunxi_secure_storage_write("key_burned_flag", "key_burned", strlen("key_burned")))
		  					{
		  						printf("save burned flag err\n");

		  						csw.bCSWStatus = -1;
		  					}
		  					sunxi_secure_storage_exit();
						}
						break;

					default:
						break;
	  			}
	  			break;
#endif

	  			case 0xf3:			//自定义命令,用于烧录用户数据
	  				sunxi_usb_dbg("usb burn private\n");
	  				printf("usb command = %d\n", cbw->CBWCDB[1]);
	  				switch(cbw->CBWCDB[1])
	  				{
	  					case 0:				//握手
	  					{
	  						__usb_handshake_t  *handshake = (__usb_handshake_t *)trans_data.base_send_buffer;

							burn_private_start = sunxi_partition_get_offset_byname("private");
							burn_private_len   = sunxi_partition_get_size_byname("private");

							if(!burn_private_start)
							{
								printf("private partition is not exist\n");

								csw.bCSWStatus = -1;
							}
							else
							{
								csw.bCSWStatus = 0;
							}

                            memset(handshake, 0, sizeof(__usb_handshake_t));
							strcpy(handshake->magic, "usb_burn_handshake");
							handshake->sizelo = burn_private_len;
							handshake->sizehi = 0;
							sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;

							sunxi_usb_burn_from_boot_setup = 1;
							sunxi_usb_burn_from_boot_handshake = 1;

		  					trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_t));
						}
						break;

						case 1:				//小机端接收数据
						{
							//pburn_flash_sectors  = *(int *)(cbw->CBWCDB + 8);
							//pburn_flash_start    = *(int *)(cbw->CBWCDB + 4);
							memcpy(&pburn_flash_start,(cbw->CBWCDB + 4),4);

							trans_data.recv_size = cbw->dCBWDataTransferLength;
							trans_data.act_recv_buffer = trans_data.base_recv_buffer;

                            pburn_flash_start += burn_private_start;
                            sunxi_usb_pburn_write_enable = 0;
							sunxi_udc_start_recv_by_dma(trans_data.act_recv_buffer, trans_data.recv_size);	//start dma to receive data

					        sunxi_usb_pburn_status = SUNXI_USB_PBURN_RECEIVE_DATA;
						}
						break;

						case 3:             //小机端发送数据
						{
							uint start, sectors;

							//start   = *(int *)(cbw->CBWCDB + 4);		//读数据的偏移量
							//sectors = *(int *)(cbw->CBWCDB + 8);		//扇区数;
							memcpy(&start,(cbw->CBWCDB + 4),4);
							memcpy(&sectors,(cbw->CBWCDB + 8),4);

							printf("start=%d, sectors=%d\n", start, sectors);

							trans_data.send_size 	   = min(cbw->dCBWDataTransferLength, sectors * 512);
							trans_data.act_send_buffer = trans_data.base_send_buffer;

							printf("send size=%d\n", trans_data.send_size);

							ret = sunxi_flash_read(start + burn_private_start, sectors, trans_data.base_send_buffer);
							if(!ret)
							{
								printf("sunxi flash read err: start,0x%x sectors 0x%x\n", start, sectors);

								csw.bCSWStatus = 1;
							}
							else
							{
								csw.bCSWStatus = 0;
							}

							sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;
						}
						break;

						case 4:				//关闭usb
						{
							__usb_handshake_ext_t  *handshake = (__usb_handshake_ext_t *)trans_data.base_send_buffer;

                            memset(handshake, 0, sizeof(__usb_handshake_ext_t));
							strcpy(handshake->magic, "usb_burn_finish");

							trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_ext_t));

							sunxi_udc_send_data((void *)trans_data.act_send_buffer, trans_data.send_size);

		  					csw.bCSWStatus = 0;

							sunxi_flash_flush();
		  					sunxi_usb_pburn_status = SUNXI_USB_PBURN_EXIT;

						}
						break;

						case 5:
						{
							__usb_handshake_ext_t  *handshake = (__usb_handshake_ext_t *)trans_data.base_send_buffer;
							char buffer[512];

							memset(handshake, 0, sizeof(__usb_handshake_ext_t));
							strcpy(handshake->magic, "usb_burn_saved");

							trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_ext_t));

		  					csw.bCSWStatus = 0;

		  					sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;

		  					memset(buffer, 0, 512);
							strcpy(buffer, "key_burned");

		  					if(!sunxi_flash_write(burn_private_start + burn_private_len - (8192+512)/512, 1, buffer))
		  					{
		  						printf("save burned flag err\n");

		  						csw.bCSWStatus = -1;
		  					}
		  					sunxi_flash_flush();
#ifdef CONFIG_SUNXI_SECURE_STORAGE
							if(sunxi_secure_storage_init())
							{
								printf("init secure storage failed\n");

								csw.bCSWStatus = -1;
							}
		  					else
		  					{
		  						if(sunxi_secure_storage_write("key_burned_flag", "key_burned", strlen("key_burned")))
		  						{
		  							printf("save burned flag err\n");

		  							csw.bCSWStatus = -1;
		  						}
		  					}
		  					sunxi_secure_storage_exit();
#endif
						}
						break;

					default:
						break;
	  				}

	  			break;

	  			default:
	  				sunxi_usb_dbg("not supported command 0x%x now\n", cbw->CBWCDB[0]);
	  				sunxi_usb_dbg("asked size 0x%x\n", cbw->dCBWDataTransferLength);

	  				csw.bCSWStatus = 1;

	  				sunxi_usb_pburn_status = SUNXI_USB_PBURN_STATUS;

	  				break;
	  		}

	  		break;

	  	case SUNXI_USB_PBURN_SEND_DATA:

	  		sunxi_usb_dbg("SUNXI_USB_SEND_DATA\n");

			sunxi_usb_pburn_status = SUNXI_USB_PBURN_STATUS;
			printf("SUNXI_USB_SEND_DATA=%d\n", trans_data.send_size);
			sunxi_udc_send_data((void *)trans_data.act_send_buffer, trans_data.send_size);
#if defined(SUNXI_USB_30)
			sunxi_usb_pburn_status_enable = 0;
#endif
	  		break;

	  	case SUNXI_USB_PBURN_RECEIVE_DATA:

	  		sunxi_usb_dbg("SUNXI_USB_RECEIVE_DATA\n");

			if(sunxi_usb_pburn_write_enable == 1)
			{
				sunxi_usb_dbg("write flash, start 0x%x, sectors 0x%x\n", pburn_flash_start, trans_data.recv_size/512);
				ret = sunxi_flash_write(pburn_flash_start, (trans_data.recv_size+511)/512, (void *)trans_data.act_recv_buffer);
				if(!ret)
				{
					printf("sunxi flash write err: start,0x%x sectors 0x%x\n", pburn_flash_start, (trans_data.recv_size+511)/512);

					csw.bCSWStatus = 1;
				}
				else
				{
					csw.bCSWStatus = 0;
  				}
				sunxi_usb_pburn_write_enable = 0;

  				sunxi_usb_pburn_status = SUNXI_USB_PBURN_STATUS;
			}

	  		break;

		case SUNXI_USB_PBURN_STATUS:

			sunxi_usb_dbg("SUNXI_USB_PBURN_STATUS\n");
#if defined(SUNXI_USB_30)
			if(sunxi_usb_pburn_status_enable)
#endif
			{
				sunxi_usb_pburn_status = SUNXI_USB_PBURN_IDLE;
				sunxi_ubuf->rx_ready_for_data = 0;
				__sunxi_pburn_send_status(&csw, sizeof(struct umass_bbb_csw_t));
			}

			break;

		case SUNXI_USB_PBURN_EXIT:

			printf("SUNXI_USB_PBURN_EXIT\n");

			sunxi_usb_pburn_status = SUNXI_USB_PBURN_IDLE;
			sunxi_ubuf->rx_ready_for_data = 0;
			__sunxi_pburn_send_status(&csw, sizeof(struct umass_bbb_csw_t));

			printf("Device will shutdown in 3 Secends...\n");
			__msdelay(3000);

			return SUNXI_UPDATE_NEXT_ACTION_SHUTDOWN;

	  	case SUNXI_USB_PBURN_RECEIVE_NULL:

	  		sunxi_usb_dbg("SUNXI_USB_PBURN_RECEIVE_NULL\n");

			if(sunxi_usb_pburn_write_enable == 1)
			{
				csw.bCSWStatus = 0;
				sunxi_usb_pburn_write_enable = 0;
  				sunxi_usb_pburn_status = SUNXI_USB_PBURN_STATUS;
			}

	  		break;

	  	default:
	  		break;
	}

	return 0;
}
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
int check_android_misc(void)
{
	int   mode;
	u32   misc_offset = 0;
	char  misc_args[2048];
	char  misc_fill[2048];
	char  boot_commond[128];
	static struct bootloader_message *misc_message;

	if(uboot_spare_head.boot_data.work_mode != WORK_MODE_BOOT)
	{
		return 0;
	}
	if(gd->force_shell)
	{
		char delaytime[8];

		sprintf(delaytime, "%d", 3);
		setenv("bootdelay", delaytime);
	}

    memset(boot_commond, 0x0, 128);
	set_boot_type_cmd(boot_commond);
	printf("base bootcmd=%s\n", boot_commond);
	//判断存储介质
	if((uboot_spare_head.boot_data.storage_type == 1) || (uboot_spare_head.boot_data.storage_type == 2))
	{
		sunxi_str_replace(boot_commond, "setargs_nand", "setargs_mmc");
		printf("bootcmd set setargs_mmc\n");
	}
	else
	{
		printf("bootcmd set setargs_nand\n");
	}
	//判断是否存在按键进入其它模式
	memset(misc_args, 0x0, 2048);
	mode = detect_other_boot_mode();
	misc_message = (struct bootloader_message *)misc_args;
	if(mode == ANDROID_NULL_MODE)
	{
		misc_offset = sunxi_partition_get_offset_byname("misc");
		if(!misc_offset)
		{
			int pmu_value;

			puts("no misc partition is found\n");
			pmu_value = axp_probe_pre_sys_mode();
			if(pmu_value == PMU_PRE_FASTBOOT_MODE)
			{
				puts("ready to enter fastboot mode\n");
				setenv("bootcmd", "run boot_fastboot");

				return 0;
			}
			else
			{
				printf("to be run cmd=%s\n", boot_commond);
				setenv("bootcmd", boot_commond);

				return 0;
			}
		}
		memset(misc_fill, 0xff, 2048);
#ifdef DEBUG
		tick_printf("misc_offset  : %d\n", (int )misc_offset);
#endif
		sunxi_flash_read(misc_offset, 2048/512, misc_args);
	}
	else if(mode == ANDROID_RECOVERY_MODE)
	{
		strcpy(misc_message->command, "boot-recovery");
	}
	else if(mode == ANDROID_FASTBOOT_MODE)
	{
		strcpy(misc_message->command, "bootloader");
	}
#ifdef DEBUG
	{
		uint *dump_value;

		dump_value = *(uint *)misc_message->command;
		if(dump_value != 0xffffffff)
			printf("misc.command  : %s\n", misc_message->command);
		else
			printf("misc.command  : NULL\n");

		dump_value = *(uint *)misc_message->status;
		if(dump_value != 0xffffffff)
			printf("misc.status  : %s\n", misc_message->status);
		else
			printf("misc.status  : NULL\n");

		dump_value = *(uint *)misc_message->recovery;
		if(dump_value != 0xffffffff)
			printf("misc.recovery  : %s\n", misc_message->recovery);
		else
			printf("misc.recovery  : NULL\n");
	}
#endif
	//判断命令
	if(!strcmp(misc_message->command, "efex"))
	{
		/* there is a recovery command */
		puts("find efex cmd\n");
		sunxi_flash_write(misc_offset, 2048/512, misc_fill);
		sunxi_board_run_fel();

		return 0;
	}

	if(!strcmp(misc_message->command, "boot-resignature"))
	{
		puts("find boot-resignature cmd\n");
		sunxi_flash_write(misc_offset, 2048/512, misc_fill);
		sunxi_oem_op_lock(SUNXI_LOCKING, NULL, 1);
	}
	else if(!strcmp(misc_message->command, "boot-recovery"))
	{
		puts("Recovery detected, will boot recovery\n");
		sunxi_str_replace(boot_commond, "boot_normal", "boot_recovery");
		/* android recovery will clean the misc */
	}
	else if(!strcmp(misc_message->command, "bootloader"))
	{
		puts("Fastboot detected, will boot fastboot\n");
		sunxi_str_replace(boot_commond, "boot_normal", "boot_fastboot");
		if(misc_offset)
			sunxi_flash_write(misc_offset, 2048/512, misc_fill);
	}

	setenv("bootcmd", boot_commond);

	printf("to be run cmd=%s\n", boot_commond);

	return 0;
}
int android_misc_flash_check(void) {

	u32   misc_offset = 0;
	char  buffer[2048];

	misc_offset = (u32)sunxi_partition_get_offset_byname("misc");
	if(misc_offset == (u32)(-1))
	{
		puts("no misc partition is found\n");
		return 0;
	}	
	memset(buffer, 0, 2048);
#ifdef DEBUG
	printf("misc_offset  : %x\n", (int )misc_offset);
#endif
	sunxi_flash_read(misc_offset, 2048/512, buffer);
	memcpy(&misc_message, buffer, sizeof(misc_message));
#ifdef DEBUG
//	printf("misc.command  : %s\n", misc_message.command);
//	printf("misc.status   : %s\n", misc_message.status);
//	printf("misc.recovery : %s\n", misc_message.recovery);
#endif
	if(storage_type)
	{
		if(!strcmp(misc_message.command, "boot-recovery")) {
			/* there is a recovery command */
			puts("find boot recovery\n");
			setenv("bootcmd", "run setargs_mmc boot_recovery");
			puts("Recovery detected, will boot recovery\n");
			/* android recovery will clean the misc */
		}
		else{
			printf("bootcmd set setargs_mmc\n");
			setenv("bootcmd", "run setargs_mmc boot_normal");
		}
		if(!strcmp(misc_message.command, "boot-fastboot")) {
			/* there is a fastboot command */
			setenv("bootcmd", "run setargs_mmc boot_fastboot");
			puts("Fastboot detected, will enter fastboot\n");
			/* clean the misc partition ourself */
			memset(buffer, 0, 2048);
			sunxi_flash_write(misc_offset, 2048/512, buffer);
		}
	}
	else
	{
		if(!strcmp(misc_message.command, "boot-recovery")) {
			/* there is a recovery command */
			puts("find boot recovery\n");
			setenv("bootcmd", "run setargs_nand boot_recovery");
			puts("Recovery detected, will boot recovery\n");
			/* android recovery will clean the misc */
		}
        else
        if (!strcmp(misc_message.command, "usb-recovery")) {
		/* there is a recovery command */
		puts("find usb recovery\n");
		setenv("bootcmd", "run setargs_nand boot_recovery");
		puts("Recovery detected, will usb recovery\n");
		/* android recovery will clean the misc */
		}
		else{
			printf("bootcmd set setargs_nand\n");
			setenv("bootcmd", "run setargs_nand boot_normal");
		}

		if(!strcmp(misc_message.command, "boot-fastboot")) {
			/* there is a fastboot command */
			setenv("bootcmd", "run setargs_nand boot_fastboot");
			puts("Fastboot detected, will enter fastboot\n");
			/* clean the misc partition ourself */
			memset(buffer, 0, 2048);
			sunxi_flash_write(misc_offset, 2048/512, buffer);
		}
	}

	return 0;
}
Exemple #16
0
int check_android_misc(void)
{
	int   mode;
	int	  pmu_value;
	u32   misc_offset = 0;
	char  misc_args[2048];
	char  misc_fill[2048];
	char  boot_commond[128];
	static struct bootloader_message *misc_message;

	if(uboot_spare_head.boot_data.work_mode != WORK_MODE_BOOT)
	{
		return 0;
	}
	if(gd->force_shell)
	{
		char delaytime[8];

		sprintf(delaytime, "%d", 3);
		setenv("bootdelay", delaytime);
	}
        //if enter debug mode,set loglevel = 8
        check_debug_mode();

        memset(boot_commond, 0x0, 128);
	strcpy(boot_commond, getenv("bootcmd"));
	printf("base bootcmd=%s\n", boot_commond);
	//判断存储介质
	if((uboot_spare_head.boot_data.storage_type == 1) || (uboot_spare_head.boot_data.storage_type == 2))
	{
		sunxi_str_replace(boot_commond, "setargs_nand", "setargs_mmc");
		printf("bootcmd set setargs_mmc\n");
	}
	else
	{
		printf("bootcmd set setargs_nand\n");
	}
	//判断是否存在按键进入其它模式
	misc_message = (struct bootloader_message *)misc_args;
	memset(misc_args, 0x0, 2048);
	memset(misc_fill, 0xff, 2048);
	mode = detect_other_boot_mode();

	misc_offset = sunxi_partition_get_offset_byname("misc");
	//先判断上一次系统是否有写入数据到pmu寄存器
	pmu_value = axp_probe_pre_sys_mode();
	if(pmu_value == PMU_PRE_FASTBOOT_MODE)
	{
		puts("PMU : ready to enter fastboot mode\n");
		strcpy(misc_message->command, "bootloader");
	}
	else if(pmu_value == PMU_PRE_RECOVERY_MODE)
	{
		puts("PMU : ready to enter recovery mode\n");
		strcpy(misc_message->command, "boot-recovery");
	}
//get the part --"misc"
	else
	{
		debug("misc_offset = %x\n",misc_offset);
		if(!misc_offset)
		{
			printf("no misc partition is found\n");
		}
		else
		{
			printf("misc partition found\n");
			sunxi_flash_read(misc_offset, 2048/512, misc_args); //read misc partition data
		}
	}
	if((misc_message->command[0] == 0x00) ||(misc_message->command[0] == 0xff))
	{
		printf("misc_message->command = %x \n",misc_message->command[0]);
		if(mode == USER_SELECT_MODE) //说明探测阶段有按键按下
		{
			printf("enter user_select_mode\n");
		#if 0
			//如果misc分区没有上次系统写入数据,并且检测到有按键按下,那么进入图片显示菜单
			user_select_current_status = FASTBOOT_MODE;
			show_user_select_menu_ui(); //显示当前模式的ui
			while(status != POWERON_KEY_PRESSED)//图片显示菜单
			{
				status = sunxi_probe_key_pressed();
				if(( status == KEY_PRESSED))
				{
					debug("key_ststus = 0x%x\n ",status);
					user_mode_status_update(status);     	//更新菜单的选项
					show_user_select_menu_ui(); 				//显示当前模式的ui
				}
			}
			if(user_select_current_status == RECOVERY_MODE )
			{
				printf("misc_message->command = boot-recovery\n");
				strcpy(misc_message->command, "boot-recovery");
			}
			else if(user_select_current_status == FASTBOOT_MODE)
			{
				printf("misc_message->command = bootloader\n");
				strcpy(misc_message->command, "bootloader");
			}
		#endif
		}
		else if(mode == ANDROID_RECOVERY_MODE)
		{
			strcpy(misc_message->command, "boot-recovery");
		}
		else if( mode == ANDROID_FASTBOOT_MODE)
		{
			strcpy(misc_message->command, "bootloader");
		}
	}

	//最终统一判断命令
	if(!loglel_change_flag)   //add by young,if you want to enter debug_mode ,so do enter boot_normal
	{
		if(!strcmp(misc_message->command, "efex"))
		{
			/* there is a recovery command */
			puts("find efex cmd\n");
			sunxi_flash_write(misc_offset, 2048/512, misc_fill);
			sunxi_board_run_fel();

			return 0;
		}

		if(!strcmp(misc_message->command, "boot-resignature"))
		{
			puts("find boot-resignature cmd\n");
			sunxi_flash_write(misc_offset, 2048/512, misc_fill);
			sunxi_oem_op_lock(SUNXI_LOCKING, NULL, 1);
		}
		else if(!strcmp(misc_message->command, "boot-recovery"))
		{
			puts("Recovery detected, will boot recovery\n");
			sunxi_str_replace(boot_commond, "boot_normal", "boot_recovery");
			/* android recovery will clean the misc */
		}
		else if(!strcmp(misc_message->command, "bootloader"))
		{
			puts("Fastboot detected, will boot fastboot\n");
			sunxi_str_replace(boot_commond, "boot_normal", "boot_fastboot");
			if(misc_offset)
				sunxi_flash_write(misc_offset, 2048/512, misc_fill);
		}
		else if(!strcmp(misc_message->command, "usb-recovery"))
		{
			puts("Recovery detected, will usb recovery\n");
			sunxi_str_replace(boot_commond, "boot_normal", "boot_recovery");
		}
	}
	if(!strcmp(misc_message->command ,"debug_mode"))
	{
		puts("debug_mode detected ,will enter debug_mode");
		if(!change_to_debug_mode())
		{
			check_debug_mode();
		}
			sunxi_flash_write(misc_offset,2048/512,misc_fill);
	}
	setenv("bootcmd", boot_commond);

	printf("to be run cmd=%s\n", boot_commond);
#if 0
	misc_message = (struct bootloader_message *)misc_args;
	if(mode == ANDROID_NULL_MODE)
	{
		misc_offset = sunxi_partition_get_offset_byname("misc");
		if(!misc_offset)
		{
			int pmu_value;

			puts("no misc partition is found\n");
			pmu_value = axp_probe_pre_sys_mode();
			if(pmu_value == PMU_PRE_FASTBOOT_MODE)
			{
				puts("ready to enter fastboot mode\n");
				setenv("bootcmd", "run boot_fastboot");

				return 0;
			}
			else
			{
				printf("to be run cmd=%s\n", boot_commond);
				setenv("bootcmd", boot_commond);

				return 0;
			}
		}
		memset(misc_fill, 0xff, 2048);
#ifdef DEBUG
		tick_printf("misc_offset  : %d\n", (int )misc_offset);
#endif
		sunxi_flash_read(misc_offset, 2048/512, misc_args);
	}
	else if(mode == ANDROID_RECOVERY_MODE)
	{
		strcpy(misc_message->command, "boot-recovery");
	}
	else if(mode == ANDROID_FASTBOOT_MODE)
	{
		strcpy(misc_message->command, "bootloader");
	}
#ifdef DEBUG
	{
		uint *dump_value;

		dump_value = *(uint *)misc_message->command;
		if(dump_value != 0xffffffff)
			printf("misc.command  : %s\n", misc_message->command);
		else
			printf("misc.command  : NULL\n");

		dump_value = *(uint *)misc_message->status;
		if(dump_value != 0xffffffff)
			printf("misc.status  : %s\n", misc_message->status);
		else
			printf("misc.status  : NULL\n");

		dump_value = *(uint *)misc_message->recovery;
		if(dump_value != 0xffffffff)
			printf("misc.recovery  : %s\n", misc_message->recovery);
		else
			printf("misc.recovery  : NULL\n");
	}
#endif
	//判断命令
	if(!strcmp(misc_message->command, "efex"))
	{
		/* there is a recovery command */
		puts("find efex cmd\n");
		sunxi_flash_write(misc_offset, 2048/512, misc_fill);
		sunxi_board_run_fel();

		return 0;
	}

	if(!strcmp(misc_message->command, "boot-resignature"))
	{
		puts("find boot-resignature cmd\n");
		sunxi_flash_write(misc_offset, 2048/512, misc_fill);
		sunxi_oem_op_lock(SUNXI_LOCKING, NULL, 1);
	}
	else if(!strcmp(misc_message->command, "boot-recovery"))
	{
		puts("Recovery detected, will boot recovery\n");
		sunxi_str_replace(boot_commond, "boot_normal", "boot_recovery");
		/* android recovery will clean the misc */
	}
	else if(!strcmp(misc_message->command, "bootloader"))
	{
		puts("Fastboot detected, will boot fastboot\n");
		sunxi_str_replace(boot_commond, "boot_normal", "boot_fastboot");
		if(misc_offset)
			sunxi_flash_write(misc_offset, 2048/512, misc_fill);
	}
	
	setenv("bootcmd", boot_commond);

	printf("to be run cmd=%s\n", boot_commond);
#endif
	return 0;
}