Linux 内核设备驱动程序需要访问用户空间中的共享对象

Linux Kernel device driver needs access to shared object in userspace

我正在尝试为 Linux 编写网络设备驱动程序。我拥有的设备有一个 API 可用,它允许我通过用户空间中存在的共享对象访问我需要的所有功能。

我想编写一个网络驱动程序,使设备显示为 CAN 接口。但是,为了与设备交互,我需要使用用户空间中存在的特定共享对象。

我需要网络设备驱动程序的原因是公开一个可以通过 SocketCAN 实用程序与之交互的 CAN 接口。

有没有办法在用户空间编写网络设备驱动程序?或者对我来说构建解决方案的最佳方式是什么?

Tl;博士

需要为只能通过提供的公开 API 的共享对象从用户空间与之交互的设备编写设备驱动程序。我需要设备显示为网络接口,以便利用 SocketCAN 实用程序和其他与 Linux.

中的 CAN 接口通信的应用程序

我在这里有哪些选择?我能做什么?

谢谢!

所以你是说你的网络设备在内核中根本没有 driver,只能通过一些 user-space 库访问?在那种情况下,您提到的共享库应该通过 memory mapping your /dev/mem file, in order to be able to read/write to hardware registers. Or perhaps by using some UIO.

与您的网络设备通信

所以你的 driver 也应该在 user-space 中开发然后......那么你应该问的实际问题是如何使用 user-space 中的内核 CAN API ?一开始有可能吗?我猜你应该看看 Documentation/networking/can.txt 的答案。如果答案是 "no"(意味着你不能从 user-space 公开 CAN 接口),那么你还应该开发一些内核 driver 来与你的 user-space 部分交互, 暴露 CAN 接口。

在理想世界中,整个 driver 架构看起来像这样:

但是您需要使用一些(proprietary,如果我理解正确的话)共享库 API 来与您的设备交互。所以我建议你使用下一个 driver 架构,如下图所示:

  • 蓝色颜色代表需要开发的部分
  • 洋红色 用于已存在的代码

简而言之,您的应用程序和 driver 都在 SocketCAN API 和共享库 API.

之间创建一个 shim

所以你需要开发2个组件:

  1. Driver(在内核端)。它负责:
    • SocketCAN 公用事业公司交谈
    • 与您的 user-space 应用程序交谈
  2. 申请(在user-space);它可能应该是 daemon,因为它将一直是 运行。它负责:
    • 与共享库对话
    • 正在与您的 driver
    • 交谈

最后一个问题是要使用哪个内核 API 在内核 space driver 和 user-space 应用程序(标记为 IPC on picture). It strictly depends on which kind of data you are going to send between two, and how much of data you will want to send, and which way of sending is most appropriate for your task. It may also depend on your shared library API: you probably don't want to spend much of CPU time to convert messages format (as you already have triple context switching with this driver architecture, which is not really nice for performance). So it's probably should be something packet-oriented, like Netlink 之间进行交互。

下次阅读有助于确定使用哪个 IPC: