Как происходит запись прошивки Android с карты Product


Исходный текст sunxi_card_sprite_main
int sunxi_card_sprite_main(int workmode, char *name)
{ int production_media; // обновить носитель
 uchar *img_mbr; //mbr
 sunxi_download_info *dl_map; //dlinfo
 int sprite_next_work;
 int nodeoffset;
 int mbr_num	   = SUNXI_MBR_COPY_NUM;
 int processbar_direct = 0;
 dl_map = (sunxi_download_info *)memalign(CONFIG_SYS_CACHELINE_SIZE,
                               ALIGN(sizeof(sunxi_download_info),
                                 CONFIG_SYS_CACHELINE_SIZE));

 img_mbr = (uchar *)memalign(CONFIG_SYS_CACHELINE_SIZE,
                            ALIGN(1024*1024,
                            CONFIG_SYS_CACHELINE_SIZE));

 memset(img_mbr, 0, ALIGN(1024*1024, CONFIG_SYS_CACHELINE_SIZE));
 memset(dl_map, 0, ALIGN(sizeof(sunxi_download_info), CONFIG_SYS_CACHELINE_SIZE));
 tick_printf("sunxi sprite begin");
 nodeoffset = fdt_path_offset(working_fdt, FDT_PATH_CARD_BOOT);

if (nodeoffset >= 0)
 { if (fdt_getprop_u32(working_fdt, nodeoffset,
		"processbar_direct",  (uint32_t *)&processbar_direct) < 0)
   processbar_direct = 0;
 }

// Является ли текущий носитель прошивки NAND или Card
production_media = get_boot_storage_type();

// Начать отображение анимации
#ifdef CONFIG_SUNXI_SPRITE_CARTOON
	sprite_cartoon_create(processbar_direct);
#endif
// Проверить легальность прошивки
if (sprite_card_firmware_probe(name))
 { printf("sunxi sprite firmware probe fail");
      return -1;
 }
#ifdef CONFIG_SUNXI_SPRITE_CARTOON
	sprite_cartoon_upgrade(5);
#endif
tick_printf("firmware probe ok");
// Получить файл dl_map для управления загруженными данными.
tick_printf("fetch download map");

if (sprite_card_fetch_download_map(dl_map))
 { printf("sunxi sprite error : fetch download map error");
       return -1;
 }
__dump_dlmap(dl_map);

// Получить МБР
tick_printf("fetch mbr");
if (sprite_card_fetch_mbr(img_mbr))
 { printf("sunxi sprite error : fetch mbr error");
      return -1;
 }
__dump_mbr((sunxi_mbr_t *)img_mbr);

// Определить, сохранять ли данные при стирании на основе mbr
tick_printf("begin to erase flash");

#ifdef CONFIG_SUNXI_NAND
   nand_get_mbr((char *)img_mbr, 16 * 1024);
#endif

if (sunxi_sprite_erase_flash(img_mbr))
 { printf("sunxi sprite error: erase flash err");
      return -1;
 }
tick_printf("successed in erasing flash");

if (production_media == STORAGE_NOR)
   	mbr_num = 1;

if (sunxi_sprite_download_mbr(img_mbr,
        ALIGN(sizeof(sunxi_mbr_t) * mbr_num,
        CONFIG_SYS_CACHELINE_SIZE)))
 {  printf("sunxi sprite error: download mbr err");
       return -1;
 }

#ifdef CONFIG_SUNXI_SPRITE_CARTOON
	sprite_cartoon_upgrade(10);
#endif

tick_printf("begin to download part");
// Начать запись раздела
if (sunxi_sprite_deal_part(dl_map))
 { printf("sunxi sprite error : download part error");
      return -1;
 }
tick_printf("successed in downloading part");

#ifdef CONFIG_SUNXI_SPRITE_CARTOON
	sprite_cartoon_upgrade(80);
#endif
sunxi_sprite_exit(1);

if (sunxi_sprite_deal_uboot(production_media))
 { printf("sunxi sprite error : download uboot error");
      return -1;
 }
tick_printf("successed in downloading uboot");

#ifdef CONFIG_SUNXI_SPRITE_CARTOON
	sprite_cartoon_upgrade(90);
#endif
if (sunxi_sprite_deal_boot0(production_media))
 { printf("sunxi sprite error : download boot0 error");
      return -1;
 }
tick_printf("successed in downloading boot0");

#ifdef CONFIG_SUNXI_SPRITE_CARTOON
	sprite_cartoon_upgrade(100);
#endif
printf("CARD OK");
tick_printf("sprite success");
// Программирование завершено
mdelay(3000);

//----- Действия после завершения записи ----------

if (fdt_getprop_u32(working_fdt, nodeoffset, "next_work",
		    (uint32_t *)&sprite_next_work) < 0)
//if(script_parser_fetch("card_boot", "next_work", &sprite_next_work, 1))
 {	sprite_next_work = SUNXI_UPDATE_NEXT_ACTION_SHUTDOWN;
	//sprite_next_work = SUNXI_UPDATE_NEXT_ACTION_REUPDATE;
 }

if (sprite_next_work == SUNXI_UPDATA_NEXT_ACTION_SPRITE_TEST)
 {
 //erase the magic from boot0 head
 printf("try to earse boot0 head :");
 char *boot0_head_buf = NULL;
 boot0_file_head_t *boot0_head = NULL;
 boot0_head_buf = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE,
	                                   ALIGN(1024,
	                                   CONFIG_SYS_CACHELINE_SIZE));

 memset(boot0_head_buf, 0x00, ALIGN(1024, CONFIG_SYS_CACHELINE_SIZE));
 if (!sunxi_flash_phyread(BOOT0_SDMMC_START_ADDR, 1024 / 512,
				 boot0_head_buf))
 printf("sunxi_sprite_error : read boot0 head failed");

 boot0_head = (boot0_file_head_t *)boot0_head_buf;
 printf("%s ", boot0_head->boot_head.magic);
 memset(boot0_head->boot_head.magic, 0x00, 8);

 printf("=====check_sum======%x ",
	boot0_head->boot_head.check_sum);

 if (!sunxi_flash_phywrite(BOOT0_SDMMC_START_ADDR, 1024 / 512,
				  boot0_head_buf))
 printf("sunxi_sprite_error : can not write boot0 head into card ");

 }
 printf("sprite_next_work=%d", sprite_next_work);
 sunxi_update_subsequent_processing(sprite_next_work);
 return 0;

}

