예제 #1
0
int optimus_verify_partition(const char* partName, HIMAGE hImg, char* _errInfo)
{
#define MaxSz (64 - 7) //verify file to at most 64B to corresponding to USB burn, strlen("verify ") == 7

    char* argv[4];
    int ret = 0;
    HIMAGEITEM hImgItem = NULL;
    int imgItemSz = 0;
    char CmdVerify[MaxSz + 7] = {0};

    hImgItem = image_item_open(hImg, "VERIFY", partName);
    if (!hImgItem) {
        DWN_ERR("Fail to open verify file for part (%s)\n", partName);
        return ITEM_NOT_EXIST;
    }

    imgItemSz = (int)image_item_get_size(hImgItem);
    if (imgItemSz > MaxSz || !imgItemSz) {
        DWN_ERR("verify file size %d for part %s invalid, max is %d\n", imgItemSz, partName, MaxSz);
        ret = __LINE__; goto _finish;
    }
    DWN_DBG("item sz %u\n", imgItemSz);

    ret = image_item_read(hImg, hImgItem, CmdVerify, imgItemSz);
    if (ret) {
        DWN_ERR("Fail to read verify item for part %s\n", partName);
        goto _finish;
    }
    CmdVerify[imgItemSz] = 0;
    DWN_DBG("verify[%s]\n", CmdVerify);

    argv[0] = "verify";
    ret = cli_simple_parse_line(CmdVerify, argv + 1);
    if (ret != 2) {
        DWN_ERR("verify cmd argc must be 2, but %d\n", ret);
        return __LINE__;
    }

    ret = optimus_media_download_verify(3, argv, _errInfo);
    if (ret) {
        DWN_ERR("Fail when verify\n");
        return __LINE__;
    }

_finish:
    image_item_close(hImgItem);
    return ret;
}
예제 #2
0
//return value is the size actual write to media
//Paras: const char* partName, const char* imgType, const char* verifyAlgorithm
static u32 optimus_func_download_image(struct ImgBurnInfo* pDownInfo, u32 dataSz, const u8* data, char* errInfo)
{
    int burnSz = 0;
    int ret = 0;
    u64 nextMediaOffset = pDownInfo->nextMediaOffset;
   
    DWN_DBG("data=0x%p, sz=0x%x, offset=%llx\n", data, dataSz, nextMediaOffset);

    ret = optimus_storage_open(pDownInfo, data, dataSz);
    if(OPT_DOWN_OK != ret){
        sprintf(errInfo, "Fail to open stoarge\n");
        DWN_ERR(errInfo);
        return 0;
    }

    burnSz = optimus_storage_write(pDownInfo, nextMediaOffset, dataSz, data, errInfo);
    if(!burnSz){
        DWN_ERR("Fail in optimus_storage_write, data 0x%p, wantSz 0x%x\n", data, dataSz);
        goto _err;
    }
    pDownInfo->imgSzDisposed += burnSz;

    ret = optimus_storage_close(pDownInfo);
    if(ret){
        DWN_ERR("Fail to close media\n");
        return 0;
    }

    return burnSz;

_err:
    optimus_storage_close(pDownInfo);
    pDownInfo->imgBurnSta = OPTIMUS_IMG_STA_BURN_FAILED;////
    return 0;
}
예제 #3
0
int do_sdc_burn(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
    int rcode = 0;
    const char* sdc_cfg_file = argv[1];

    if (argc < 2 ) {
        return CMD_RET_USAGE;
    }

    if ( !aml_check_is_ready_for_sdc_produce() ) {
        DWN_DBG("Not ready\n");
        return __LINE__;
    }

    optimus_work_mode_set(OPTIMUS_WORK_MODE_SDC_UPDATE);
    show_logo_to_report_burning();//indicate enter flow of burning! when 'run update'
    if (optimus_led_open(LED_TYPE_PWM)) {
        DWN_ERR("Fail to open led for burn\n");
        return __LINE__;
    }
    optimus_led_show_in_process_of_burning();

    rcode = optimus_burn_package_in_sdmmc(sdc_cfg_file);

    return rcode;
}
예제 #4
0
//Normal image can write directly to NAND, best aligned to 16K when write
//FIXME: check it aligned to 16K when called
//1, write to media     2 -- save the verify info
static u32 optimus_download_normal_image(struct ImgBurnInfo* pDownInfo, u32 dataSz, const u8* data)
{
    int ret = 0;
    u64 addrOrOffsetInBy = pDownInfo->nextMediaOffset;

    DWN_DBG("addrOffset=0x%x, dataSz=0x%x, data = 0x%x\n", addrOffset, dataSz, data);
    
//FIXME:why dirty value if not convert to u64
    ret = store_write_ops((u8*)pDownInfo->partName, (u8*)data, addrOrOffsetInBy, (u64)dataSz);
    if(ret){
        DWN_ERR("Fail to write to media\n");
        return 0;
    }

    pDownInfo->nextMediaOffset += dataSz;

    return dataSz;
}
예제 #5
0
int optimus_progress_init(const unsigned itemSzHigh, const unsigned itemSzLow, const u32 startStep, const u32 endStep)
{
    _progressInfo.itemSzLow     = itemSzLow;
    _progressInfo.itemSzHigh    = itemSzHigh;

    _progressInfo.startStep     = startStep;
    _progressInfo.endStep       = endStep;
    _progressInfo.currentStep   = startStep;
    _progressInfo.totalStepNum  = endStep - startStep;

    _progressInfo.unReportSzInByte  = 0;//clear it

    //ATTENTION: as divisor / is lossy, _progressInfo.bytesToIncOneStep * _progressInfo.totalStepNum <= item size, so 100% is sometimes not exactly Burn Completed!!
    _progressInfo.bytesToIncOneStep = ((((u64)itemSzHigh)<<32) + itemSzLow) / _progressInfo.totalStepNum;
    _progressInfo.bytesToUpdateStep = (OPTIMUS_PROMPT_SIZE_MIN > _progressInfo.bytesToIncOneStep) ? OPTIMUS_PROMPT_SIZE_MIN : _progressInfo.bytesToIncOneStep;


    DWN_DBG("item size 0x[%x, %x], currentStep %d, totalStepNum %d, bytesToIncOneStep 0x%x\n",
            itemSzHigh, itemSzLow, _progressInfo.currentStep, _progressInfo.totalStepNum, _progressInfo.bytesToIncOneStep);
    return 0;
}
예제 #6
0
int optimus_sdc_burn_partitions(ConfigPara_t* pCfgPara, HIMAGE hImg, __hdle hUiProgress, int NeedVerify)
{
    BurnParts_t* cfgParts = &pCfgPara->burnParts;
    int burnNum       = cfgParts->burn_num;
    int i = 0;
    int rcode = 0;

    //update burn_parts para if burnNum is 0, i.e, not configured
    if (!burnNum)
    {
        rcode = get_burn_parts_from_img(hImg, pCfgPara);
        if (rcode) {
            DWN_ERR("Fail to get burn parts from image\n");
            return __LINE__;
        }
        burnNum = cfgParts->burn_num;
        DWN_DBG("Data part num %d\n", burnNum);
    }
    if (!burnNum) {
        DWN_ERR("Data part num is 0!!\n");
        return __LINE__;
    }

    for (i = 0; i < burnNum; i++)
    {
        const char* partName = cfgParts->burnParts[i];

        rcode = optimus_burn_one_partition(partName, hImg, hUiProgress, NeedVerify);
        if (rcode) {
            DWN_ERR("Fail in burn part %s\n", partName);
            return __LINE__;
        }
    }

    return rcode;
}
예제 #7
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;
}
예제 #8
0
static int _check_partition_table_consistency(const unsigned uboot_bin)
{
    int rc = 0;
    unsigned partitionTableSz = 0;
    const int acsOffsetInSpl   = START_ADDR - AHB_SRAM_BASE;
    const int addrMapFromAhb2Bin = AHB_SRAM_BASE - uboot_bin;

    const struct acs_setting* acsSettingInBin   = NULL;
    unsigned partTabAddrInBin             = 0;
    const struct partitions*  partsTabInBin     = NULL;

    const struct acs_setting* acsSettingInSram  = NULL;
    const struct partitions*  partsTabInSram    = NULL;

    DWN_DBG("uboot_bin 0x%p, acsOffsetInSpl 0x%x, addrMapFromAhb2Bin 0x%x\n", uboot_bin, acsOffsetInSpl, addrMapFromAhb2Bin);
    acsSettingInBin   = (struct acs_setting*)(*(unsigned*)(uboot_bin + acsOffsetInSpl) - addrMapFromAhb2Bin);
    partitionTableSz = acsSettingInBin->partition_table_length;
    DWN_MSG("acsSettingInBin=0x%x, partTabSz=0x%x\n", (unsigned int)acsSettingInBin, partitionTableSz);
    
    if( (unsigned)acsSettingInBin >= uboot_bin + 64*1024 || (unsigned)acsSettingInBin <= uboot_bin){//acs not in the spl
        DWN_MSG("Acs not in the spl of uboot_bin\n");
        return 0;
    }
    if(memcmp(MAGIC_ACS, acsSettingInBin->acs_magic, strlen(MAGIC_ACS))
        || memcmp(TABLE_MAGIC_NAME, acsSettingInBin->partition_table_magic, strlen(TABLE_MAGIC_NAME)))
    {
        DWN_MSG("acs magic OR part magic in ubootin not match\n");
        return 0;//Not to check partTable as acs magic or part magic not match in u-boot.bin, maybe encrypted by AMLETOOL
    }
    partTabAddrInBin  = acsSettingInBin->partition_table_addr - addrMapFromAhb2Bin;
    partsTabInBin     = (const struct partitions*)partTabAddrInBin;

#ifndef CONFIG_MESON_TRUSTZONE
    acsSettingInSram  = (struct acs_setting*)(*(unsigned*)START_ADDR);
#else
    //twice eget value at sram address and copy 1K to memory
    acsSettingInSram  = (struct acs_setting*)meson_trustzone_acs_addr(START_ADDR);
    DWN_MSG("[Trust]acsSettingInSram=0x%p\n", acsSettingInSram);
#endif// #ifndef CONFIG_MESON_TRUSTZONE
    partsTabInSram    = (const struct partitions*)acsSettingInSram->partition_table_addr;
    DWN_MSG("partsTabInSram=0x%p\n", partsTabInSram);

    if(memcmp(MAGIC_ACS, acsSettingInSram->acs_magic, strlen(MAGIC_ACS))
       || memcmp(TABLE_MAGIC_NAME, acsSettingInSram->partition_table_magic, strlen(TABLE_MAGIC_NAME)))
    {
        DWN_MSG("acs magic OR part magic in SPL not match\n");
        return __LINE__;//Not to check partTable as acs magic or part magic not match in SRAM, assert this!!
    }

#ifdef CONFIG_MESON_TRUSTZONE
    partsTabInSram    = (const struct partitions*)meson_trustzone_acs_addr((unsigned)&acsSettingInSram->partition_table_addr);
#endif// #ifndef CONFIG_MESON_TRUSTZONE

    rc = memcmp(partsTabInSram, partsTabInBin, partitionTableSz);
    DWN_MSG("Check parts table %s\n", !rc ? "OK." : "FAILED!");
#if 0//I comment print as str-prefix function (strcmp, strcmp, and .etc) are all not reliable in uboot
    if(rc)
    {
        DWN_MSG("acs_setting    0x%p, 0x%p\n", acsSettingInBin, acsSettingInSram);
        DWN_MSG("partitions     0x%08x, 0x%p\n", partTabAddrInBin, partsTabInSram);
        DWN_MSG("partition_table_addr 0x%x, 0x%x\n", acsSettingInSram->partition_table_addr, acsSettingInBin->partition_table_addr);

        DWN_MSG("part in ubootbin:\n");
        _show_partition_table(partsTabInBin);

        DWN_MSG("part in spl:\n");
        _show_partition_table(partsTabInSram);
        return __LINE__;
    }
#endif//#if 0

    return rc;
}
예제 #9
0
//.NeedVerify: Try to get verify file if .NeedVerify == 1
static int optimus_burn_one_partition(const char* partName, HIMAGE hImg, __hdle hUiProgress, int NeedVerify)
{
    int rcode = 0;
    s64 imgItemSz       = 0;
    s64 leftItemSz      = 0;
    u32 thisReadLen     = 0;
    __hdle hImgItem     = NULL;
    char* downTransBuf  = NULL;//get buffer from optimus_buffer_manager
    const unsigned ItemReadBufSz = OPTIMUS_DOWNLOAD_SLOT_SZ;//read this size from image item each time
    unsigned sequenceNo = 0;
    const char* fileFmt = NULL;
    /*static */char _errInfo[512];
    unsigned itemSizeNotAligned = 0;

    printf("\n");
    DWN_MSG("=====>To burn part [%s]\n", partName);
    optimus_progress_ui_printf("Burning part[%s]\n", partName);
    hImgItem = image_item_open(hImg, "PARTITION", partName);
    if (!hImgItem) {
        DWN_ERR("Fail to open item for part (%s)\n", partName);
        return __LINE__;
    }

    imgItemSz = leftItemSz = image_item_get_size(hImgItem);
    if (!imgItemSz) {
        DWN_ERR("image size is 0 , image of part (%s) not exist ?\n", partName);
        return __LINE__;
    }

    fileFmt = (IMAGE_ITEM_TYPE_SPARSE == image_item_get_type(hImgItem)) ? "sparse" : "normal";

    itemSizeNotAligned = image_item_get_first_cluster_size(hImg, hImgItem);
    leftItemSz        -= itemSizeNotAligned;
    rcode = sdc_burn_buf_manager_init(partName, imgItemSz, fileFmt, itemSizeNotAligned);
    if (rcode) {
        DWN_ERR("fail in sdc_burn_buf_manager_init, rcode %d\n", rcode);
        return __LINE__;
    }

    //for each loop:
    //1, get buffer from buffer_manager,
    //2, read item data to buffer,
    //3, report data ready to buffer_manager
    for (; leftItemSz > 0; leftItemSz -= thisReadLen, sequenceNo++)
    {
        thisReadLen = leftItemSz > ItemReadBufSz ? ItemReadBufSz: (u32)leftItemSz;

        rcode = optimus_buf_manager_get_buf_for_bulk_transfer(&downTransBuf, thisReadLen, sequenceNo, _errInfo);
        if (rcode) {
            DWN_ERR("fail in get buf, msg[%s]\n", _errInfo);
            goto _finish;
        }

		//If the item head is not alinged to FAT cluster, Read it firstly to speed up mmc read
        if (itemSizeNotAligned && !sequenceNo)
        {
            DWN_MSG("itemSizeNotAligned 0x%x\n", itemSizeNotAligned);
            rcode = image_item_read(hImg, hImgItem, downTransBuf - itemSizeNotAligned, itemSizeNotAligned);
            if (rcode) {
                DWN_ERR("fail in read data from item,rcode %d, len 0x%x, sequenceNo %d\n", rcode, itemSizeNotAligned, sequenceNo);
                goto _finish;
            }
        }

        rcode = image_item_read(hImg, hImgItem, downTransBuf, thisReadLen);
        if (rcode) {
            DWN_ERR("fail in read data from item,rcode %d\n", rcode);
            goto _finish;
        }

        rcode = optimus_buf_manager_report_transfer_complete(thisReadLen, _errInfo);
        if (rcode) {
            DWN_ERR("fail in report data ready, rcode %d\n", rcode);
            goto _finish;
        }
        if (hUiProgress)optimus_progress_ui_update_by_bytes(hUiProgress, thisReadLen) ;
    }

    DWN_DBG("BURN part %s %s!\n", partName, leftItemSz ? "FAILED" : "SUCCESS");

_finish:
    image_item_close(hImgItem);

    if (rcode) {
        DWN_ERR("Fail to burn part(%s) with in format (%s) before verify\n", partName, fileFmt);
        optimus_progress_ui_printf("Failed at burn part[%s] befor VERIFY\n", partName);
        return rcode;
    }

#if 1
    if (!NeedVerify) {
            return rcode;
    }
    rcode = optimus_verify_partition(partName, hImg, _errInfo);
    if (ITEM_NOT_EXIST == rcode)
    {
        printf("WRN:part(%s) NOT verified\n", partName);
        return 0;
    }
    if (rcode) {
        printf("Fail in verify part(%s)\n", partName);
        optimus_progress_ui_printf("Failed at VERIFY part[%s]\n", partName);
        return __LINE__;
    }
#endif//#fi 0

    return rcode;
}