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; }