2 * FIS table updating code for mtd
4 * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License v2
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
25 struct fis_image_hdr
{
26 unsigned char name
[16];
32 } __attribute__((packed
));
34 struct fis_image_crc
{
37 } __attribute__((packed
));
39 struct fis_image_desc
{
40 struct fis_image_hdr hdr
;
41 char _pad
[256 - sizeof(struct fis_image_hdr
) - sizeof(struct fis_image_crc
)];
42 struct fis_image_crc crc
;
43 } __attribute__((packed
));
45 static int fis_fd
= -1;
46 static struct fis_image_desc
*fis_desc
;
47 static int fis_erasesize
= 0;
53 munmap(fis_desc
, fis_erasesize
);
62 static struct fis_image_desc
*
65 struct fis_image_desc
*desc
;
70 fis_fd
= mtd_check_open("FIS directory");
75 fis_fd
= mtd_open("FIS directory", true);
79 fis_erasesize
= erasesize
;
80 desc
= mmap(NULL
, erasesize
, PROT_READ
|PROT_WRITE
, MAP_SHARED
|MAP_LOCKED
, fis_fd
, 0);
81 if (desc
== MAP_FAILED
)
93 fis_validate(struct fis_part
*old
, int n_old
, struct fis_part
*new, int n_new
)
95 struct fis_image_desc
*desc
;
104 for (i
= 0; i
< n_new
- 1; i
++) {
106 fprintf(stderr
, "FIS error: only the last partition can detect the size automatically\n");
113 end
= (char *) end
+ fis_erasesize
;
114 while ((void *) desc
< end
) {
115 if (!desc
->hdr
.name
[0] || (desc
->hdr
.name
[0] == 0xff))
118 for (i
= 0; i
< n_old
; i
++) {
119 if (!strncmp((char *) desc
->hdr
.name
, (char *) old
[i
].name
, sizeof(desc
->hdr
.name
))) {
140 fis_remap(struct fis_part
*old
, int n_old
, struct fis_part
*new, int n_new
)
142 struct fis_image_desc
*first
= NULL
;
143 struct fis_image_desc
*last
= NULL
;
144 struct fis_image_desc
*first_fb
= NULL
;
145 struct fis_image_desc
*last_fb
= NULL
;
146 struct fis_image_desc
*desc
;
147 struct fis_part
*part
;
148 uint32_t offset
= 0, size
= 0;
149 char *start
, *end
, *tmp
;
157 fprintf(stderr
, "Updating FIS table... \n");
159 start
= (char *) desc
;
160 end
= (char *) desc
+ fis_erasesize
;
161 while ((char *) desc
< end
) {
162 if (!desc
->hdr
.name
[0] || (desc
->hdr
.name
[0] == 0xff))
165 /* update max offset */
166 if (offset
< desc
->hdr
.flash_base
)
167 offset
= desc
->hdr
.flash_base
;
169 for (i
= 0; i
< n_old
; i
++) {
170 if (!strncmp((char *) desc
->hdr
.name
, (char *) old
[i
].name
, sizeof(desc
->hdr
.name
))) {
184 if (first_fb
->hdr
.flash_base
> last_fb
->hdr
.flash_base
) {
189 /* determine size of available space */
190 desc
= (struct fis_image_desc
*) start
;
191 while ((char *) desc
< end
) {
192 if (!desc
->hdr
.name
[0] || (desc
->hdr
.name
[0] == 0xff))
195 if (desc
->hdr
.flash_base
> last_fb
->hdr
.flash_base
&&
196 desc
->hdr
.flash_base
< offset
)
197 offset
= desc
->hdr
.flash_base
;
203 size
= offset
- first_fb
->hdr
.flash_base
;
206 desc
= first
+ n_new
;
207 offset
= first_fb
->hdr
.flash_base
;
215 memmove(desc
, last
, end
- tmp
);
217 tmp
= end
- (last
- desc
) * sizeof(struct fis_image_desc
);
218 memset(tmp
, 0xff, tmp
- end
);
222 for (part
= new, desc
= first
; desc
< first
+ n_new
; desc
++, part
++) {
223 memset(desc
, 0, sizeof(struct fis_image_desc
));
224 memcpy(desc
->hdr
.name
, part
->name
, sizeof(desc
->hdr
.name
));
226 desc
->crc
.file
= part
->crc
;
228 desc
->hdr
.flash_base
= offset
;
229 desc
->hdr
.mem_base
= part
->loadaddr
;
230 desc
->hdr
.entry_point
= part
->loadaddr
;
231 desc
->hdr
.size
= (part
->size
> 0) ? part
->size
: size
;
232 desc
->hdr
.data_length
= (part
->length
> 0) ? part
->length
:
234 offset
+= desc
->hdr
.size
;
235 size
-= desc
->hdr
.size
;
238 msync(fis_desc
, fis_erasesize
, MS_SYNC
|MS_INVALIDATE
);