【问题标题】:How to access the node created in user space from kernel?如何从内核访问在用户空间创建的节点?
【发布时间】:2016-08-02 14:03:27
【问题描述】:

我正在做一个练习,我想从内核访问声卡的节点/dev/snd/controlC0,以使用 tinymix 实用程序从内核空间而不是用户空间设置 tinymix 控件。现在从 tinymix 实用程序的流程中,我发现它在开始执行时会从用户空间调用 mixer_open() 函数,该函数在内部调用内核的 snd_ctl_open() 函数。现在我必须做同样的事情从内核我的模块需要调用相同的函数。我面临的问题是函数snd_ctl_open() 有参数struct inode *inode, struct file *file。那么如何获取我的模块中节点的inode信息呢?

文件mixer.c 位于Android AOSP 代码external/tinyalsa/mixer.csnd_ctl_open() 位于 Linux 内核中的 sound/core/control.c

我在构建内核 API filp_open() 中找到了一个,它可以完成上述任务,但它只能在文件系统挂载后使用。我想在文件系统挂载之前打开一个节点。

简而言之,我的目标是了解如何在文件系统挂载之前从内核访问或打开设备节点。

【问题讨论】:

  • 这个接口不打算从内核空间使用。为什么您认为需要将 tinymix 移至内核?
  • 感谢您的回复,我的目标是通过内核在 Pandaboard 上启用音频。现在要启用音频,我需要设置一些混音器设置以启用来自模块的声音路径。现在要设置混音器设置,我需要从内核访问设备节点 /dev/snd/controlC0。还有一件事是我不想从内核中使用 tinymix 本身,我只想复制 tinymix 在我的模块中执行的任务。
  • 为什么不能在机器驱动中这样做?
  • 我对机器驱动程序(它的 sdp4430.c)知之甚少,但如果你能解释一下我该如何实现这一点,那就太好了。还有一件事是我必须在不更改现有内核代码的情况下完成这项任务。我只需要在我的模块中进行所有更改。
  • 如果你不想改变内核,你必须使用tinymix。你所说的一切都不是不使用它的理由。

标签: linux drivers alsa


【解决方案1】:

感谢斯科特的回复。

我能够访问设备节点/dev/controlC0 以及能够从内核模块设置混音器控制设置。我遵循了以下方法。

  1. sound/core/sound.c 中定义了一个全局结构“static struct snd_minor *snd_minors[SNDRV_OS_MINORS]”。此结构包含有关所有声音设备的次要数量的信息。
  2. 我找到了一种从设备次要编号中查找设备节点和文件指针结构的方法。所以我所做的是我从我的驱动程序中调用一个函数find_control_device(),它依次迭代所有设备并检查SNDRV_DEVICE_TYPE_CONTROL(声音控制设备)设备类型。函数find_control_device()返回控制设备的次设备号。
  3. 我能够从设备次要设备中获取设备节点和文件结构信息。
  4. 获得上述信息后,我会调用snd_ctl_open(),它将为操作打开一个设备节点。
  5. 当用户空间应用程序使用 IOCTL 与内核空间交互时。要设置混音器设置 tinymix 调用snd_ctl_ioctl() 函数。所以我做了一个包装函数,它会在内部调用snd_ctl_ioctl() 并设置混音器控制值。

我已经在驱动程序的module_init 函数部分完成了上述所有步骤。因此,一旦驱动程序在内核树中注册,就会根据要求设置所需的 tinymix 控件。

我已经从 AOSP 代码树中引用了 tinymix.c 的代码来操纵 IOCTL 的参数。

谢谢,

赫曼特

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-17
    • 2018-06-30
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    相关资源
    最近更新 更多