@@ -156,9 +156,10 @@ mtd_fixtrx(const char *mtd, size_t offset, size_t data_size)
int fd;
struct trx_header *trx;
char *first_block;
- char *buf;
+ char *buf, *to;
ssize_t res;
size_t block_offset;
+ size_t read_offset, read_size;
if (quiet < 2)
fprintf(stderr, "Trying to fix trx header in %s at 0x%x...\n", mtd, offset);
@@ -214,10 +215,38 @@ mtd_fixtrx(const char *mtd, size_t offset, size_t data_size)
exit(1);
}
- res = pread(fd, buf, data_size, data_offset);
- if (res != data_size) {
- perror("pread");
- exit(1);
+ read_offset = data_offset;
+ read_size = data_size;
+ to = buf;
+ while (read_size) {
+ size_t read_block_offset = read_offset & ~(erasesize - 1);
+ size_t read_chunk;
+
+ read_chunk = erasesize - (read_offset & (erasesize - 1));
+ read_chunk = read_chunk > read_size ? read_size : read_chunk;
+
+ res = ioctl(fd, MEMGETBADBLOCK, &read_block_offset);
+ if (res == -1) {
+ perror("ioctl");
+ exit(1);
+ }
+
+ /* Skip bad block to match CFE behavior */
+ if (res) {
+ read_offset += read_chunk;
+ read_size -= read_chunk;
+ continue;
+ }
+
+ res = pread(fd, to, read_chunk, read_offset);
+ if (res != read_chunk) {
+ perror("pread");
+ exit(1);
+ }
+
+ read_offset += read_chunk;
+ read_size -= read_chunk;
+ to += read_chunk;
}
trx->len = STORE32_LE(data_size + offsetof(struct trx_header, flag_version));
@@ -244,4 +273,3 @@ mtd_fixtrx(const char *mtd, size_t offset, size_t data_size)
return 0;
}
-