void image_flash_notify(unsigned long load_addr)
{
#ifdef CONFIG_OF_LIBFDT
	char cmd[128];
	unsigned long base_emmc_addr, dtb_load_addr, dtb_emmc_addr;
	int recovery_flag = 0;
	struct andr_img_hdr *ahdr =
		(struct andr_img_hdr *)(CONFIG_LOADADDR - 0x1000 - 0x200);

	/*load_op bit[3] flash dtb to mmc */
	if (load_op & MV_DTB_FLASH) {
		recovery_flag = get_recovery_flag();
		base_emmc_addr = recovery_flag ?
			RECOVERYIMG_EMMC_ADDR : BOOTIMG_EMMC_ADDR;

		/* Load DTB */
		dtb_load_addr = load_addr;
		load_image_head(ahdr, base_emmc_addr);
		dtb_emmc_addr = dtb_emmc_lookup(ahdr, base_emmc_addr) / 512;

		printf("write dtb to mmc 0x%lx\n", dtb_emmc_addr);
		sprintf(cmd, "%s; mmc write %lx %lx %x", CONFIG_MMC_BOOT_DEV,
			dtb_load_addr, dtb_emmc_addr, DTB_SIZE / 512);
		run_command(cmd, 0);
	}
#endif
}
static int app_tag_read_proc(char* page, char** start, off_t off, int count, int* eof, void *data)
{
    int len = 0;
    u32 charge_flag;
	u32 recovery_flag;  

	recovery_flag = get_recovery_flag();
    charge_flag = get_charge_flag();
    
    len = snprintf(page, PAGE_SIZE,
					"recovery_flag:\n%d\n"
					"charge_flag:\n%d\n",
					recovery_flag,
					charge_flag);
    return proc_calc_metrics(page, start, off, count, eof, len);
}
int do_dtb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char cmd[128];
	unsigned long base_emmc_addr, dtb_load_addr, dtb_emmc_addr;
	int recovery_flag = 0;
	struct andr_img_hdr *ahdr =
		(struct andr_img_hdr *)(CONFIG_LOADADDR - 0x1000 - 0x200);

	if (argc > 3)
		return cmd_usage(cmdtp);

	if (argc == 1) {
		recovery_flag = get_recovery_flag();
		/* Load DTB from emmc */
		dtb_load_addr = DTB_LOADADDR;
		base_emmc_addr = recovery_flag ?
			RECOVERYIMG_EMMC_ADDR : BOOTIMG_EMMC_ADDR;
		load_image_head(ahdr, base_emmc_addr);
		dtb_emmc_addr = dtb_emmc_lookup(ahdr, base_emmc_addr) / 512;
		printf("Load dtb to 0x%lx\n", dtb_load_addr);
		sprintf(cmd, "mmc read %lx %lx %x", dtb_load_addr,
				dtb_emmc_addr, DTB_SIZE / 512);
		run_command(cmd, 0);

		load_op |= MV_DTB_LOADED;
		return 0;
	}
	/*load_op bit[3] flash dtb to mmc */
	if ((argc == 3) && !strcmp(argv[1], "b"))
		load_op |= MV_DTB_FLASH;

	sprintf(cmd, "tftpboot 0x%x %s",
		DTB_LOADADDR, argc == 3 ? argv[2] : argv[1]);
	run_command(cmd, 0);

	return 0;
}
int do_mrvlboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char cmd[128];
	char cmdline[COMMAND_LINE_SIZE];
	char *bootargs;
	unsigned int kernel_offset = 0, ramdisk_offset = KERNEL_SIZE;
	unsigned int kernel_size = KERNEL_SIZE, ramdisk_size = RAMDISK_SIZE;
	unsigned long base_emmc_addr, kernel_load_addr, ramdisk_load_addr;
	int recovery_flag = 0;
	int fastboot_flag = 0;
#ifdef CONFIG_OF_LIBFDT
	unsigned long dtb_load_addr, dtb_emmc_addr;
	struct fdt_header *devtree;
#endif
#ifdef CONFIG_MULTIPLE_SLOTS
	int slot;
#endif
        block_dev_desc_t *dev;
        disk_partition_t info;
        unsigned long recovery_image_addr;

	/* The bootimg/recoveryimg header + uImage header ddr parse address */
	struct andr_img_hdr *ahdr =
		(struct andr_img_hdr *)(CONFIG_LOADADDR - 0x1000 - 0x200);

	recovery_flag = get_recovery_flag();
	fastboot_flag = fastboot_key_detect();

        dev = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
        if(!dev){
                printf("Failed to get mmc device!\n");
                return -1;
        }
        /*Parse flash address from the partition name*/ 
        if (get_partition_info_efi_by_name(dev, "recovery", &info)){
                printf("Failed to get partition(recovery) info!\n");
                return -1;
        }
        recovery_image_addr = info.start * dev->blksz;

	/*
	 * OBM doesn't load kernel and ramdisk for nontrusted boot, but it
	 * still passes validation_status and loading_status as 1 to uboot
	 * since uboot is loaded and validated.
	 * Always load the kernel and ramdisk here to solve this problem,
	 * negative impact of a little boot time.
	 */
