/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ int sunxi_sprite_store_part_data(void *buffer) { int i, j; j = 0; sunxi_mbr_t *mbr = (sunxi_mbr_t *)buffer; for(i=0;i<mbr->PartCount;i++) { printf("part name %s\n", mbr->array[i].name); printf("keydata = 0x%x\n", mbr->array[i].keydata); if( (!strcmp((const char *)mbr->array[i].name, SUNXI_SPRITE_PROTECT_PART)) || (mbr->array[i].keydata == 0x8000)) { printf("find keypart %s\n", mbr->array[i].name); printf("keypart read start: 0x%x, sectors 0x%x\n", mbr->array[i].addrlo, mbr->array[i].lenlo); part_info[j].part_buf = (char *)malloc(mbr->array[i].lenlo * 512); if(!part_info[j].part_buf) { printf("sprite protect private data fail: cant malloc memory for part %s, sectors 0x%x\n", mbr->array[i].name, mbr->array[i].lenlo); goto __sunxi_sprite_store_part_data_fail; } if(!sunxi_sprite_read(mbr->array[i].addrlo, mbr->array[i].lenlo, (void *)part_info[j].part_buf)) { printf("sunxi sprite error : read private data error\n"); goto __sunxi_sprite_store_part_data_fail; } printf("keypart part %s read end: 0x%x, sectors 0x%x\n", mbr->array[i].name, mbr->array[i].addrlo, mbr->array[i].lenlo); part_info[j].part_sectors = mbr->array[i].lenlo; strcpy(part_info[j].part_name, (const char *)mbr->array[i].name); j ++; } } if(!j) { printf("there is no keypart part on local flash\n"); } return 0; __sunxi_sprite_store_part_data_fail: for(i=0;i<j;i++) { if(part_info[i].part_buf) { free(part_info[i].part_buf); } else { break; } } return -1; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ int sunxi_sprite_force_erase_key(void) { char buf[SUNXI_MBR_SIZE * SUNXI_MBR_COPY_NUM]; if(sunxi_sprite_init(1)) { printf("sunxi sprite pre init fail\n"); return -1; } //读出量产介质上的MBR if(!sunxi_sprite_read(0, (SUNXI_MBR_SIZE * SUNXI_MBR_COPY_NUM)/512, buf)) { printf("read local mbr on flash failed\n"); sunxi_sprite_exit(1); return -1; } //校验MBR if(sunxi_sprite_verify_mbr(buf)) { printf("the mbr on flash is bad\n"); sunxi_sprite_exit(1); return -1; } if(sunxi_sprite_erase_private_key(buf)) { printf("erase key fail \n"); return -1; } #ifdef CONFIG_SUNXI_SECURE_STORAGE if(sunxi_secure_storage_init()) return -1; if(sunxi_secure_storage_erase("key_burned_flag") == -1) return -1; #endif printf("erase key success \n"); return 0; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ int sunxi_sprite_erase_flash(void *img_mbr_buffer) { uint32_t need_erase_flag = 0; char buf[SUNXI_MBR_SIZE * SUNXI_MBR_COPY_NUM]; //int ret; int nodeoffset; if(sunxi_sprite_erase(0, img_mbr_buffer) > 0) { printf("flash already erased\n"); return 0; } //获取擦除信息,查看是否需要擦除flash //ret = script_parser_fetch("platform", "eraseflag", &need_erase_flag, 1); nodeoffset = fdt_path_offset(working_fdt,FDT_PATH_PLATFORM); if(nodeoffset > 0) { fdt_getprop_u32(working_fdt,nodeoffset,"eraseflag",&need_erase_flag); } if(need_erase_flag) { printf("do need erase flash\n"); } else { printf("not need erase flash\n"); } //当要求强制擦除,不处理私有数据 if(need_erase_flag == 0x11) { printf("force erase flash\n"); sunxi_sprite_erase(1, img_mbr_buffer); return 0; } //检测不到private分区,即不用保护用户数据 if(!sunxi_sprite_probe_prvt(img_mbr_buffer)) { printf("no part need to protect user data\n"); sunxi_sprite_erase(need_erase_flag, img_mbr_buffer); return 0; } //当初始化失败的时候,直接擦除,不处理私有数据 if(sunxi_sprite_init(1)) { debug("sunxi sprite pre init fail, we have to erase it\n"); sunxi_sprite_exit(1); sunxi_sprite_erase(need_erase_flag, img_mbr_buffer); return 0; } debug("nand pre init ok\n"); //读出量产介质上的MBR if(!sunxi_sprite_read(0, (SUNXI_MBR_SIZE * SUNXI_MBR_COPY_NUM)/512, buf)) { printf("read local mbr on flash failed\n"); sunxi_sprite_exit(1); sunxi_sprite_erase(need_erase_flag, img_mbr_buffer); return 0; } //校验MBR if(sunxi_sprite_verify_mbr(buf)) { printf("the mbr on flash is bad\n"); sunxi_sprite_exit(1); sunxi_sprite_erase(need_erase_flag, img_mbr_buffer); return 0; } printf("begin to store data\n"); if(sunxi_sprite_store_part_data(buf) < 0) { sunxi_sprite_exit(1); return -1; } sunxi_sprite_exit(1); printf("need_erase_flag = %d\n", need_erase_flag); //开始擦除 printf("begin to erase\n"); sunxi_sprite_erase(need_erase_flag, img_mbr_buffer); //开始回写private printf("finish erase\n"); sunxi_sprite_init(0); printf("rewrite\n"); if(sunxi_sprite_restore_part_data(img_mbr_buffer)) { sunxi_sprite_exit(0); return -1; } printf("flash exit\n"); sunxi_sprite_exit(0); return 0; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ uint sunxi_sprite_part_rawdata_verify(uint base_start, long long base_bytes) { uint checksum = 0; uint unaligned_bytes, last_time_bytes; uint rest_sectors; uint crt_start; char *tmp_buf = NULL; tmp_buf = (char *)malloc(VERIFY_ONCE_BYTES); if(!tmp_buf) { printf("sunxi sprite err: unable to malloc memory for verify\n"); return 0; } crt_start = base_start; rest_sectors = (uint)((base_bytes + 511)>>9); unaligned_bytes = (uint)base_bytes & 0x1ff; debug("read total sectors %d\n", rest_sectors); debug("read part start %d\n", crt_start); while(rest_sectors >= VERIFY_ONCE_SECTORS) { if(sunxi_sprite_read(crt_start, VERIFY_ONCE_SECTORS, tmp_buf) != VERIFY_ONCE_SECTORS) { printf("sunxi sprite: read flash error when verify\n"); checksum = 0; goto __rawdata_verify_err; } crt_start += VERIFY_ONCE_SECTORS; rest_sectors -= VERIFY_ONCE_SECTORS; checksum += add_sum(tmp_buf, VERIFY_ONCE_BYTES); debug("check sum = 0x%x\n", checksum); } if(rest_sectors) { if(sunxi_sprite_read(crt_start, rest_sectors, tmp_buf) != rest_sectors) { printf("sunxi sprite: read flash error when verify\n"); checksum = 0; goto __rawdata_verify_err; } if(unaligned_bytes) { last_time_bytes = (rest_sectors - 1) * 512 + unaligned_bytes; } else { last_time_bytes = rest_sectors * 512; } checksum += add_sum(tmp_buf, last_time_bytes); debug("check sum = 0x%x\n", checksum); } __rawdata_verify_err: if(tmp_buf) { free(tmp_buf); } return checksum; }