static int get_bootloader_message_block_rk29(struct bootloader_message *out,
                                        const Volume* v) {
    FILE* f = NULL;
#ifdef TARGET_RK3188
    if (strcmp(v->fs_type, "emmc") == 0){
        f = fopen(v->blk_device, "rb");
    }else{
        f = fopen("/dev/block/rknand_misc", "rb");
    }
#else
    f = fopen(v->blk_device, "rb");
#endif

    if (f == NULL) {
        LOGE("Can't open %s\n(%s)\n", v->blk_device, strerror(errno));
        return -1;
    }
    const ssize_t size =READ_SIZE * MISC_PAGES;	
    char data[size];
	
    int count = rk29_fread(data, size, 1, f);

    if (count != 1) {
        LOGE("Failed reading %s\n(%s)\n", v->blk_device, strerror(errno));
        fclose(f);
        return -1;
    }
    if (fclose(f) != 0) {
        LOGE("Failed closing %s\n(%s)\n", v->blk_device, strerror(errno));
        return -1;
    }
    memcpy(out, &data[READ_SIZE * MISC_COMMAND_PAGE], sizeof(*out));
    return 0;
}
static int get_bootloader_message_block(struct bootloader_message *out,
                                        const Volume* v) {
    wait_for_device(v->blk_device);
    FILE* f = fopen(v->blk_device, "rb");
    if (f == NULL) {
        LOGE("Can't open %s\n(%s)\n", v->blk_device, strerror(errno));
        return -1;
    }
    struct bootloader_message temp;
#if TARGET_BOARD_PLATFORM == rockchip
    int count = rk29_fread(&temp, sizeof(temp), 1, f);
#else
    int count = fread(&temp, sizeof(temp), 1, f);
#endif
    if (count != 1) {
        LOGE("Failed reading %s\n(%s)\n", v->blk_device, strerror(errno));
        return -1;
    }
    if (fclose(f) != 0) {
        LOGE("Failed closing %s\n(%s)\n", v->blk_device, strerror(errno));
        return -1;
    }
    memcpy(out, &temp, sizeof(temp));
    return 0;
}
static int get_bootloader_message_block_rk29(struct bootloader_message *out,
                                        const Volume* v) {
    FILE* f = fopen(v->blk_device, "rb");
    if (f == NULL) {
        LOGE("Can't open %s\n(%s)\n", v->blk_device, strerror(errno));
        return -1;
    }
    const ssize_t size =READ_SIZE * MISC_PAGES;	
    char data[size];
	
    int count = rk29_fread(data, size, 1, f);

    if (count != 1) {
        LOGE("Failed reading %s\n(%s)\n", v->blk_device, strerror(errno));
        fclose(f);
        return -1;
    }
    if (fclose(f) != 0) {
        LOGE("Failed closing %s\n(%s)\n", v->blk_device, strerror(errno));
        return -1;
    }
    memcpy(out, &data[READ_SIZE * MISC_COMMAND_PAGE], sizeof(*out));
    return 0;
}
static int LoadPartitionContents(const char* filename, FileContents* file) {
    char* copy = strdup(filename);
    const char* magic = strtok(copy, ":");

    enum PartitionType type;
    int emmcEnabled = getEmmcState();
    char temp[64];

    if (strcmp(magic, "MTD") == 0 && emmcEnabled == 0) {
        type = MTD;
    } else if (strcmp(magic, "EMMC") == 0 || emmcEnabled == 1) {
        type = EMMC;
    } else {
        printf("LoadPartitionContents called with bad filename (%s)\n",
               filename);
        return -1;
    }

    const char* partition = strtok(NULL, ":");
    if(emmcEnabled) {
		transformPath(partition, temp);
		partition = temp;
    }

    int i;
    int colons = 0;
    for (i = 0; filename[i] != '\0'; ++i) {
        if (filename[i] == ':') {
            ++colons;
        }
    }
    if (colons < 3 || colons%2 == 0) {
        printf("LoadPartitionContents called with bad filename (%s)\n",
               filename);
    }

    int pairs = (colons-1)/2;     // # of (size,sha1) pairs in filename
    int* index = malloc(pairs * sizeof(int));
    size_t* size = malloc(pairs * sizeof(size_t));
    char** sha1sum = malloc(pairs * sizeof(char*));

    for (i = 0; i < pairs; ++i) {
        const char* size_str = strtok(NULL, ":");
        size[i] = strtol(size_str, NULL, 10);
        if (size[i] == 0) {
            printf("LoadPartitionContents called with bad size (%s)\n", filename);
            return -1;
        }
        sha1sum[i] = strtok(NULL, ":");
        index[i] = i;
    }

    // sort the index[] array so it indexes the pairs in order of
    // increasing size.
    size_array = size;
    qsort(index, pairs, sizeof(int), compare_size_indices);

    MtdReadContext* ctx = NULL;
    FILE* dev = NULL;

    switch (type) {
        case MTD:
            if (!mtd_partitions_scanned) {
                mtd_scan_partitions();
                mtd_partitions_scanned = 1;
            }

            const MtdPartition* mtd = mtd_find_partition_by_name(partition);
            if (mtd == NULL) {
                printf("mtd partition \"%s\" not found (loading %s)\n",
                       partition, filename);
                return -1;
            }

            ctx = mtd_read_partition(mtd);
            if (ctx == NULL) {
                printf("failed to initialize read of mtd partition \"%s\"\n",
                       partition);
                return -1;
            }
            break;

        case EMMC:
            dev = fopen(partition, "rb");
            if (dev == NULL) {
                printf("failed to open emmc partition \"%s\": %s\n",
                       partition, strerror(errno));
                return -1;
            }
    }

    SHA_CTX sha_ctx;
    SHA_init(&sha_ctx);
    uint8_t parsed_sha[SHA_DIGEST_SIZE];

    // allocate enough memory to hold the largest size.
    file->data = malloc(size[index[pairs-1]]);
    char* p = (char*)file->data;
    file->size = 0;                // # bytes read so far

    for (i = 0; i < pairs; ++i) {
        // Read enough additional bytes to get us up to the next size
        // (again, we're trying the possibilities in order of increasing
        // size).
        size_t next = size[index[i]] - file->size;
        size_t read = 0;
        if (next > 0) {
            switch (type) {
                case MTD:
                    read = mtd_read_data(ctx, p, next);
                    break;

                case EMMC:
					//modify by [email protected]
                    read = rk29_fread(p, 1, next, dev);
                    //read = fread(p, 1, next, dev);
                    break;
            }
            if (next != read) {
                printf("short read (%zu bytes of %zu) for partition \"%s\"\n",
                       read, next, partition);
                free(file->data);
                file->data = NULL;
                return -1;
            }
            SHA_update(&sha_ctx, p, read);
            file->size += read;
        }

        // Duplicate the SHA context and finalize the duplicate so we can
        // check it against this pair's expected hash.
        SHA_CTX temp_ctx;
        memcpy(&temp_ctx, &sha_ctx, sizeof(SHA_CTX));
        const uint8_t* sha_so_far = SHA_final(&temp_ctx);

        if (ParseSha1(sha1sum[index[i]], parsed_sha) != 0) {
            printf("failed to parse sha1 %s in %s\n",
                   sha1sum[index[i]], filename);
            free(file->data);
            file->data = NULL;
            return -1;
        }

        if (memcmp(sha_so_far, parsed_sha, SHA_DIGEST_SIZE) == 0) {
            // we have a match.  stop reading the partition; we'll return
            // the data we've read so far.
            printf("partition read matched size %zu sha %s\n",
                   size[index[i]], sha1sum[index[i]]);
            break;
        }

        p += read;
    }

    switch (type) {
        case MTD:
            mtd_read_close(ctx);
            break;

        case EMMC:
            fclose(dev);
            break;
    }


    if (i == pairs) {
        // Ran off the end of the list of (size,sha1) pairs without
        // finding a match.
        printf("contents of partition \"%s\" didn't match %s\n",
               partition, filename);
        free(file->data);
        file->data = NULL;
        return -1;
    }

    const uint8_t* sha_final = SHA_final(&sha_ctx);
    for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
        file->sha1[i] = sha_final[i];
    }

    // Fake some stat() info.
    file->st.st_mode = 0644;
    file->st.st_uid = 0;
    file->st.st_gid = 0;

    free(copy);
    free(index);
    free(size);
    free(sha1sum);

    return 0;
}