内核模块或用户 space 应用程序

Kernel module or user space application

我进退两难。我不知道以下情况的最佳方法是什么,然后花时间开发内核模块是否有意义。

我有像许多模块(大约 30 个)一样暴露的硬件 (FPGA)。每个模块可以这样定义:

在目标设备上有一个自定义 Linux 发行版(从 Yocto 构建)。

你觉得哪个更好?

  1. 用户 space 中使用 mmap(/dev/mem 映射所有 模块)然后 reads/writes 直接 from/to 内存。我有一个 C++ 实施并且它正在运行但也许它不是最好的 解决方案...我需要手动设置所有偏移量,使用许多 reinterpret_cast<> 正确读取数据,如果有的话 错误导致应用程序崩溃;

  2. 实现一个字符设备 驱动程序公开每个模块,如 /dev/module1、/dev/module2 等? 并在用户 space open/write/read/release/ioctl 中使用。我刚刚 开始阅读大量关于 Linux 内核开发的手册,我 我不太确定字符设备在这里是否是个好主意,尤其是 如何向用户公开这么多模块和这么多字段space;

  3. 其他

非常感谢您的任何想法。

使用 /dev/mem 非常简单,但它也会导致一些严重的安全问题。您要么必须 运行 您的应用程序作为 root,要么使 /dev/mem 文件可供其他用户访问,这在设计中都是不受欢迎的,在某些时候将成为产品。如果恶意进程可以访问 /dev/mem 文件,它可能会访问存储在 RAM 中的任何秘密或破坏任何应用程序 - 包括内核本身。即使您的应用程序是唯一能够访问此文件的应用程序,您代码的任何安全问题都会成为整个系统的安全问题。

准备驱动程序显然不是一件容易的事,但允许您将(通常是简单的)特权代码与用户 space 中的应用程序分开。在最简单的情况下,您只需提供一些寄存器读写方法(通过 ioctl)。这些应该检查地址是否对齐并约束到设备地址 space。此外,驱动程序通常会执行任何额外的地址转换 - 因此客户端应用程序不需要知道您的设备映射到哪个物理地址(例如 PCI Express 就是这种情况)。

我不建议从头开始编写驱动程序,而是重新利用一些现有代码。在提到的 PCI Express 案例中,我使用了两个灵感来源 - 此处描述的 Xilinx 驱动程序:https://www.xilinx.com/support/answers/65444.html (sources included) and more complicated 'pcieuni' and 'gpcieuni' from ChimeraTk project (https://github.com/ChimeraTK).