как получить доступ к дереву устройств FDT/DTS и отладить его из драйвера Linux (seg-fault)

Я написал модуль ядра Linux, который действует как драйвер FPGA для пользовательской платы на основе Freescale P2020RDB. Драйвер содержит несколько #define для указания различных адресов, размеров, ширины шины и т. д. может использоваться для других плат, где FPGA имеет другие размеры или находится по другим адресам.

Я добавил следующий простой код в функцию инициализации моего модуля, код, который я нашел, изучая дерево исходного кода ядра Linux:

...
#include <linux/of_device.h>
#include <linux/of_platform.h>

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", &len);

  printk(KERN_INFO "(I) reg=0x%08lX\n", (unsigned long) property[0]);
  ...
  return 0;
}

К сожалению, вставка модуля приводит к ошибке сегментации при попытке найти узел устройства.

# 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 <EE,ME,CE>  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 <80830000> 3c60e117 386361f8 4cc63182 
---[ end trace 40317dd8a9588d98 ]---
Segmentation fault

На что это указывает? Есть ли способ убедиться, что большой двоичный объект дерева устройств был правильно загружен и пригоден для использования? Нужен ли мне еще какой-то «установочный» код для подготовки к такому запросу? Или я пытаюсь использовать отвертку вместо молотка?

Спасибо!

Кстати, вот мой источник FDT (DTS):

/dts-v1/;
/ {
    model = "fsl,P2020";
    compatible = "fsl,P2020RDB";
    #address-cells = <2>;
    #size-cells = <2>;
    ...
    fpga_dt@c0000000 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "xilinx,xc6vlx240t", "virtex6";
        model = "xilinx,XC6VLX240T";
        reg = <0xc0000000 1 0xc8000000 0x08000000>;
        label = "Xilinx FPGA XC6VLX240T for My Custom Board";
    };
};
10
задан TheCodeArtist 19 July 2013 в 13:23
поделиться