On 28/02/16(Sun) 16:58, Patrick Wildt wrote:
> 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.

Looks good to me and does not create any regression on Thecus N1200.

I'm going to commit the rebased diff below unless I hear any objection.

Index: dev/ofw//fdt.c
===================================================================
RCS file: /cvs/src/sys/dev/ofw/fdt.c,v
retrieving revision 1.1
diff -u -p -r1.1 fdt.c
--- dev/ofw//fdt.c      3 Mar 2016 02:42:16 -0000       1.1
+++ dev/ofw//fdt.c      6 Mar 2016 14:32:02 -0000
@@ -59,7 +59,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