繁体   English   中英

我如何找到内核加载哪个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 ...
...

我想知道是否可以摆脱这么多司机,所以我开始四处寻找如何:

  1. lsmod寻找,我看不到RTC驱动程序
  2. lshw也无济于事
  3. 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不返回任何内容?

这是否意味着我不需要所有其他驱动程序? 这是否意味着我的笔记本电脑使用CMOS兼容硬件?

的确,如果您只关心该RTC,则只需要rtc_cmos。 如果您的PC足够新,则rtc-efi可能是有效的选择。

另外,为什么modinfo rtc_cmos不返回任何内容?

因为驱动程序可能是在内核中静态编译的,而不是作为模块编译的。 在您的配置中检查CONFIG_RTC_DRV_CMOS = y。

我了解OP对狭窄问题的正确答案,但是我觉得将答案归纳起来更符合SO精神,因此我将其发布,希望对回答以下普遍问题有所帮助: 我如何找到哪个驱动程序/dev/xyz正在使用?

选项1:戳/ sys文件系统

假设您已安装sysfs (通常位于/sys ;但我尚未找到没有发行版的发行版),为什么不询问内核本身?

1.找出设备类型(字符/块)和节点号

$ 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是char设备, block是块设备,您猜对了)。

$ cat /sys/dev/char/249:0/name
rtc_cmos 00:00

这是附加到节点的内核模块的名称。 无论模块是链接到内核还是通过modprobe加载,其工作方式都是相同的。 (而且00:00并不是RTC时钟中的时间。IIRC是它的父驱动程序或总线上的设备地址或“功能”;但是对此我并不信任,我只是模糊地记得)。


旁注,请随时浏览此文件系统。 非root用户可以读取它(安全敏感部分除外,您可以以root用户的身份读取其中的大部分内容),并且完全可以安全读取,并且可以在其中找到很多硬件和低级软件配置信息。 与大多数/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开关用于上级父驱动程序/总线。 在这里,您看到父设备/devices/pnp0/00:00具有驱动程序rtc_cmos ,并且在另一个设备pnp0创建的总线上被发现/激活,该设备是即插即用总线枚举器。

顺便说一句,udevadm打印名称也是sysfs中的路径,即,您可以在普通文件空间中通过在sysfs挂载点/sys前面加上前缀来看到它们:

$ ls -l /sys/devices/pnp0/00:00/rtc/rtc0
$ ls -l /sys/dev/char/249:0/

这两个命令将产生相同的输出。

需要注意的是,与“普通”文件系统不同,sysfs 会进行硬链接目录,因此请勿尝试在其中进行任何递归搜索(例如find。/ find . /sysls -R /sys )-这些程序在与文件系统的无限循环。

那么/sys/class/rtc/rtc0/device/rtc/rtc0呢?

如您所注意到的,从sysfs的根目录到设备参数节点之间有多个路径。 真正的麦考伊是哪一个?

  • 并不是每一个设备具有通过一个接口/dev文件系统(或任何其他,没有什么特别之处/dev -它只是一个tempfs,它是该文件 /dev/rtc0这是特殊的)。 这些您不会通过/sys/dev/*路径找到。

  • 并非每个设备都是子系统的一部分,这也是可选的。 无法通过/sys/class*发现。 因此,这也是一个有用但可选的链接。 请注意,此节点是不同的:它必须公开子系统特定的参数。 在我们的案例中,所有RTC时钟都公开了rtc sybsystem的组众所周知的设置

  • 现在, /sys/devices/pnp0/00:00/rtc/rtc0 设备sysfs节点的主要规范路径。 它始终对应于其在系统总线和驱动程序层次结构中的拓扑位置:这是设备rtc的实例rtc0 ,在总线pnp0上的地址为00:00 它并不总是与其物理连接相对应。 在我们的例子中, pnp0是虚拟总线,它不将设备连接到物理总线和网桥,而只是发现并枚举它们。 这是udev用来唯一标识它的设备的规范名称(当然,没有/sys前缀-它只是一个安装点)。

  • 最后,内核模块不必在sysfs中公开任何内容 严格来说,只有必须在用户空间中可发现的模块才需要。 但如果这样做,该模块决定揭露什么 ,以及它的父和祖父母确定在sysfs 那里将是下devices根目录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM