Ho scritto un modulo kernel Linux per fungere da driver FPGA per una scheda personalizzata basata su Freescale P2020RDB. Il driver contiene diversi #defines
per specificare vari indirizzi, dimensioni, ampiezze del bus, ecc. Vorrei accedere all'albero del dispositivo appiattito (FDT) della scheda all'interno del driver per configurare questi indirizzi, in modo che il driver possa essere utilizzato per altre schede, dove l'FPGA ha dimensioni diverse o risiede in indirizzi diversi.come accedere e eseguire il debug di una struttura di dispositivi FDT/DTS da un driver Linux (seg-fault)
ho aggiunto il seguente codice semplice funzione di inizializzazione del mio modulo, quale codice ho trovato, mentre le crociere il codice sorgente del kernel 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("/[email protected]");
if (!dt_node) {
printk(KERN_ERR "(E) Failed to find device-tree node: /[email protected]\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;
}
Purtroppo, l'inserimento del modulo produce un errore di segmentazione, mentre solo cercando di trova il nodo del dispositivo.
# 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
Che cosa indica? C'è un modo per verificare che il BLOB dell'albero del dispositivo sia stato correttamente caricato e utilizzabile? Ho bisogno di qualche altro codice di "setup" per prepararmi a una tale richiesta? Oppure sto cercando di usare un cacciavite come un martello?
Grazie!
BTW, ecco la mia FDT (DTS) fonte:
/dts-v1/;
/{
model = "fsl,P2020";
compatible = "fsl,P2020RDB";
#address-cells = <2>;
#size-cells = <2>;
...
[email protected] {
#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";
};
};
Puoi mostrare un disassemblaggio di 'fpga_init'? – ninjalj