内核模块或用户空间应用程序

时间:2017-05-02 20:30:41

标签: c++ linux-kernel linux-device-driver fpga yocto

我陷入两难境地。我不知道对于以下场景的最佳方法是什么,然后是否有必要花时间开发内核模块。

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

  • 模块的基地址;
  • 字段' offset(来自基地址);
  • 每个模块的最大字段数约为10;
  • 每个字段都有自己的类型,如uint32_t,float32_t,uint32_t []等;
  • 某些字段仅读/写,其他字段只读;
  • 通常模块已经就绪。我的意思是没有必要实现任何逻辑来检查是否可以写入字段(少数情况除外)。

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

您认为哪种更好?

  1. 在使用mmap的用户空间中的应用程序(/ dev / mem用于映射所有 模块)然后直接从/向内存读/写。我有一个C ++ 实施,它正在运作,但也许它不是最好的 解决方案......我需要手动设置所有偏移,使用很多 的reinterpret_cast<>正确地读取数据以及是否存在 错误的应用程序崩溃;

  2. 实施角色设备 驱动程序暴露每个模块,如/ dev / module1,/ dev / module2等? 并在用户空间中使用open / write / read / release / ioctl。我刚才 我开始阅读一本关于Linux内核开发的大手册 我不太确定角色设备在这里是不是一个好主意,尤其如此 如何将如此多的字段暴露给用户空间;

  3. 其他。
  4. 非常感谢您的任何想法。

1 个答案:

答案 0 :(得分:1)

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

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

我不建议从头开始编写驱动程序,而是重新调整一些现有的代码。在上面提到的PCI Express案例中,我使用了两个灵感来源 - 这里描述的Xilinx驱动程序:https://www.xilinx.com/support/answers/65444.html(包括来源)和来自ChimeraTk项目的更复杂的'pcieuni'和'gpcieuni'(https://github.com/ChimeraTK