Riffa學習——Linux Driver原始碼分析

呵呵复呵呵發表於2024-07-21

目的

Riffa是一個基於FPGA的PCIe介面通訊框架,用於解析PCIe傳送的TLP包,並轉換成資料流形式的讀寫請求,主要用於高速資料通訊。相比於網上已有的如何在FPGA上使用Riffa的資料,筆者決定採用自頂向下的分析方法,先從Riffa的Linux Driver入手,分析上位機軟體是如何完成資料通訊的,然後再結合Verilog原始碼分析其行為,從另一個層面學習Riffa,在此過程也作為學習記錄,也進行分享。

驅動原始碼

根據Riffa2.2公開的原始碼,下載後可以在driver/linux/riffa_driver.c檔案內檢視到大部分的Linux驅動。那麼接下來將從Driver初始化開始,一步一步進行分析。

初始化

 1 /**
 2  * Called to initialize the PCI device. 
 3  */
 4 static int __init fpga_init(void) 
 5 {    
 6     int i;
 7     int error;
 8 
 9     for (i = 0; i < NUM_FPGAS; i++)
10         atomic_set(&used_fpgas[i], 0);
11 
12     error = pci_register_driver(&fpga_driver);
13     if (error != 0) {
14         printk(KERN_ERR "riffa: pci_module_register returned %d\n", error);
15         return (error);
16     }
17 
18     error = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fpga_fops);
19     if (error < 0) {
20         printk(KERN_ERR "riffa: register_chrdev returned %d\n", error);
21         return (error);
22     }
23 
24     #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
25         mymodule_class = class_create(THIS_MODULE, DEVICE_NAME);
26     #else
27         mymodule_class = class_create(DEVICE_NAME);
28     #endif
29 
30     if (IS_ERR(mymodule_class)) {
31         error = PTR_ERR(mymodule_class);
32         printk(KERN_ERR "riffa: class_create() returned %d\n", error);
33         return (error);
34     }
35 
36     devt = MKDEV(MAJOR_NUM, 0);
37     device_create(mymodule_class, NULL, devt, "%s", DEVICE_NAME);
38 
39     return 0;
40 }
41 
42 /**
43  * Called to destroy the PCI device.
44  */
45 static void __exit fpga_exit(void)
46 {
47     device_destroy(mymodule_class, devt); 
48     class_destroy(mymodule_class);
49     pci_unregister_driver(&fpga_driver);
50     unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
51 }

相關文章