我如何找到我的内核加载的 RTC 模块?
How do I find which RTC module my kernel loads?
在使用从 Ubuntu OS 16.04 获得的配置文件编译我的内核期间,我注意到我正在编译很多 RTC 驱动程序,基本上是所有可能的驱动程序:
... snip ...
CC [M] drivers/rtc/rtc-bq4802.o
CC [M] drivers/rtc/rtc-da9052.o
CC [M] drivers/rtc/rtc-da9055.o
... more of those ...
...
我想知道是否可以摆脱那么多驱动程序,所以我开始四处寻找如何:
- 查看
lsmod
我没有看到 RTC 驱动程序
lshw
也没有帮助
lspci -v
也没有提供太多信息。
下级检查,显示设备存在:
$ ls -l /dev/rtc
lrwxrwxrwx 1 root root 4 Dec 18 09:54 /dev/rtc -> rtc0
我得到的最接近的信息是在 /sys/class/rtc/
:
$ sudo cat /sys/class/rtc/rtc0/device/rtc/rtc0/name
rtc_cmos
这是否意味着我的内核使用的唯一驱动程序是 rtc_cmos
?
- 这是否意味着我不需要所有其他驱动程序?
- 这是否意味着我的笔记本电脑使用 CMOS 兼容硬件?
- 另外,为什么
modinfo rtc_cmos
return 什么都没有?
Does that mean I do not need all the other drivers?
Does that mean that my laptop uses a CMOS compatible hardware?
确实,如果您只关心那个 RTC,那么 rtc_cmos 就是您所需要的。
如果您的 PC 足够新,rtc-efi 可能是一个有效的替代方案。
also, why does modinfo rtc_cmos return nothing?
因为驱动程序可能是在内核中静态编译的,而不是作为模块。检查配置中的 CONFIG_RTC_DRV_CMOS=y。
我知道 OP 得到了狭义问题的正确答案,但我觉得概括答案更符合 SO 精神,所以我发布它是希望它能对回答概括性问题有所帮助:如何找到 /dev/xyz
使用的驱动程序?.
选项 1:戳 /sys 文件系统
如果你已经安装了 sysfs
(通常在 /sys
;但我还没有找到没有的发行版),为什么不问问内核本身呢?
1。找出 device type (char/block) and the node number:
$ ls -l /dev/rtc0
crw------- 1 root root 249, 0 2019-04-01 15:22:29 /dev/rtc0
^ ^ ^
+-> character device +---+-> Major and minor node numbers.
2。将数字替换到 /sys/dev 路径中,如下所示,(char
用于字符设备,block
是,您猜对了,用于块设备)。
$ cat /sys/dev/char/249:0/name
rtc_cmos 00:00
这是附加到节点的内核模块的名称。无论模块是 linked 到内核,还是通过 modprobe 加载,都可以正常工作。 (并且 00:00
不是 RTC 时钟中的时间。相反,IIRC,它是设备地址或 "function" 在其 parent 驱动程序或总线上;但不要相信我,我只是模糊地记得。
旁注,请随意探索这个文件系统。 non-root 可读(除了 security-sensitive 部分, 大部分 您可以以 root 身份阅读),完全可以安全阅读,并且您可以找到很多那里有硬件和 low-level 软件配置信息。与大多数 /proc
不同,大多数 /sys
是可写的,并被程序用来更改 运行 内核和设备参数。一方面,sysctl 完全通过它工作。但是我跑题了。
选项 2:让 udevadm
为您查看 /sys
如果你有可用的 udevadm,请询问它所知道的有关设备的所有信息(该程序接受设备的 /dev
和 /sys
路径):
$ udevadm info -a /dev/rtc0
[...snip intro text...]
looking at device '/devices/pnp0/00:00/rtc/rtc0':
KERNEL=="rtc0"
SUBSYSTEM=="rtc"
DRIVER==""
ATTR{date}=="2019-06-27"
ATTR{hctosys}=="1"
ATTR{max_user_freq}=="64"
ATTR{name}=="rtc_cmos 00:00"
ATTR{since_epoch}=="1561605536"
ATTR{time}=="03:18:56"
ATTR{wakealarm}==""
looking at parent device '/devices/pnp0/00:00':
KERNELS=="00:00"
SUBSYSTEMS=="pnp"
DRIVERS=="rtc_cmos" <== THIS
ATTRS{id}=="PNP0b00"
ATTRS{nvram}==""
ATTRS{options}==""
looking at parent device '/devices/pnp0':
KERNELS=="pnp0"
SUBSYSTEMS==""
DRIVERS==""
info
命令指示 udevadm 给出它所知道的关于设备的所有信息,-a
开关是在 parent drivers/busses 链上向上移动。在这里您看到 parent 设备 /devices/pnp0/00:00
具有驱动程序 rtc_cmos
,并且 discovered/activated 在由另一个设备 pnp0
创建的总线上,这是 plug-and-play总线枚举器。
顺便说一下,名称 udevadm 打印也是 sysfs 中的路径,i。 e.你可以在你的普通文件 space 中看到它们,方法是在 sysfs 挂载点前加上前缀,/sys
:
$ ls -l /sys/devices/pnp0/00:00/rtc/rtc0
$ ls -l /sys/dev/char/249:0/
这两个命令将产生相同的输出。
需要注意的是,与 "normal" 文件系统不同,sysfs 执行 硬 link 目录,因此不要尝试在其中进行任何递归搜索(像 find . /sys
或 ls -R /sys
) -- 这些程序在与文件系统的无限循环作斗争后只会崩溃。
那么 /sys/class/rtc/rtc0/device/rtc/rtc0
呢?
如您所见,从 sysfs 的根目录到设备参数节点有多个路径。 哪一个才是真正的麦考伊?
并非每个设备都有通过 /dev
文件系统(或任何其他文件系统;/dev
没有什么特别之处——它只是一个临时文件系统;它是 file /dev/rtc0
这是特殊的)。这些你不会通过路径 /sys/dev/*
.
找到
并非每个设备都是子系统的一部分,这也是可选的。通过 /sys/class*
无法发现。所以这也是一个有用但可选的link。请注意,此节点不同:它必须公开 subsystem-specific 参数。在我们的例子中,所有 RTC 时钟都公开了一个 well-known set of settings common to the rtc
sybsystem.
现在,/sys/devices/pnp0/00:00/rtc/rtc0
是设备sysfs节点的主要规范路径。它始终对应于其在系统总线和驱动程序层次结构中的拓扑位置:这是设备 rtc
的实例 rtc0
,在总线 pnp0
上的地址为 00:00
].它并不总是对应于它的物理连接;在我们的例子中,pnp0
是一个虚拟总线,它不将设备连接到物理总线和网桥,而只是发现和枚举它们。这是设备的规范名称(当然没有 /sys
前缀——它只是一个挂载点)被 udev 用来唯一地标识它。
最后,内核模块不必在 sysfs 中暴露任何东西。严格来说,只有必须可以从 userspace 发现的模块才需要它。但如果它这样做,模块决定 what 公开,它是 parent 和 grandparents 决定 where in sysfs 它将在 devices
根目录下。
在使用从 Ubuntu OS 16.04 获得的配置文件编译我的内核期间,我注意到我正在编译很多 RTC 驱动程序,基本上是所有可能的驱动程序:
... snip ...
CC [M] drivers/rtc/rtc-bq4802.o
CC [M] drivers/rtc/rtc-da9052.o
CC [M] drivers/rtc/rtc-da9055.o
... more of those ...
...
我想知道是否可以摆脱那么多驱动程序,所以我开始四处寻找如何:
- 查看
lsmod
我没有看到 RTC 驱动程序 lshw
也没有帮助lspci -v
也没有提供太多信息。
下级检查,显示设备存在:
$ ls -l /dev/rtc
lrwxrwxrwx 1 root root 4 Dec 18 09:54 /dev/rtc -> rtc0
我得到的最接近的信息是在 /sys/class/rtc/
:
$ sudo cat /sys/class/rtc/rtc0/device/rtc/rtc0/name
rtc_cmos
这是否意味着我的内核使用的唯一驱动程序是 rtc_cmos
?
- 这是否意味着我不需要所有其他驱动程序?
- 这是否意味着我的笔记本电脑使用 CMOS 兼容硬件?
- 另外,为什么
modinfo rtc_cmos
return 什么都没有?
Does that mean I do not need all the other drivers? Does that mean that my laptop uses a CMOS compatible hardware?
确实,如果您只关心那个 RTC,那么 rtc_cmos 就是您所需要的。 如果您的 PC 足够新,rtc-efi 可能是一个有效的替代方案。
also, why does modinfo rtc_cmos return nothing?
因为驱动程序可能是在内核中静态编译的,而不是作为模块。检查配置中的 CONFIG_RTC_DRV_CMOS=y。
我知道 OP 得到了狭义问题的正确答案,但我觉得概括答案更符合 SO 精神,所以我发布它是希望它能对回答概括性问题有所帮助:如何找到 /dev/xyz
使用的驱动程序?.
选项 1:戳 /sys 文件系统
如果你已经安装了 sysfs
(通常在 /sys
;但我还没有找到没有的发行版),为什么不问问内核本身呢?
1。找出 device type (char/block) and the node number:
$ ls -l /dev/rtc0
crw------- 1 root root 249, 0 2019-04-01 15:22:29 /dev/rtc0
^ ^ ^
+-> character device +---+-> Major and minor node numbers.
2。将数字替换到 /sys/dev 路径中,如下所示,(char
用于字符设备,block
是,您猜对了,用于块设备)。
$ cat /sys/dev/char/249:0/name
rtc_cmos 00:00
这是附加到节点的内核模块的名称。无论模块是 linked 到内核,还是通过 modprobe 加载,都可以正常工作。 (并且 00:00
不是 RTC 时钟中的时间。相反,IIRC,它是设备地址或 "function" 在其 parent 驱动程序或总线上;但不要相信我,我只是模糊地记得。
旁注,请随意探索这个文件系统。 non-root 可读(除了 security-sensitive 部分, 大部分 您可以以 root 身份阅读),完全可以安全阅读,并且您可以找到很多那里有硬件和 low-level 软件配置信息。与大多数 /proc
不同,大多数 /sys
是可写的,并被程序用来更改 运行 内核和设备参数。一方面,sysctl 完全通过它工作。但是我跑题了。
选项 2:让 udevadm
为您查看 /sys
如果你有可用的 udevadm,请询问它所知道的有关设备的所有信息(该程序接受设备的 /dev
和 /sys
路径):
$ udevadm info -a /dev/rtc0
[...snip intro text...]
looking at device '/devices/pnp0/00:00/rtc/rtc0':
KERNEL=="rtc0"
SUBSYSTEM=="rtc"
DRIVER==""
ATTR{date}=="2019-06-27"
ATTR{hctosys}=="1"
ATTR{max_user_freq}=="64"
ATTR{name}=="rtc_cmos 00:00"
ATTR{since_epoch}=="1561605536"
ATTR{time}=="03:18:56"
ATTR{wakealarm}==""
looking at parent device '/devices/pnp0/00:00':
KERNELS=="00:00"
SUBSYSTEMS=="pnp"
DRIVERS=="rtc_cmos" <== THIS
ATTRS{id}=="PNP0b00"
ATTRS{nvram}==""
ATTRS{options}==""
looking at parent device '/devices/pnp0':
KERNELS=="pnp0"
SUBSYSTEMS==""
DRIVERS==""
info
命令指示 udevadm 给出它所知道的关于设备的所有信息,-a
开关是在 parent drivers/busses 链上向上移动。在这里您看到 parent 设备 /devices/pnp0/00:00
具有驱动程序 rtc_cmos
,并且 discovered/activated 在由另一个设备 pnp0
创建的总线上,这是 plug-and-play总线枚举器。
顺便说一下,名称 udevadm 打印也是 sysfs 中的路径,i。 e.你可以在你的普通文件 space 中看到它们,方法是在 sysfs 挂载点前加上前缀,/sys
:
$ ls -l /sys/devices/pnp0/00:00/rtc/rtc0
$ ls -l /sys/dev/char/249:0/
这两个命令将产生相同的输出。
需要注意的是,与 "normal" 文件系统不同,sysfs 执行 硬 link 目录,因此不要尝试在其中进行任何递归搜索(像 find . /sys
或 ls -R /sys
) -- 这些程序在与文件系统的无限循环作斗争后只会崩溃。
那么 /sys/class/rtc/rtc0/device/rtc/rtc0
呢?
如您所见,从 sysfs 的根目录到设备参数节点有多个路径。 哪一个才是真正的麦考伊?
并非每个设备都有通过
/dev
文件系统(或任何其他文件系统;/dev
没有什么特别之处——它只是一个临时文件系统;它是 file/dev/rtc0
这是特殊的)。这些你不会通过路径/sys/dev/*
. 找到
并非每个设备都是子系统的一部分,这也是可选的。通过
/sys/class*
无法发现。所以这也是一个有用但可选的link。请注意,此节点不同:它必须公开 subsystem-specific 参数。在我们的例子中,所有 RTC 时钟都公开了一个 well-known set of settings common to thertc
sybsystem.现在,
/sys/devices/pnp0/00:00/rtc/rtc0
是设备sysfs节点的主要规范路径。它始终对应于其在系统总线和驱动程序层次结构中的拓扑位置:这是设备rtc
的实例rtc0
,在总线pnp0
上的地址为00:00
].它并不总是对应于它的物理连接;在我们的例子中,pnp0
是一个虚拟总线,它不将设备连接到物理总线和网桥,而只是发现和枚举它们。这是设备的规范名称(当然没有/sys
前缀——它只是一个挂载点)被 udev 用来唯一地标识它。最后,内核模块不必在 sysfs 中暴露任何东西。严格来说,只有必须可以从 userspace 发现的模块才需要它。但如果它这样做,模块决定 what 公开,它是 parent 和 grandparents 决定 where in sysfs 它将在
devices
根目录下。