X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/3a0a80e1294f903c0fc271b1e71dba59007b5f61..b2e1bfb056bca17d81fdcbf020d9948a88d17304:/package/mtd/src/fis.c diff --git a/package/mtd/src/fis.c b/package/mtd/src/fis.c index e774e62a6..559ca9506 100644 --- a/package/mtd/src/fis.c +++ b/package/mtd/src/fis.c @@ -1,3 +1,17 @@ +/* + * FIS table updating code for mtd + * + * Copyright (C) 2009 Felix Fietkau + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License v2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include #include #include @@ -63,7 +77,7 @@ fis_open(void) goto error; fis_erasesize = erasesize; - desc = mmap(NULL, erasesize, PROT_READ|PROT_WRITE, MAP_SHARED, fis_fd, 0); + desc = mmap(NULL, erasesize, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, fis_fd, 0); if (desc == MAP_FAILED) goto error; @@ -85,7 +99,7 @@ fis_validate(struct fis_part *old, int n_old, struct fis_part *new, int n_new) desc = fis_open(); if (!desc) - return 0; + return -1; for (i = 0; i < n_new - 1; i++) { if (!new[i].size) { @@ -132,7 +146,7 @@ fis_remap(struct fis_part *old, int n_old, struct fis_part *new, int n_new) struct fis_image_desc *desc; struct fis_part *part; uint32_t offset = 0, size = 0; - char *end, *tmp; + char *start, *end, *tmp; int i; desc = fis_open(); @@ -142,6 +156,7 @@ fis_remap(struct fis_part *old, int n_old, struct fis_part *new, int n_new) if (!quiet) fprintf(stderr, "Updating FIS table... \n"); + start = (char *) desc; end = (char *) desc + fis_erasesize; while ((char *) desc < end) { if (!desc->hdr.name[0] || (desc->hdr.name[0] == 0xff)) @@ -153,9 +168,12 @@ fis_remap(struct fis_part *old, int n_old, struct fis_part *new, int n_new) if (!strcmp((char *) desc->hdr.name, "RedBoot")) redboot = desc; + /* update max offset */ + if (offset < desc->hdr.flash_base) + offset = desc->hdr.flash_base; + for (i = 0; i < n_old; i++) { if (!strncmp((char *) desc->hdr.name, (char *) old[i].name, sizeof(desc->hdr.name))) { - size += desc->hdr.size; last = desc; if (!first) first = desc; @@ -166,13 +184,21 @@ fis_remap(struct fis_part *old, int n_old, struct fis_part *new, int n_new) } desc--; - if (desc == last) { - desc = fisdir; + /* determine size of available space */ + desc = (struct fis_image_desc *) start; + while ((char *) desc < end) { + if (!desc->hdr.name[0] || (desc->hdr.name[0] == 0xff)) + break; + + if (desc->hdr.flash_base > last->hdr.flash_base && + desc->hdr.flash_base < offset) + offset = desc->hdr.flash_base; + + desc++; } + desc--; - /* size fixup */ - if (desc && (last->hdr.flash_base < desc->hdr.flash_base - last->hdr.size)) - size += (desc->hdr.flash_base - last->hdr.flash_base) - last->hdr.size; + size = offset - first->hdr.flash_base; #ifdef notyet desc = first - 1;