Esempio n. 1
0
//return value is the data size that actual dealed
static u32 optimus_storage_write(struct ImgBurnInfo* pDownInfo, u64 addrOrOffsetInBy, unsigned dataSz, const u8* data, char* errInfo)
{
    u32 burnSz = 0;
    const u32 imgType = pDownInfo->imgType;
    const int MediaType = pDownInfo->storageMediaType;

    addrOrOffsetInBy += pDownInfo->partBaseOffset;
    DWN_DBG("[0x]Data %p, addrOrOffsetInBy %llx, dataSzInBy %x\n", data, addrOrOffsetInBy, dataSz);

    if(OPTIMUS_IMG_STA_BURN_ING != pDownInfo->imgBurnSta) {
        sprintf(errInfo, "Error burn sta %d\n", pDownInfo->imgBurnSta);
        DWN_ERR(errInfo);
        return 0;
    }

    switch(MediaType)
    {
        case OPTIMUS_MEDIA_TYPE_NAND:
        case OPTIMUS_MEDIA_TYPE_SDMMC:
        case OPTIMUS_MEDIA_TYPE_STORE:
            {
                switch(imgType)
                {
                    case IMG_TYPE_NORMAL:
                        burnSz = optimus_download_normal_image(pDownInfo, dataSz, data);
                        break;

                    case IMG_TYPE_BOOTLOADER:
                        burnSz = optimus_download_bootloader_image(pDownInfo, dataSz, data);
                        break;

                    case IMG_TYPE_SPARSE:
                        burnSz = optimus_download_sparse_image(pDownInfo, dataSz, data);
                        break;

                    default:
                        DWN_ERR("error image type %d\n", imgType);
                }
            }
            break;

        case OPTIMUS_MEDIA_TYPE_KEY_UNIFY:
            {
                burnSz = v2_key_burn(pDownInfo->partName, data, dataSz, errInfo);
                if(burnSz != dataSz){//return value is write size
                    DWN_ERR("burn key failed\n");
                    return 0;
                }
            }
            break;

        case OPTIMUS_MEDIA_TYPE_MEM:
        {
            u8* buf = (u8*)(unsigned)addrOrOffsetInBy;
            if(buf != data){
                DWN_ERR("buf(%llx) != data(%p)\n", addrOrOffsetInBy, data);
                return 0;
            }
            if(!strcmp("dtb", pDownInfo->partName))//as memory write back size = min[fileSz, 2G], so reach here if downloaded ok!
            {
                int rc = 0;
                char* dtbLoadAddr = (char*)CONFIG_DTB_LOAD_ADDR;
                const int DtbMaxSz = (2U<<20);
                unsigned fdtSz = 0;
                unsigned char* destDtb = (unsigned char*)data;

                //Make sure flash already inited before 'run aml_dt'
                //old tool will download dtb before 'disk_initial', but new tool will 'disk_initial' first
                if(is_optimus_storage_inited() || 
                                (OPTIMUS_WORK_MODE_USB_PRODUCE != optimus_work_mode_get()))
                {
                        destDtb = (unsigned char*)get_multi_dt_entry((unsigned int)data);
                }
                rc = fdt_check_header(destDtb);
                if(rc){
                    sprintf(errInfo, "failed at fdt_check_header\n");
                    DWN_ERR(errInfo);
                    return 0;
                }
                fdtSz = fdt_totalsize(destDtb);
                if(DtbMaxSz <= fdtSz){
                    sprintf(errInfo, "failed: fdt header ok but sz 0%x > max 0x%x\n", fdtSz, DtbMaxSz);
                    DWN_ERR(errInfo);
                    return 0;
                }

                DWN_MSG("load dtb to 0x%p\n", dtbLoadAddr);
                memcpy(dtbLoadAddr, destDtb, fdtSz);
            }

            burnSz = dataSz;
        }
        break;

        default:
            sprintf(errInfo, "Error MediaType %d\n", MediaType);
            DWN_ERR(errInfo);
    }

    return burnSz;
}
//store dtb read/write buff size
static int do_store_dtb_ops(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
        int ret = 0;
        char _cmdBuf[128];
        char* ops = argv[2];
        const unsigned maxDtbSz = 256 * 1024;
        unsigned actualDtbSz = 0;
        char* devCmd = NULL;
        char* dtbLoadaddr = argv[3];

        if (argc < 4) return CMD_RET_USAGE;

        const int is_write = !strcmp("write", ops);
        if (!is_write) {
                ret = !strcmp("read", ops) || !strcmp("iread", ops);//must be 0
                if (!ret) return CMD_RET_USAGE;
        }

        actualDtbSz = maxDtbSz;
        if (argc > 4) {
                const unsigned bufSz = simple_strtoul(argv[4], NULL, 0);
                if (bufSz > maxDtbSz) {
                        ErrP("bufSz (%s) > max 0x%x\n", argv[4], maxDtbSz);
                        return CMD_RET_FAILURE;
                }
        }

        ops = is_write ? "dtb_write" : "dtb_read";

        switch (device_boot_flag)
        {
                case NAND_BOOT_FLAG:
                case SPI_NAND_FLAG:
                        {
                                devCmd = "amlnf";
                        }
                        break;

                case EMMC_BOOT_FLAG:
                case SPI_EMMC_FLAG:
                        {
                                devCmd = "emmc";
                        }
                        break;

                default:
                        ErrP("device_boot_flag=0x%x err\n", device_boot_flag);
                        return CMD_RET_FAILURE;
        }

        sprintf(_cmdBuf, "%s %s %s 0x%x", devCmd, ops, dtbLoadaddr, actualDtbSz);
        MsgP("To run cmd[%s]\n", _cmdBuf);
        ret = run_command(_cmdBuf, 0);

#ifdef CONFIG_MULTI_DTB
        if (!is_write && strcmp("iread", ops))
        {
                extern unsigned long get_multi_dt_entry(unsigned long fdt_addr);
                unsigned long dtImgAddr = simple_strtoul(dtbLoadaddr, NULL, 16);

                unsigned long fdtAddr = get_multi_dt_entry(dtImgAddr);
                ret = fdt_check_header((char*)fdtAddr);
                if (ret) {
                        ErrP("Fail in fdt check header\n");
                        return CMD_RET_FAILURE;
                }
                unsigned fdtsz    = fdt_totalsize((char*)fdtAddr);
                memmove((char*)dtImgAddr, (char*)fdtAddr, fdtsz);
        }
#endif// #ifdef CONFIG_MULTI_DTB

        return ret;
}
Esempio n. 3
0
static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	void		*os_hdr;
	int		ret;
