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 }
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 }
/* ************************************************************************************************************ * * 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; }
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; }
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; }
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; }
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 }
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; }
/* ************************************************************************************************************ * * 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; } } }
/* ************************************************************************************************************ * * 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(§ors,(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; }
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; }