4 * Copyright (C) 2005 Mike Baker
5 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include <sys/ioctl.h>
33 #include <mtd/mtd-user.h>
37 #define TRX_MAGIC 0x30524448 /* "HDR0" */
39 uint32_t magic
; /* "HDR0" */
40 uint32_t len
; /* Length of file including header */
41 uint32_t crc32
; /* 32-bit CRC from flag_version to end of file */
42 uint32_t flag_version
; /* 0:15 flags, 16:31 version */
43 uint32_t offsets
[3]; /* Offsets of partitions from start of header */
46 #if __BYTE_ORDER == __BIG_ENDIAN
47 #define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24))
48 #elif __BYTE_ORDER == __LITTLE_ENDIAN
49 #define STORE32_LE(X) (X)
51 #error unknown endianness!
54 ssize_t
pread(int fd
, void *buf
, size_t count
, off_t offset
);
55 ssize_t
pwrite(int fd
, const void *buf
, size_t count
, off_t offset
);
58 trx_fixup(int fd
, const char *name
)
60 struct mtd_info_user mtdInfo
;
62 struct trx_header
*trx
;
66 if (ioctl(fd
, MEMGETINFO
, &mtdInfo
) < 0) {
67 fprintf(stderr
, "Failed to get mtd info\n");
72 if (mtdInfo
.size
<= 0) {
73 fprintf(stderr
, "Invalid MTD device size\n");
77 bfd
= mtd_open(name
, true);
78 ptr
= mmap(NULL
, len
, PROT_READ
|PROT_WRITE
, MAP_SHARED
, bfd
, 0);
79 if (!ptr
|| (ptr
== (void *) -1)) {
85 if (trx
->magic
!= TRX_MAGIC
) {
86 fprintf(stderr
, "TRX header not found\n");
90 scan
= ptr
+ offsetof(struct trx_header
, flag_version
);
91 trx
->crc32
= crc32buf(scan
, trx
->len
- (scan
- ptr
));
92 msync(ptr
, sizeof(struct trx_header
), MS_SYNC
|MS_INVALIDATE
);
100 fprintf(stderr
, "Error fixing up TRX header\n");
105 trx_check(int imagefd
, const char *mtd
, char *buf
, int *len
)
107 const struct trx_header
*trx
= (const struct trx_header
*) buf
;
110 if (strcmp(mtd
, "linux") != 0)
113 *len
= read(imagefd
, buf
, 32);
115 fprintf(stdout
, "Could not get image header, file too small (%d bytes)\n", *len
);
119 if (trx
->magic
!= TRX_MAGIC
|| trx
->len
< sizeof(struct trx_header
)) {
121 fprintf(stderr
, "Bad trx header\n");
122 fprintf(stderr
, "This is not the correct file format; refusing to flash.\n"
123 "Please specify the correct file or use -f to force.\n");
128 /* check if image fits to mtd device */
129 fd
= mtd_check_open(mtd
);
131 fprintf(stderr
, "Could not open mtd device: %s\n", mtd
);
135 if(mtdsize
< trx
->len
) {
136 fprintf(stderr
, "Image too big for partition: %s\n", mtd
);
146 mtd_fixtrx(const char *mtd
, size_t offset
)
149 struct trx_header
*trx
;
155 fprintf(stderr
, "Trying to fix trx header in %s at 0x%x...\n", mtd
, offset
);
157 block_offset
= offset
& ~(erasesize
- 1);
158 offset
-= block_offset
;
160 fd
= mtd_check_open(mtd
);
162 fprintf(stderr
, "Could not open mtd device: %s\n", mtd
);
166 if (block_offset
+ erasesize
> mtdsize
) {
167 fprintf(stderr
, "Offset too large, device size 0x%x\n", mtdsize
);
171 buf
= malloc(erasesize
);
177 res
= pread(fd
, buf
, erasesize
, block_offset
);
178 if (res
!= erasesize
) {
183 trx
= (struct trx_header
*) (buf
+ offset
);
184 if (trx
->magic
!= STORE32_LE(0x30524448)) {
185 fprintf(stderr
, "No trx magic found\n");
189 if (trx
->len
== STORE32_LE(erasesize
- offset
)) {
191 fprintf(stderr
, "Header already fixed, exiting\n");
196 trx
->len
= STORE32_LE(erasesize
- offset
);
198 trx
->crc32
= STORE32_LE(crc32buf((char*) &trx
->flag_version
, erasesize
- offset
- 3*4));
199 if (mtd_erase_block(fd
, block_offset
)) {
200 fprintf(stderr
, "Can't erease block at 0x%x (%s)\n", block_offset
, strerror(errno
));
205 fprintf(stderr
, "New crc32: 0x%x, rewriting block\n", trx
->crc32
);
207 if (pwrite(fd
, buf
, erasesize
, block_offset
) != erasesize
) {
208 fprintf(stderr
, "Error writing block (%s)\n", strerror(errno
));
213 fprintf(stderr
, "Done.\n");
This page took 0.049507 seconds and 5 git commands to generate.