//------------------------------------------
void __dump_dlmap(sunxi_download_info *dl_info)
{  dl_one_part_info *part_info;
   u32 i;
   char buffer[32];

printf("*************DOWNLOAD MAP DUMP************");
printf("total download part %d", dl_info->download_count);

for (part_info = dl_info->one_part_info, i = 0;
     i < dl_info->download_count; i++, part_info++)
 { memset(buffer, 0, 32);
  memcpy(buffer, part_info->name, 16);
  printf("download part[%d] name  :%s", i, buffer);
  memset(buffer, 0, 32);
  memcpy(buffer, part_info->dl_filename, 16);
  printf("download part[%d] download file :%s", i, buffer);
  memset(buffer, 0, 32);
  memcpy(buffer, part_info->vf_filename, 16);
  printf("download part[%d] verify file   :%s", i, buffer);
  printf("download part[%d] lenlo   :0x%x", i,
 	       part_info->lenlo);
  printf("download part[%d] addrlo  :0x%x", i,
 	       part_info->addrlo);
  printf("download part[%d] encrypt  :0x%x", i,
 	       part_info->encrypt);
  printf("download part[%d] verify  :0x%x", i,
 	       part_info->verify);
  printf("");
  }
}

//------------------------------------------
void __dump_mbr(sunxi_mbr_t *mbr_info)
{   sunxi_partition *part_info;
    u32 i;
   char buffer[32];

printf("*************MBR DUMP***************");
printf("total mbr part %d", mbr_info->PartCount);
printf("");

for (part_info = mbr_info->array, i = 0; i < mbr_info->PartCount;
     i++, part_info++)
 { memset(buffer, 0, 32);
  memcpy(buffer, part_info->name, 16);
  printf("part[%d] name      :%s", i, buffer);
  memset(buffer, 0, 32);
  memcpy(buffer, part_info->classname, 16);
  printf("part[%d] classname :%s", i, buffer);
  printf("part[%d] addrlo    :0x%x", i, part_info->addrlo);
  printf("part[%d] lenlo     :0x%x", i, part_info->lenlo);
  printf("part[%d] user_type :0x%x", i, part_info->user_type);
  printf("part[%d] keydata   :0x%x", i, part_info->keydata);
  printf("part[%d] ro        :0x%x", i, part_info->ro);
  printf("");
  }
}