#if defined(CONFIG_ANDROID_IMG)
	void	*temp_os_hdr = NULL;
	boot_img_hdr *temp_android_hdr = NULL;
#endif

	memset ((void *)&images, 0, sizeof (images));
	images.verify = getenv_yesno ("verify");

	bootm_start_lmb();

	/* get kernel image header, start address and length */
	os_hdr = boot_get_kernel (cmdtp, flag, argc, argv,
			&images, &images.os.image_start, &images.os.image_len);
	if (images.os.image_len == 0) {
		puts ("ERROR: can't get kernel image!\n");
		return 1;
	}

	/* get image parameters */
	switch (genimg_get_format (os_hdr)) {
	case IMAGE_FORMAT_LEGACY:
		images.os.type = image_get_type (os_hdr);
		images.os.comp = image_get_comp (os_hdr);
		images.os.os = image_get_os (os_hdr);

		images.os.end = image_get_image_end (os_hdr);
		images.os.load = image_get_load (os_hdr);
		break;
#if defined(CONFIG_FIT)
	case IMAGE_FORMAT_FIT:
		if (fit_image_get_type (images.fit_hdr_os,
					images.fit_noffset_os, &images.os.type)) {
			puts ("Can't get image type!\n");
			show_boot_progress (-109);
			return 1;
		}

		if (fit_image_get_comp (images.fit_hdr_os,
					images.fit_noffset_os, &images.os.comp)) {
			puts ("Can't get image compression!\n");
			show_boot_progress (-110);
			return 1;
		}

		if (fit_image_get_os (images.fit_hdr_os,
					images.fit_noffset_os, &images.os.os)) {
			puts ("Can't get image OS!\n");
			show_boot_progress (-111);
			return 1;
		}

		images.os.end = fit_get_end (images.fit_hdr_os);

		if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os,
					&images.os.load)) {
			puts ("Can't get image load address!\n");
			show_boot_progress (-112);
			return 1;
		}
		break;
