我是初学者。我对与设备驱动程序相关的主要编号和次要编号有所了解。我还知道大多数可以插入 Linux 系统的设备都有一个主编号。并根据这个主设备号,加载相应的驱动程序。我有这个疑问,请告诉我内核在插入设备时如何从设备中读取主设备号?请解释从设备插件到驱动加载的步骤,尽可能简单。
提前致谢。
我是初学者。我对与设备驱动程序相关的主要编号和次要编号有所了解。我还知道大多数可以插入 Linux 系统的设备都有一个主编号。并根据这个主设备号,加载相应的驱动程序。我有这个疑问,请告诉我内核在插入设备时如何从设备中读取主设备号?请解释从设备插件到驱动加载的步骤,尽可能简单。
提前致谢。
主要/次要数字用于块和字符设备。
您没有从设备中检测到主要号码。也许您认为 USB 设备可以传达设备编号而 Linux 使用这些设备编号,但 USB 供应商/产品 ID 与主要编号无关。如果您将一个完全哑巴的串行设备插入串行端口会怎样?内核无法知道您插入/拔出某些东西。
因此,例如,如果您想要字符设备的主要号码,您可以使用
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
就像 NKamrath 说的那样,或者您使用绝对的。但是,请注意,许多是保留的。
据我所知,这是您要求的步骤:
register_chrdev_region
)一个主号码,如果它有一个保留(参见这个著名的保留列表);否则它会要求内核为其分配一个(例如alloc_chrdev_region
);驱动程序还将为此驱动程序保留一个次要区域。此时,您可以使用驱动程序的设备号与驱动程序进行通信,但是如何呢?还没有任何内容/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 Device Drivers 3rd Edition,即使您只阅读前 3 章(大约 100 页),它也会为您提供很好的驱动程序介绍你会很好地理解我认为你在问什么。此外,示例的所有源代码都是可用的,因此您可以破解他们的演示并更快地开始编写驱动程序!