On IXP4XX systems the FIS directory is big endian even with a little endian kernel. This patch recognises the FIS directory on such a system and byte swaps it to obtain a valid table based on the 'size' field of the FIS directory (the size field is know to always match the erase block size on such systems, and probably all systems.) --- linux-2.6.13/.pc/10-mtdpart-redboot-fis-byteswap.patch/drivers/mtd/redboot.c 2005-08-28 16:41:01.000000000 -0700 +++ linux-2.6.13/drivers/mtd/redboot.c 2005-10-23 21:44:59.999694674 -0700 @@ -89,8 +89,34 @@ i = numslots; break; } - if (!memcmp(buf[i].name, "FIS directory", 14)) + if (!memcmp(buf[i].name, "FIS directory", 14)) { + /* This is apparently the FIS directory entry for the + * FIS directory itself. The FIS directory size is + * one erase block, if the buf[i].size field is + * swab32(erasesize) then we know we are looking at + * a byte swapped FIS directory - swap all the entries! + * (NOTE: this is 'size' not 'data_length', size is + * the full size of the entry.) + */ + if (swab32(buf[i].size) == master->erasesize) { + int j; + for (j = 0; j < numslots && buf[j].name[0] != 0xff; ++j) { + /* The unsigned long fields were written with the + * wrong byte sex, name and pad have no byte sex. + */ +# define do_swab32(x) (x) = swab32(x) + do_swab32(buf[j].flash_base); + do_swab32(buf[j].mem_base); + do_swab32(buf[j].size); + do_swab32(buf[j].entry_point); + do_swab32(buf[j].data_length); + do_swab32(buf[j].desc_cksum); + do_swab32(buf[j].file_cksum); +# undef do_swab32 + } + } break; + } } if (i == numslots) { /* Didn't find it */