主次号是否唯一

Dee*_*ole 15 hardware numbering

major, minor唯一的编号?

我们有任何引用和参考吗?

NAME   MAJ:MIN RM   SIZE RO MOUNTPOINT
sda      8:0    0 465.8G  0 
??sda1   8:1    0 298.2M  0 
??sda2   8:2    0     3G  0 
??sda3   8:3    0 458.7G  0 /
??sda4   8:4    0     1K  0 
??sda5   8:5    0   3.8G  0 
sr0     11:0    1  1024M  0 
Run Code Online (Sandbox Code Playgroud)

mr.*_*tic 29

来自Linux 编程接口,第 14.1 节

每个设备文件都有一个主 ID 号和一个次要 ID 号。主 ID 标识设备的一般类别,内核使用它来查找此类设备的适当驱动程序。次要 ID 唯一标识通用类中的特定设备。ls -l 命令显示设备文件的主要和次要 ID。

[...]

每个设备驱动程序将其与特定主要设备 ID 的关联注册,该关联提供设备专用文件和设备之间的连接。当内核查找设备驱动程序时,设备文件的名称无关紧要。

另请参阅旧的 (2001) Linux Device Drivers (2e) 章节

即目的是为每种类型的设备提供一个从主要:次要到设备:实例的唯一映射。严格来说,你可以有两个不同的设备具有相同的主要:次要,只要一个是字符,一个是块:

# ls -l /dev/ram1 /dev/mem
crw-r----- 1 root kmem 1, 1 Jan  1  1970 /dev/mem
brw-rw---- 1 root disk 1, 1 Jan  1  1970 /dev/ram1
Run Code Online (Sandbox Code Playgroud)

在 Linux 上,在一个系统上的任何时间点,每种设备的主要:次要编号都是唯一的。然而,这些数字可能会随着时间的推移而改变,并且在不同的 Linux 系统(即使是相同的发行版、内核和硬件)上也不必相同。请注意,字符设备和块设备具有不同的编号空间,例如,块主设备 1 分配给 RAM 磁盘,字符主设备 1 分配给一组内核设备,包括空和零。

从历史上看,设备专业(大部分)是通过注册表静态分配(也仍然存在,尽管未维护,在内核源代码中Documentation/devices.txt)。现在很多设备都是动态分配的,这是由udev管理的,映射可以在/proc/devices. 固定设备仍然存在incude/uapi/linux/major.h(最近从 中移出include/major.h

现在,尽管主要:次要组合唯一标识特定设备实例,但没有什么可以阻止您创建引用同一设备的多个设备节点(文件)。它们甚至不必在其中创建/dev(但它们必须在支持创建设备节点的文件系统上,并且不使用nodev选项挂载)。

一个常见的用途是在 chroot 中创建重复的零、空和随机设备:

# find /dev /var/chroot -regextype posix-extended -regex ".*/(zero|null|random)" -type c | 
xargs ls -l
crwxrwxrwx 1 root root 1, 3 2012-11-21 03:22 /dev/null
crw-rw-r-- 1 root root 1, 8 2012-05-07 10:35 /dev/random
crw-rw-rw- 1 root root 1, 5 2012-11-21 03:22 /dev/zero
crwxrwxrwx 1 root root 1, 3 2012-11-21 03:22 /var/chroot/sendmail/dev/null
crw-rw-r-- 1 root root 1, 8 2012-05-07 10:35 /var/chroot/sendmail/dev/random
crw-rw-rw- 1 root root 1, 5 2012-11-21 03:22 /var/chroot/sendmail/dev/zero
Run Code Online (Sandbox Code Playgroud)

名称只是别名,内核并不关心大多数名称或位置,它关心主编号以便它可以选择正确的驱动程序,而驱动程序(通常)关心次要编号以便它可以选择正确的实例。

大多数名称只是约定(尽管有些是由 POSIX 定义的)。另请注意,一台设备可能会注册多个主号码,请在sd中检查驱动程序/proc/devices;驱动模块名( .ko) 不必与设备名相同,也不必与中的设备节点相同/dev,一个驱动模块可以管理多个逻辑/物理设备或设备名。


回顾一下:您可能有两个或多个设备节点(在/dev/或其他地方)具有相同的主次:次要编号,但如果它们是相同的类型,则它们指的是相同的设备。您可以拥有一个可以处理多个主要实例的驱动程序,但在内核和驱动程序中,对于每种类型(字符或块),主要:次要编号用于指代特定设备(主要)和特定实例(次要)设备。

您不能有两个具有相同类型和主要:次要的设备节点,并期望它们访问两个不同的逻辑或物理设备。当访问设备时,内核根据类型和主编号(而不是基于设备节点名称)选择一个驱动程序,并且按照约定,次编号确定性地选择特定实例或子功能。


更新 一些有趣的历史和一些 *BSD 观点可以在 Poul-Henning Kamp 的 2002 BSDCon演讲中找到:https : //www.usenix.org/legacy/events/bsdcon/full_papers/kamp/kamp_html/

如果您将时间回溯到 1978 年(由阿尔卡特朗讯提供,贝尔系统技术杂志1978 年 7 月至 8 月),“ Unix 时间共享系统”清楚地说明了这一点 (p1937):

设备的特征在于主设备号、次设备号和类(块或字符)。对于每个类,都有一个进入设备驱动程序的入口点数组。主设备号用于在调用特定设备驱动程序的代码时对数组进行索引。次设备号作为参数传递给设备驱动程序。次要号码除了驱动程序赋予它的意义外没有其他意义。通常,驱动程序使用次要编号访问几个相同的物理设备之一。