5763917827915e699b4a427c6c1d628cb27d81a2
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.
33 #include <sys/ioctl.h>
34 #include <mtd/mtd-user.h>
38 #define TRX_MAGIC 0x30524448 /* "HDR0" */
40 uint32_t magic
; /* "HDR0" */
41 uint32_t len
; /* Length of file including header */
42 uint32_t crc32
; /* 32-bit CRC from flag_version to end of file */
43 uint32_t flag_version
; /* 0:15 flags, 16:31 version */
44 uint32_t offsets
[3]; /* Offsets of partitions from start of header */
47 #define SEAMA_MAGIC 0x17a4a35e
49 #if __BYTE_ORDER == __BIG_ENDIAN
50 #define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24))
51 #elif __BYTE_ORDER == __LITTLE_ENDIAN
52 #define STORE32_LE(X) (X)
54 #error unknown endianness!
57 ssize_t
pread(int fd
, void *buf
, size_t count
, off_t offset
);
58 ssize_t
pwrite(int fd
, const void *buf
, size_t count
, off_t offset
);
61 trx_fixup(int fd
, const char *name
)
63 struct mtd_info_user mtdInfo
;
65 struct trx_header
*trx
;
69 if (ioctl(fd
, MEMGETINFO
, &mtdInfo
) < 0) {
70 fprintf(stderr
, "Failed to get mtd info\n");
75 if (mtdInfo
.size
<= 0) {
76 fprintf(stderr
, "Invalid MTD device size\n");
80 bfd
= mtd_open(name
, true);
81 ptr
= mmap(NULL
, len
, PROT_READ
|PROT_WRITE
, MAP_SHARED
, bfd
, 0);
82 if (!ptr
|| (ptr
== (void *) -1)) {
88 if (trx
->magic
!= TRX_MAGIC
) {
89 fprintf(stderr
, "TRX header not found\n");
93 scan
= ptr
+ offsetof(struct trx_header
, flag_version
);
94 trx
->crc32
= crc32buf(scan
, trx
->len
- (scan
- ptr
));
95 msync(ptr
, sizeof(struct trx_header
), MS_SYNC
|MS_INVALIDATE
);
103 fprintf(stderr
, "Error fixing up TRX header\n");
107 #ifndef target_ar71xx
109 trx_check(int imagefd
, const char *mtd
, char *buf
, int *len
)
111 const struct trx_header
*trx
= (const struct trx_header
*) buf
;
114 if (strcmp(mtd
, "firmware") != 0)
117 *len
= read(imagefd
, buf
, 32);
119 fprintf(stdout
, "Could not get image header, file too small (%d bytes)\n", *len
);
123 /* Allow writing Seama files to firmware without an extra validation */
124 if (trx
->magic
== SEAMA_MAGIC
)
127 if (trx
->magic
!= TRX_MAGIC
|| trx
->len
< sizeof(struct trx_header
)) {
129 fprintf(stderr
, "Bad trx header\n");
130 fprintf(stderr
, "This is not the correct file format; refusing to flash.\n"
131 "Please specify the correct file or use -f to force.\n");
136 /* check if image fits to mtd device */
137 fd
= mtd_check_open(mtd
);
139 fprintf(stderr
, "Could not open mtd device: %s\n", mtd
);
143 if(mtdsize
< trx
->len
) {
144 fprintf(stderr
, "Image too big for partition: %s\n", mtd
);
155 mtd_fixtrx(const char *mtd
, size_t offset
)
158 struct trx_header
*trx
;
164 fprintf(stderr
, "Trying to fix trx header in %s at 0x%x...\n", mtd
, offset
);
166 fd
= mtd_check_open(mtd
);
168 fprintf(stderr
, "Could not open mtd device: %s\n", mtd
);
172 block_offset
= offset
& ~(erasesize
- 1);
173 offset
-= block_offset
;
175 if (block_offset
+ erasesize
> mtdsize
) {
176 fprintf(stderr
, "Offset too large, device size 0x%x\n", mtdsize
);
180 buf
= malloc(erasesize
);
186 res
= pread(fd
, buf
, erasesize
, block_offset
);
187 if (res
!= erasesize
) {
192 trx
= (struct trx_header
*) (buf
+ offset
);
193 if (trx
->magic
!= STORE32_LE(0x30524448)) {
194 fprintf(stderr
, "No trx magic found\n");
198 if (trx
->len
== STORE32_LE(erasesize
- offset
)) {
200 fprintf(stderr
, "Header already fixed, exiting\n");
205 trx
->len
= STORE32_LE(erasesize
- offset
);
207 trx
->crc32
= STORE32_LE(crc32buf((char*) &trx
->flag_version
, erasesize
- offset
- 3*4));
208 if (mtd_erase_block(fd
, block_offset
)) {
209 fprintf(stderr
, "Can't erease block at 0x%x (%s)\n", block_offset
, strerror(errno
));
214 fprintf(stderr
, "New crc32: 0x%x, rewriting block\n", trx
->crc32
);
216 if (pwrite(fd
, buf
, erasesize
, block_offset
) != erasesize
) {
217 fprintf(stderr
, "Error writing block (%s)\n", strerror(errno
));
222 fprintf(stderr
, "Done.\n");