Commit f33665d9 authored by Rod Whitby's avatar Rod Whitby Committed by David Woodhouse

[MTD] Support combined RedBoot FIS directory and configuration area

RedBoot supports storing the FIS directory and the RedBoot
configuration area in the same block of flash memory.  This is
not the most common RedBoot configuration, but it is used on
commercially available boards supported by the kernel.

A recent patch to mtd/redboot.c (http://lkml.org/lkml/2006/3/20/410)
which corrected the skipping of deleted table entries has exposed the
latent problem of the kernel redboot parser running off the end of the
FIS directory and interpreting the RedBoot configuration information
as table entries.

This patch terminates the table parsing when the first truly empty
entry is found (table entry deletion only clears the first byte of the
name, so two cleared bytes in a row indicates the end of the table),
thereby supporting the combined redboot FIS directory and RedBoot
configuration information flash layout scenario.
Signed-off-by: default avatarRod Whitby <rod@whitby.id.au>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent dd11b8cd
...@@ -96,7 +96,19 @@ static int parse_redboot_partitions(struct mtd_info *master, ...@@ -96,7 +96,19 @@ static int parse_redboot_partitions(struct mtd_info *master,
*/ */
if (swab32(buf[i].size) == master->erasesize) { if (swab32(buf[i].size) == master->erasesize) {
int j; int j;
for (j = 0; j < numslots && buf[j].name[0] != 0xff; ++j) { for (j = 0; j < numslots; ++j) {
/* A single 0xff denotes a deleted entry.
* Two of them in a row is the end of the table.
*/
if (buf[j].name[0] == 0xff) {
if (buf[j].name[1] == 0xff) {
break;
} else {
continue;
}
}
/* The unsigned long fields were written with the /* The unsigned long fields were written with the
* wrong byte sex, name and pad have no byte sex. * wrong byte sex, name and pad have no byte sex.
*/ */
...@@ -126,8 +138,13 @@ static int parse_redboot_partitions(struct mtd_info *master, ...@@ -126,8 +138,13 @@ static int parse_redboot_partitions(struct mtd_info *master,
for (i = 0; i < numslots; i++) { for (i = 0; i < numslots; i++) {
struct fis_list *new_fl, **prev; struct fis_list *new_fl, **prev;
if (buf[i].name[0] == 0xff) if (buf[i].name[0] == 0xff) {
if (buf[i].name[1] == 0xff) {
break;
} else {
continue; continue;
}
}
if (!redboot_checksum(&buf[i])) if (!redboot_checksum(&buf[i]))
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment