这是我对开放阅读/写作文件的理解。
在应用程序层中,我可以调用fopen()
函数。
fwrite()
函数将调用系统调用open()
。
操作系统收到open()
调用后,会将命令传递给VFS(虚拟文件系统)。
VFS查找文件名,包括所需的任何目录,并进行必要的访问检查。
如果这是在RAM缓存中,则不需要磁盘访问。如果没有,VFS会向特定文件系统发送一个读取请求,该请求可能是EXT4。
然后EXT4文件系统驱动程序将确定该目录所在的磁盘块。然后它将向磁盘设备驱动程序发送读取命令。
现在让我们说我想读一个附在板上的 i2c设备A 。文件目录是 / dev / i2c / A
所有设备都有一个主要号码吗?例如,Linux OS将180设置为USB的主要编号。那么在设备方面,每个USB设备中是否有一个主要的数字180?
如果第一个问题的答案为否,那么Linux操作系统如何确定设备A 的类型,是否只是根据文件目录?
我认为第二个问题的答案可能是:在启动初始化阶段,有些代码已经使用export()这样的东西将该端口挂载到文件系统?事实上,在启动阶段之后,文件目录 / dev / i2c / A 就存在,并且它与i2c设备的主号绑定。因此,当我想打开dev / i2c / A时,操作系统会为我找到合适的i2c驱动程序,而不是SPI或USB驱动程序。我不确定这部分,我需要更多相关信息。
在启动阶段后立即将设备安装到文件系统时会发生上述情况。那么如果我有一个usb会发生什么,在插入后,如何将这个usb安装到具有正确的主号码180的文件系统?我想在安装阶段开始之前插入usb时有一个irq?
答案 0 :(得分:7)
请参阅:hotplug doc。如果您运行示例代码,则可以看到在netlink
添加/删除设备时发送USB
事件。这是driver model的一部分。每个驱动程序都应附加到BUS
;这可以是platform
,USB
,I2C
,SPI
,PCI
等。同样,在sysfs
中,还会有用于标识特定设备的条目。通常,I2C
地址可用于标识特定客户端/从属芯片。 驱动程序模型还有助于暂停,恢复,有序关闭等。
/dev/
中的文件由udev
或mdev
用户空间程序创建。它们将名称与设备节点(major,minor,char / block)相关联。您可以使用sysfs
和/或udev
脚本根据netlink
信息创建所需的设备名称;其中大多数可用于udev
脚本。
编辑:对于i2c
,总线主控驱动程序通过运行probe
注1 来发现设备的地址。设备与具有表的特定驱动器相关联。例如,stargate machine file有imote2_i2c_board_info
,它将i2c
地址与驱动程序相关联。 SPI
设备存在类似的表。 Platform
注意2 设备添加了platform_add_devices()
。 USB
和PCI
设备由设备的类似BUS
特定ID标识。通常,机器文件(或最近的device tree
)将两者联系起来。
另请参阅:Linux Journal - I2C Drivers pt1,Linux Journal - I2C Drivers pt2
我认为混淆的一个原因是所有驱动程序/设备都是您在/dev/
目录中看到的。这不是真的。用户只能看到顶级驱动程序。许多Linux驱动程序/设备由主设备使用。它们可以形成设备层次结构。通常只有顶级设备会向用户公开。有spi_write()
等功能,更高级别的驱动程序可以通过SPI
进行通话,SPI
设备不会向user space
公开。声音和媒体/电视捕获卡通常使用SPI
设备,但用户永远不会知道这个BUS
存在并且正在被使用。通常,多个卡供应商将在下面使用相同的芯片组。不是为每张卡写驱动程序,而是只写一些卡的粘合。然后将一个chip
驱动程序的通用集合与 glue 一起使用,将它们连接在层次结构的顶部;这是向user space
公开的顶级驱动程序。这也允许智能 TM 芯片供应商创建系统集成商可以使用的良好驱动程序。
注1:通过i2c
探测,我的意思是I2C
消息,请求总线上的所有已注册地址。我不确定探测是否是正确的i2c
命名法。
注意2 Platform
设备是SOC设备。他们没有相关的BUS,所以平台是一个全能的。通常,platform
设备与CPU集成(SOC代表片上系统)。
答案 1 :(得分:1)
每个设备都有一个主要和次要编号。你可以通过这样做看到它们
ls -n /dev
对于某些驱动程序,如磁盘,主要数字是硬编码的。对于其他人来说,这是动态在运行时发现设备时,可以动态分配次要编号,而不仅仅是在启动时。内核维护一个内部设备切换表,将dev编号映射到正确的驱动程序。