这个视频显示了创建新字符设备的 Raspberry Pi Linux 内核模块示例。它使用内核 API register_chdev
。在视频的评论中(我无法生成指向它的直接链接),关于 的返回值register_chdev
,作者指出:
如果返回值不等于0,则设备号已被使用。返回值的高12位是主设备号,低20位是次设备号。
我猜想“设备号已在使用中”他的意思是“在内核模块中任意选择的非零主设备号已在使用中”。
尽管有几个网页处理这个问题(官方的, 然后这个和这个),我没有找到任何有关返回值内部细分的信息。
如果我选择(使用我的内核模块)创建一个主设备号已在使用的设备,则内核永远不会接受它并拒绝注册该设备。当我选择的主设备号与块设备的主设备号相同时,以及当我选择的主设备号与字符设备的主设备号相同时,都会发生这种情况。register_chdev
始终返回负值。相反,在后一种情况下,我期待一个正的非零返回值,其中高 12 位代表主设备号,低 20 位代表次设备号(可能大于 0:如果主设备号是已经使用,也许系统已经至少有一个与之相关的设备,次设备号为0)。
YouTube 评论中所说的属实吗?我在哪里可以找到有关它的一些文档?
我正在运行 Raspbian 10,uname -a
显示:
Linux raspberrypi 5.10.63-v7+ #1459 SMP Wed Oct 6 16:41:10 BST 2021 armv7l GNU/Linux
答案1
register_chrdev
本身没有记录在内核中,但是它的定义很短:
static inline int register_chrdev(unsigned int major, const char *name,
const struct file_operations *fops)
{
return __register_chrdev(major, 0, 256, name, fops);
}
这基本上意味着它调用__register_chrdev
注册一个具有完整范围的次要(从 0 开始的 256 个次要)的主要,并返回该函数的结果。后者被记录为
如果
major
== 0 该函数将动态分配专业并返回其编号。如果
major
> 0 此函数将尝试保留具有给定主编号的设备,并在成功时返回零。失败时返回 -ve errno。
没有规定以编码或其他方式返回未成年人。这些功能的目的是在任何情况下注册一个专业,可能还有一部分未成年人;没有一个未成年人。
这编码open
当设备驱动程序处理调用时,或者需要确定给定设备对应的次要设备(如果它处理多个主要设备,则可能是主要设备)的任何其他时间,就会发挥作用。驱动程序被赋予要求处理的索引节点;对于设备节点,包括设备编号,对主要和次要进行编码。这MAJOR
和MINOR
宏,或者从 inode 开始,imajor
和iminor
函数,应该用来提取值。
一些字符设备在上述主要注册机制之上提供多路复用;看一个杂项驱动程序如何控制所有这些不同的硬件?举个例子。