title: how to access and debug a FDT/DTS device tree from a Linux driver (seg-fault)
body: <p>I have written a Linux kernel-module to act as an FPGA driver for a custom board based off the Freescale P2020RDB.  The driver contains several <code>#defines</code> to specify various addresses, sizes, bus-widths, etc.  I would like to access the board's Flattened Device Tree (FDT) from within the driver to configure these addresses, so the driver can be used for other boards, where the FPGA has different sizes or resides at different addresses.</p>
  
  <p>I have added the following simple code to my module's initialization function, which code I found while cruising the Linux kernel source code tree:</p>
  
  <pre><code>...
  #include &lt;linux/of_device.h&gt;
  #include &lt;linux/of_platform.h&gt;
  
  static int __init fpga_init(void) {
  
    struct device_node *dt_node;
    const u8 *property;
    int len;
  
    printk(KERN_INFO "(I) FPGA module loaded at 0x%p\n", fpga_init);
    dt_node = of_find_node_by_path("/fpga_dt@c0000000");
    if (!dt_node) {
      printk(KERN_ERR "(E) Failed to find device-tree node: /fpga_dt@c0000000\n");
      return -ENODEV;
    }
    printk(KERN_INFO "(I) Found device-tree node.  Now retrieving property.\n");
  
    property = of_get_property(dt_node, "reg", &amp;len);
  
    printk(KERN_INFO "(I) reg=0x%08lX\n", (unsigned long) property[0]);
    ...
    return 0;
  }
  </code></pre>
  
  <p>Unfortunately, inserting the module produces a segmentation fault while just trying to find the device node.  </p>
  
  <pre><code># insmod fpga_drv.ko 
  (I) FPGA module loaded at 0xe112d000
  Unable to handle kernel paging request for data at address 0x00000000
  Faulting instruction address: 0xe112d07c
  Oops: Kernel access of bad area, sig: 11 [#1]
  SMP NR_CPUS=2 P2020 RDB
  Modules linked in: fpga_drv(P+)
  NIP: e112d07c LR: e112d078 CTR: c03ed6a4
  REGS: df043e10 TRAP: 0300   Tainted: P            (2.6.32.13)
  MSR: 00029000 &lt;EE,ME,CE&gt;  CR: 24000222  XER: 20000000
  DEAR: 00000000, ESR: 00000000
  TASK = dfb85300[1167] 'insmod' THREAD: df042000 CPU: 1
  GPR00: e112d078 df043ec0 dfb85300 00000000 e11761f4 c05838c4 00000000 dfffc650 
  GPR08: 00000020 00000000 00000012 c03ed6a4 24000282 10098374 1ff92100 10081fc8 
  GPR16: 1007a3e0 1007a434 00000000 00000002 00000000 00000000 bfbe6364 4801f468 
  GPR24: 10094009 1007ca88 c064d07c 00000000 e112d000 c0690000 e1170000 e1170000 
  NIP [e112d07c] fpga_init+0x7c/0x460 [fpga_drv]
  LR [e112d078] fpga_init+0x78/0x460 [fpga_drv]
  Call Trace:
  [df043ec0] [e112d078] fpga_init+0x78/0x460 [fpga_drv] (unreliable)
  [df043ef0] [c0001d94] do_one_initcall+0x3c/0x1e8
  [df043f20] [c0077720] sys_init_module+0xf8/0x220
  [df043f40] [c0010644] ret_from_syscall+0x0/0x3c
  Instruction dump:
  3860ffed 80010034 bb410018 38210030 7c0803a6 4e800020 3c80e117 38a10008 
  388461f4 3fe0e117 4800038d 3fc0e117 &lt;80830000&gt; 3c60e117 386361f8 4cc63182 
  ---[ end trace 40317dd8a9588d98 ]---
  Segmentation fault
  </code></pre>
  
  <p>What does this indicate?  Is there some way to verify that the device tree blob was properly loaded and usable?  Do I need some more "setup" code to prepare for such a query?  Or, am I trying to use a screwdriver as a hammer?</p>
  
  <p>Thanks!</p>
  
  <p>BTW, Here is my FDT (DTS) source:</p>
  
  <pre><code>/dts-v1/;
  / {
      model = "fsl,P2020";
      compatible = "fsl,P2020RDB";
      #address-cells = &lt;2&gt;;
      #size-cells = &lt;2&gt;;
      ...
      fpga_dt@c0000000 {
          #address-cells = &lt;1&gt;;
          #size-cells = &lt;1&gt;;
          compatible = "xilinx,xc6vlx240t", "virtex6";
          model = "xilinx,XC6VLX240T";
          reg = &lt;0xc0000000 1 0xc8000000 0x08000000&gt;;
          label = "Xilinx FPGA XC6VLX240T for My Custom Board";
      };
  };
  </code></pre>