+ buf = malloc(data_size);
+ if (!buf) {
+ perror("malloc");
+ exit(1);
+ }
+
+ to = buf;
+ while (data_size) {
+ size_t read_block_offset = data_offset & ~(erasesize - 1);
+ size_t read_chunk;
+
+ read_chunk = erasesize - (data_offset & (erasesize - 1));
+ read_chunk = min(read_chunk, data_size);
+
+ /* Read from good blocks only to match CFE behavior */
+ if (!mtd_block_is_bad(fd, read_block_offset)) {
+ res = pread(fd, to, read_chunk, data_offset);
+ if (res != read_chunk) {
+ perror("pread");
+ exit(1);
+ }
+ to += read_chunk;
+ }
+
+ data_offset += read_chunk;
+ data_size -= read_chunk;
+ }
+ data_size = to - buf;
+
+ trx->len = STORE32_LE(data_size + offsetof(struct trx_header, flag_version));