#endif
#if defined(CONFIG_ANDROID_IMG)
	case IMAGE_FORMAT_ANDROID:
		temp_os_hdr = os_hdr + 0x800;//shift 0x800 Android format head
		temp_android_hdr = (void *) os_hdr;
		images.os.type = image_get_type (temp_os_hdr);
		images.os.comp = image_get_comp (temp_os_hdr);
		images.os.os = image_get_os (temp_os_hdr);

		images.os.end = image_get_image_end (temp_os_hdr);
		images.os.load = image_get_load (temp_os_hdr);
		images.rd_start = ((ulong)temp_android_hdr->kernel_size + 0x800 + (ulong)os_hdr 
			+  ((ulong)temp_android_hdr->page_size - 1)) & (~((ulong)temp_android_hdr->page_size - 1));
		images.rd_end = images.rd_start + (ulong)temp_android_hdr->ramdisk_size;
		printf("    Ramdisk start addr = 0x%x, len = 0x%x\n",images.rd_start,temp_android_hdr->ramdisk_size );
#if defined(CONFIG_OF_LIBFDT)
		if(images.ft_len = (ulong)temp_android_hdr->second_size)
		{
			fdt_addr = (images.rd_end
				+ ((ulong)temp_android_hdr->page_size - 1)) & (~((ulong)temp_android_hdr->page_size - 1));
			/*get_multi_dt_entry, compatible with single dt*/
			fdt_addr = get_multi_dt_entry(fdt_addr);
			images.ft_addr = (char *)fdt_addr;
			images.ft_len = fdt_totalsize(fdt_addr);
			printf("    Flat device tree start addr = 0x%x, len = 0x%x magic=0x%x\n",
			(int *)images.ft_addr,images.ft_len,*(unsigned int*)images.ft_addr);
		}
#endif
		break;
#endif
	default:
		puts ("ERROR: unknown image format type!\n");
		return 1;
	}

	/* find kernel entry point */
	if (images.legacy_hdr_valid) {
		images.ep = image_get_ep (&images.legacy_hdr_os_copy);
#if defined(CONFIG_FIT)
	} else if (images.fit_uname_os) {
		ret = fit_image_get_entry (images.fit_hdr_os,
				images.fit_noffset_os, &images.ep);
		if (ret) {
			puts ("Can't get entry point property!\n");
			return 1;
		}
#endif
	} else {
		puts ("Could not find kernel entry point!\n");
		return 1;
	}

	if (((images.os.type == IH_TYPE_KERNEL) ||
	     (images.os.type == IH_TYPE_MULTI)) &&
	    (images.os.os == IH_OS_LINUX)) {
		/* find ramdisk */
#ifndef CONFIG_ANDROID_IMG
#if defined(CONFIG_AML_MESON_FIT)
		//call boot_get_ramdisk() here for get ramdisk start addr
		boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH,
						&images.rd_start, &images.rd_end);
#endif
#endif

#if defined(CONFIG_ANDROID_IMG)
		if(!images.rd_start)
#endif
		{
			ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH,
					&images.rd_start, &images.rd_end);
			if (ret) {
				puts ("Ramdisk image is corrupt or invalid\n");
				return 1;
			}
		}

#if defined(CONFIG_OF_LIBFDT)
		/* find flattened device tree */
#if defined(CONFIG_ANDROID_IMG)
		if(!images.ft_addr)
#endif
		{
			ret = boot_get_fdt (flag, argc, argv, &images,
					    &images.ft_addr, &images.ft_len);
			if (ret) {
				puts ("Could not find a valid device tree\n");
				return 1;
			}
		}

		set_working_fdt_addr(images.ft_addr);
#endif
	}

#if defined(CONFIG_ANDROID_IMG)
	images.os.start = (ulong)temp_os_hdr;
#else
	images.os.start = (ulong)os_hdr;
#endif
	
	images.state = BOOTM_STATE_START;

	return 0;
}