主号码次号码和驾驶员加载

我是初学者。 我有一些关于设备驱动程序相关的主要号码和次要号码的想法。 另外我知道大多数可以插入Linux系统的设备都有一个主要的编号。 并根据这个主数字,加载相应的驱动程序。 我有这个疑问,请告诉我内核在插入时如何从设备读取主设备号? 请解释从设备插件到驱动程序加载的步骤,尽可能简单。

提前致谢。

主要/次要号码是字符设备。

您没有检测到设备的主要号码。 也许你认为USB设备可以传送设备号码,而Linux使用这些设备号码,但USB供应商/产品ID与主要号码无关。 如果你把一个完全愚蠢的串行设备插入串口呢? 内核没有办法知道你插入/拔出的东西。

所以,如果你想要一个主要的数字为你的字符设备,无论你使用

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name); 

像NKamrath说的,或者你使用绝对的。 但是,要小心, 许多是保留的 。

据我所知,这是你要求的步骤:

  1. 你插入一些块/字符设备到一些总线
  2. 根据总线(USB,PCI,PCI Express,SCSI,I²C等)的不同,总线(可能)会发送一个中断信号 ,这个中断信号有一天会到达CPU,从而到达Linux。
  3. 中断程序执行必要的工作,知道总线类型及其内部机制,为该设备加载相应的驱动程序 (如果存在,并且确实存在)并执行其初始化功能。
  4. 设备驱动程序的初始化函数(如register_chrdev_regionregister_chrdev_region一个主要的数字,如果它有一个保留的(见这个着名的保留列表 )。 否则它要求内核为它分配一个(例如alloc_chrdev_region ); 司机也将为这个司机保留一个小地区。
  5. 驱动程序设置了一些回调(打开/关闭/读/写),并要求内核将它们与设备号相关联。

此时,您可以使用其设备号与驱动程序通信,但是如何? 在/dev没有任何东西…一个办法是使用mknod当你知道你要与之通信的主要/次要对。 你会问:

 # mknod /dev/mydevice c 232 4 

…这是:请设备节点在/dev/mydevice链接到字符( c )设备与主要232和次要4.但你怎么知道这些数字呢? 他们可能是绝对的(保留列表),或者可能是驱动程序printk它,所以你可以手动。

但是这里有更好的东西。

仍然在设备驱动程序的初始化函数中:驱动程序将设备注册为Sysfs设备(请参阅device_create )。 这会将设备放入/sys树,其节点(一个目录)将有一个名为uevent的文件。 如果你cat它,它会输出类似的东西

 MAJOR=232 MINOR=4 DEVNAME=whatever 

尝试一下:

 $ cat /sys/class/tty/console/uevent 

它匹配吗?

 $ ls -l /dev/console 

现在, udev是负责管理/dev的用户空间程序。 总的来说,它只是扫描/sys树,以便自动填充/dev 。 你也可以看到所有的字符和块设备主要/次要像这样:

 $ ls /sys/dev/char $ ls /sys/dev/block 

就是这样。 如果你想更好地理解这一切,开发一个虚拟驱动程序,并尝试使它自动出现在/dev

如果您事先知道主要号码,您可以使用

 int register_chrdev_region(dev_t first, unsigned int count); 

允许内核动态分配主设备号

 int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name); 

阅读主要号码使用

 int MAJOR(dev_t dev); 

要插入设备或驱动程序,您必须使用insmod 。 然后内核尝试使用你给的数字,或者如果你使用了alloc函数,动态地给它分配一个空闲的主数字。 正确地解释内核和驱动程序设计的内部工作将需要大量的解释。 然而,有一个很好的免费书,这是一个简单的阅读(代码簿)称为Linux设备驱动程序第三版 ,这将给你一个很好的介绍驱动程序,即使你只看了前三章(大约100页)你会很好的理解我认为你在问什么。 此外,所有示例的源代码都可用,因此您可以破解他们的演示,并开始更快地编写驱动程序!