#ifdef CONFIG_MULTIPLE_SLOTS
	slot = bootctrl_find_boot_slot();
	if (slot == -1)
		recovery_flag = 1;

	base_emmc_addr = recovery_flag ? recovery_image_addr :
							bootctrl_get_boot_addr(slot);
#else
        if(get_partition_info_efi_by_name(dev, "boot", &info)){
                printf("Failed to get partition(boot) info!\n");
                return -1;
        }
        unsigned long boot_image_addr = info.start * dev->blksz;

	base_emmc_addr = recovery_flag ? recovery_image_addr : boot_image_addr;
#endif

	load_image_head(ahdr, base_emmc_addr);

	if (!memcmp(ANDR_BOOT_MAGIC, ahdr->magic, ANDR_BOOT_MAGIC_SIZE)) {
		printf("This is Android %s image\n",
		       recovery_flag ? "recovery" : "boot");
		kernel_offset = ahdr->page_size;
		kernel_size = ALIGN(ahdr->kernel_size, ahdr->page_size);
		ramdisk_offset = kernel_offset + kernel_size;
		ramdisk_size = ALIGN(ahdr->ramdisk_size, ahdr->page_size);
	}
	/* calculate mmc block number */
	kernel_offset /= dev->blksz;
	ramdisk_offset /= dev->blksz;
	kernel_size /= dev->blksz;
	ramdisk_size /= dev->blksz;

	/* Load kernel */
	kernel_load_addr = CONFIG_LOADADDR;
	if ((load_op & MV_KERNEL_LOADED) == 0) {
		printf("Load kernel to 0x%lx\n", kernel_load_addr);
		sprintf(cmd, "mmc read %lx %lx %x", kernel_load_addr,
			base_emmc_addr / 512 + kernel_offset, kernel_size);
		run_command(cmd, 0);
	}

	/* Load ramdisk */
	ramdisk_load_addr = RAMDISK_LOADADDR;
	if ((load_op & MV_RAMDISK_LOADED) == 0) {
		printf("Load ramdisk to 0x%lx\n", ramdisk_load_addr);
		sprintf(cmd, "mmc read %lx %lx %x", ramdisk_load_addr,
			base_emmc_addr / 512 + ramdisk_offset, ramdisk_size);
		run_command(cmd, 0);
	}

	/* Modify ramdisk command line */
	bootargs = getenv("bootargs");
	strncpy(cmdline, bootargs, COMMAND_LINE_SIZE);
	remove_cmdline_param(cmdline, "initrd=");
	sprintf(cmdline + strlen(cmdline),  " initrd=0x%lx,10m rw",
		ramdisk_load_addr);

	if (recovery_flag)
		sprintf(cmdline + strlen(cmdline), " recovery=1");

#ifdef CONFIG_MULTIPLE_SLOTS
	if(slot >= 0)
		sprintf(cmdline + strlen(cmdline), " androidboot.slot_suffix=%s",
				bootctrl_get_boot_slot_suffix(slot));
#endif

	setenv("bootargs", cmdline);

#ifdef CONFIG_OF_LIBFDT
	/* Load DTB */
	dtb_load_addr = DTB_LOADADDR;
	if ((load_op & MV_DTB_LOADED) == 0) {
		dtb_emmc_addr = dtb_emmc_lookup(ahdr, base_emmc_addr);
		printf("Load dtb to 0x%lx\n", dtb_load_addr);
		sprintf(cmd, "mmc read %lx %lx %x", dtb_load_addr,
			dtb_emmc_addr / 512, DTB_SIZE / 512);
		run_command(cmd, 0);
	}

	devtree = (struct fdt_header *)dtb_load_addr;
	if (be32_to_cpu(devtree->magic) == FDT_MAGIC) {
		handle_dtb(devtree);
		sprintf(cmd, "fdt addr 0x%lx; bootm 0x%lx - 0x%lx",
			dtb_load_addr, kernel_load_addr, dtb_load_addr);
	} else
#endif
//#if !defined(CONFIG_CMD_BOOTZ) || defined(CONFIG_OF_LIBFDT)
#ifndef CONFIG_BOOTZIMAGE
 		sprintf(cmd, "bootm 0x%lx", kernel_load_addr);
#else
		/* zImage-dtb option */
		sprintf(cmd, "bootz 0x%lx", kernel_load_addr);
#endif

	if (fastboot_flag) {
		printf("mrvlboot, fastboot mode\n");
		fastboot_key_set_led();
		run_command("fb", 0);
		return 0;
	} else
		printf("mrvlboot, normal mode\n");

	run_command(cmd, 0);

	return 0;
}