【问题标题】:Kernel module or user space application内核模块或用户空间应用程序
【发布时间】:2017-05-02 20:30:40
【问题描述】:

我有一个难题。我不知道以下场景的最佳方法是什么,以及花时间开发内核模块是否有意义。

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

  • 模块的基地址;
  • 字段的偏移量(从基地址开始);
  • 每个模块的最大字段数约为 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. 其他。

非常感谢您的任何想法。

【问题讨论】:

  • 用户空间代码几乎总是比内核代码简单。如果可以,请将其保留在用户空间中。
  • FUSE 也可用于实现字符设备。这会给你一些关于多个文件的特定错觉。然而,目前尚不清楚最终消费者应该是什么。无论如何,它是一个单一的应用程序吗?如果是这样,请使用使您的 C++ 实现更安全的技术。听起来您几乎可以将任何“模块”定义为正确制作的结构。
  • @JesperJuhl 是的,内核开发似乎有点复杂。我刚刚开始学习它,就像当我有新东西要学习时我正在享受的程序员一样......你认为在这种情况下开发自定义内核模块没有意义吗?
  • @cnettel “但是,目前尚不清楚最终消费者应该是什么。它还是一个应用程序吗?”在目标设备上,我有使用 python 和 C++ 开发的应用程序,即 GUI、服务器,让远程应用程序与设备通信等等。我也试试FUSE
  • 使用 FPGA 模块的进程之间需要什么样的隔离或保护?

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


【解决方案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)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 2012-08-19
    • 2023-03-12
    • 1970-01-01
    • 2010-10-21
    相关资源
    最近更新 更多