【问题标题】:How do the files in '/dev' match Linux's model of a device? [closed]'/dev' 中的文件如何匹配 Linux 的设备型号? [关闭]
【发布时间】:2019-08-18 12:38:05
【问题描述】:

这是我对打开文件进行读/写的理解。

在应用层,我可以调用fopen()函数。

fwrite() 函数将调用系统调用open()

操作系统收到open()调用后,会将命令传递给VFS(虚拟文件系统)。

VFS 查找文件名,包括所需的任何目录并进行必要的访问检查。

如果这是在 RAM 缓存中,则不需要磁盘访问。如果没有,VFS 会向可能是 EXT4 的特定文件系统发送读取请求。

然后 EXT4 文件系统驱动程序将确定该目录位于哪个磁盘块中。然后它将向磁盘设备驱动程序发送读取命令。


所以现在假设我想读取连接到板上的 i2c 设备 A。并且文件目录是/dev/i2c/A

  • 是否有适用于所有设备的主设备号?例如,Linux 操作系统将 180 设置为 USB 的主编号。那么在设备方​​面,每个 USB 设备中是否有一个主编号 180?

  • 如果第一个问题的答案是否定的,那么Linux操作系统如何判断设备A是哪一种类型,仅仅是根据文件目录吗?

  • 我认为第二个问题的答案可能是:在引导初始化阶段,某些代码已经使用 export() 之类的方法将该端口挂载到文件系统?所以事实上,在启动阶段之后,文件目录 /dev/i2c/A 就存在在那里,并且它与 i2c 设备的主设备号绑定。所以当我想打开 dev/i2c/A 时,操作系统会为我找到正确的 i2c 驱动程序,而不是 SPI 或 USB 驱动程序。我不确定这部分,我需要更多信息。

  • 当设备在启动阶段后立即挂载到文件系统时,会发生上述情况。那么如果我有一个 USB 会发生什么,这个 USB 插入后如何以正确的主编号 180 安装到文件系统?而且我猜在安装阶段开始之前插入usb时会有一个irq?

【问题讨论】:

标签: linux-kernel linux-device-driver embedded-linux


【解决方案1】:

请参阅:hotplug doc。如果您运行示例代码,您可以看到在从USB 添加/删除设备时发送了netlink 事件。这是driver model 的一部分。每个驱动程序都应附加到BUS;这可以是platformUSBI2CSPIPCI 等。同样,在sysfs 中,会有用于识别特定设备的条目。通常I2C 地址可用于识别特定的客户端/从属芯片。 驱动程序模型还有助于挂起、恢复、有序关闭等。

/dev/ 中的文件由udevmdevuser-space 程序创建。它们将名称与设备节点(主要、次要、字符/块)相关联。您可以使用sysfs 和/或您的udev 脚本根据netlink 信息创建您想要的设备名称;其中大部分可用于udev 脚本。

编辑:对于i2c,总线主控驱动程序通过运行probe注意1来发现设备的地址。设备与具有表的特定驱动程序相关联。例如,stargate machine file 具有imote2_i2c_board_info,它将i2c 地址与驱动程序相关联。 SPI 设备也有一个类似的表。 Platform注意 2 设备添加了platform_add_devices()USBPCI 设备由类似的BUS 特定设备ID 标识。通常一个机器文件(或最近的device tree)将两者关联起来。
另请参阅:Linux Journal - I2C Drivers pt1Linux Journal - I2C Drivers pt2

我认为混淆的根源在于所有驱动程序/设备都是您在/dev/ 目录中看到的那些。这不是真的。用户只能看到顶级驱动程序。 master 设备使用许多 Linux 驱动程序/设备。它们可以形成设备的层次结构。通常只有顶级设备会暴露给用户。有诸如spi_write()之类的功能,更高级别的驱动程序可以使用通过SPI进行通信,SPI设备不会暴露给user space。声音和媒体/电视采集卡经常使用SPI 设备,但用户永远不知道这个BUS 存在并且正在使用。通常,多个卡供应商会在下面使用相同的芯片组。无需为每张卡编写驱动程序,只需为卡编写一些胶水。然后将chip 驱动程序的通用集合与胶水 一起使用,在层次结构的顶部将它们捆绑在一起;这是暴露给user space 的顶级驱动程序。这也允许 smartTM 芯片供应商创建系统集成商可以使用的良好驱动程序。

注 1:i2c 探测是指 I2C 消息,它请求总线上的所有注册地址。我不确定 probe 是否是正确的 i2c 命名法。

注 2 Platform 设备是 SOC 设备。他们没有相关的 BUS,所以平台是一个包罗万象的东西。通常,platform 设备与 CPU 集成(SOC 代表片上系统)。

【讨论】:

  • 一个小问题,什么是平台设备? GPIO 需要驱动吗?
  • 平台设备为SOC 设备。他们没有关联的BUS,所以平台是这些的全部。通常,它们与 CPU 集成在一起(SOC 代表 片上系统)。您不需要gpio 驱动程序。有一个图书馆。您可以将GPIO 引脚传递给驱动程序(也许以太网驱动程序想要闪烁 LED)。在不同的板上,使用不同的GPIO 引脚,但以太网驱动程序不会关心哪个引脚,它只是使用一些传递给它的platform data。通常,只传递function pointers,最终将使用GPIO,因为这提供了更大的灵活性。
  • @henryyao,如果驱动程序在某处维护文件(设备节点、debugfs 中的文件或其他任何东西),它会在 struct file_operations 中指定回调,如 open() 等并注册创建文件时的结构。当应用程序打开文件、读取或写入文件、调用ioctl() 等时,将调用这些回调。一些驱动程序使用它来管理与用户空间的数据传输,调整参数等。
  • @Henryyao。某些驱动程序对user space 不公开。大多数人不想直接使用i2c。通常,顶级设备是带有open()read() 等的设备。例如,声卡将有一个SSI 接口、一个编解码器芯片,可能还有很多GPIO。编解码芯片可以使用SPII2C;这用于设置volumemixer等; user space 使用 ioctl() 执行此操作。实际的 PCM 音频数据经过SSI,从主 CPU 内存到编解码器。 CPU 端有SSI 驱动程序,这些驱动程序必须连接到编解码器;这些是通用的。
  • @Henryyao。最后,有一个顶级机器驱动程序将所有这些东西放在一起。 sound/soc 目录对此有共同的infra-structureuser space 可以通过这个 infra-structure 进行通信,但是顶级机器驱动程序将数据/请求路由到不同的总线等。请参阅:git.kernel.org/?p=linux/kernel/git/torvalds/… I2C/@987654395 的声音抽象@.
【解决方案2】:

每个设备都有一个主要和次要编号。你可以通过做看到它们 ls -n /dev 对于某些驱动程序,例如磁盘,主要数字是硬编码的。对于其他人来说,它是动态的。次要编号可以在运行时发现设备时动态分配,而不仅仅是在启动时。内核维护一个内部设备切换表,将开发号映射到正确的驱动程序。

【讨论】:

    猜你喜欢
    • 2015-10-14
    • 2016-09-18
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 2012-10-28
    • 1970-01-01
    相关资源
    最近更新 更多