Hi,

unfortunately the end signature check is still not correct.  Consulting
the spec cleared the confusion of why the check does not work on my ARM
machines.

The FDT tree contains a "structure block".  The FDT header contains
information, on which offset that block starts.  Since version 17 of
the spec there's another bit of information in the header.  It's the
size of the structure block.  Now the end of the structure block is
marked by an FDT_END marker.

The spec says that there shall only be one FDT_END token, and it should
be the last _in_ the structure block.  And the byte following that token
has the offset fh_struct_size + fh_struct_off from the root header.

Now essentially we have to look for that tag at:

  fdt + fh_struct_size + fh_struct_off - 1

The following diff allows fdt_init() to succeed in my tests.

Patrick

diff --git sys/arch/socppc/socppc/fdt.c sys/arch/socppc/socppc/fdt.c
index 0dec4fb..8535c33 100644
--- sys/arch/socppc/socppc/fdt.c
+++ sys/arch/socppc/socppc/fdt.c
@@ -60,7 +60,8 @@ fdt_check_head(void *fdt)
 
        /* check for end signature on version 17 blob */
        if ((betoh32(fh->fh_version) >= 17) &&
-           (betoh32(*(ptr + betoh32(fh->fh_struct_size))) != FDT_END))
+           (betoh32(*(ptr + (betoh32(fh->fh_struct_off) / 4) +
+           (betoh32(fh->fh_struct_size) / 4) - 1)) != FDT_END))
                return 0;
 
        return betoh32(fh->fh_version);

Reply via email to