主要号码次要号码和驱动程序加载

Aji*_*red 5 linux driver device linux-kernel

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

提前致谢.

eep*_*epp 16

主要/次要编号用于字符设备.

您没有从设备中检测到主号码.也许您认为USB设备可以通信设备号而Linux使用这些设备号,但USB供应商/产品ID与主要数字无关.如果将完全愚蠢的串行设备插入串口怎么办?内核无法知道你插入/拔出了什么东西.

因此,如果你想要一个主要设备的主号码,你可以使用

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
Run Code Online (Sandbox Code Playgroud)

像NKamrath说,或者你使用绝对的.但要注意,许多都是保留的.

据我所知,以下是您要求的步骤:

  1. 你将一些块/字符设备插入某个总线.
  2. 根据总线(USB,PCI,PCI Express,SCSI,I²C等),总线(可能)发送一个中断信号,该信号将在一天或一天​​内到达CPU,从而到达Linux.
  3. 中断例程在知道总线类型及其内部机制的情况下完成必要的工作,为该器件加载适当的驱动程序(如果它存在,并且确实存在)并执行其初始化函数.
  4. 如果设备驱动程序的初始化函数register_chrdev_region有一个保留(请参阅此着名的保留列表),则它会注册(例如)一个主要编号.否则它要求内核为它分配一个(例如alloc_chrdev_region); 司机还会为这名司机预留一个次要区域.
  5. 驱动程序设置一些回调(打开/关闭/读/写)并要求内核将它们与设备号相关联.

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

# mknod /dev/mydevice c 232 4
Run Code Online (Sandbox Code Playgroud)

...这是:请创建一个设备节点,/dev/mydevice该节点链接到c具有主要232和次要4的character()设备.但是,您如何知道这些数字呢?它们可能是绝对的(保留列表)或驱动程序printk,因此您可以手动执行.

但这里有更好的东西.

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

MAJOR=232
MINOR=4
DEVNAME=whatever
Run Code Online (Sandbox Code Playgroud)

试试吧:

$ cat /sys/class/tty/console/uevent
Run Code Online (Sandbox Code Playgroud)

它匹配吗

$ ls -l /dev/console
Run Code Online (Sandbox Code Playgroud)

现在,udev是负责管理的用户空间程序/dev.总的来说,它只是扫描/sys树以便/dev自动填充.您可能还会看到所有主要/次要的字符和块设备,如下所示:

$ ls /sys/dev/char
$ ls /sys/dev/block
Run Code Online (Sandbox Code Playgroud)

就是这样.如果你想更好地理解这一切,请开发一个虚拟驱动程序,并尝试将其自动显示/dev.

  • 非常整齐地回答! (2认同)

小智 3

如果您事先知道主设备号,则可以使用

int register_chrdev_region(dev_t first, unsigned int count);
Run Code Online (Sandbox Code Playgroud)

要允许内核动态分配设备主设备号,请使用

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, 
                    char *name);
Run Code Online (Sandbox Code Playgroud)

要读取主编号,请使用

int MAJOR(dev_t dev);
Run Code Online (Sandbox Code Playgroud)

要插入设备或驱动程序,您必须使用该insmod命令。然后,内核尝试使用您给它的编号,或者如果您使用了 alloc 函数,则动态地为其分配一个空闲的主编号。正确解释内核和驱动程序设计的内部工作原理需要大量解释。然而,有一本很棒的免费书籍,它很容易阅读(对于代码书而言),名为Linux Device Drivers 3rd Edition,即使您只阅读了前 3 章(大约 100 页),它也会为您提供有关驱动程序的非常好的介绍。你会对我认为你要问的问题有一个很好的理解。此外,示例的所有源代码都可用,因此您可以破解他们的演示并开始更快地编写驱动程序!