Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I find which RTC module my kernel loads?

During compilation of my kernel using a configuration file obtained from Ubuntu OS 16.04, I noticed I am compiling a lot of RTC drivers, basically every possible driver:

... 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 ...
...

I was wondering if could get rid of those many drivers, so I started looking around for how to:

  1. looking in lsmod I see no RTC driver
  2. lshw isn't helpful either
  3. lspci -v also wasn't yielding much info.

Lower level inspection, shows a device exists:

$ ls -l /dev/rtc
lrwxrwxrwx 1 root root 4 Dec 18 09:54 /dev/rtc -> rtc0

The closest I got the get more info is in /sys/class/rtc/:

$ sudo cat /sys/class/rtc/rtc0/device/rtc/rtc0/name 
rtc_cmos

Doe that mean, that the only driver my kernel is using is rtc_cmos?

  • Does that mean I do not need all the other drivers?
  • Does that mean that my laptop uses a CMOS compatible hardware?
  • also, why does modinfo rtc_cmos return nothing?
like image 465
oz123 Avatar asked Oct 18 '25 19:10

oz123


2 Answers

I understand the OP got the correct answers to the narrow question, but I feel it more in SO spirit to generalize the answer, so I am posting it in hope that it would be helpful to answer the generalized question: How do I find what driver the /dev/xyz is using?.

Option 1: Poke the /sys filesystem

Provided you have sysfs mounted (normally at /sys; but I have yet to find out a distro that does not), why do not ask the kernel itself?

1. Find out the 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. Substitute the numbers into the /sys/dev path as below, (char is for char devices, block is, you guessed it, for block devices).

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

This is the name of the kernel module that is attached to the node. Works same regardelss of whether the module is linked into kernel, or loaded via modprobe. (And 00:00 is not the time in the RTC clock. Rather, IIRC, it's the device address or "function" on its parent driver or bus; but do not trust me on this, I remember that only vaguely).


Side note, feel free to explore this filesystem. It's readable by non-root (except for security-sensitive parts, most of which you can read as root), entirely safe to read, and you can find a lot of hardware and low-level software configuration info there. Unlike most of /proc, most of /sys is writable, and used by programs to change the running kernel and device parameters. For one, sysctl works entirely through it. But I digress.

Option 2: Have udevadm look under /sys for you

If you have udevadm available, ask it everything it knows about the device (the program accepts both /dev and /sys paths for the device):

$ 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==""

The info command instructs udevadm to give out everything it knows about the device, and the -a switch is to go up the chain of parent drivers/busses. Here you see that the parent device /devices/pnp0/00:00 has the driver rtc_cmos, and is discovered/activated on the bus created by another device, pnp0, which is the plug-and-play bus enumerator.

By the way, the names udevadm prints are also paths in the sysfs, i. e. you can see them in your normal file space by prefixing the sysfs mount point, /sys:

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

Both these command will produce identical output.

Once caveat is, unlike "normal" file systems, sysfs does hardlink directories, so do not try to do any recursive searches in it (like find . /sys or ls -R /sys) -- these programs will just crash after struggling with the infinite looping over the filesystem.

So what about the /sys/class/rtc/rtc0/device/rtc/rtc0?

As you noticed, there are multiple paths from the root of sysfs down to the device parameter node. Which one is the real McCoy?

  • Not every device has an interface via the /dev filesystem (or any other; there is nothing special about /dev -- it's just a tempfs; it's the file /dev/rtc0 which is special). These you won't find through the path /sys/dev/*.

  • Not every device is part of a subsystem, this is also optional. There are not discoverable through /sys/class*. So this is also a helpful, but optional link. Note that this node is different: it must expose subsystem-specific parameters. In our case, all RTC clocks expose a well-known set of settings common to the rtc sybsystem.

  • Now, /sys/devices/pnp0/00:00/rtc/rtc0 is the main, canonical path to the device sysfs node. It always corresponds to its topological location in the hierarchy of system busses and drivers: this is the instance rtc0 of the device rtc, which is addressed as 00:00 on the bus pnp0. It does not always correspond to its physical connection; in our case, pnp0 is a virtual bus which does not connect devices to physical busses and bridges, but only discovers and enumerates them. This is the canonical name for the device (sans the /sys prefix, of course--it's just a mount point) used by udev to uniquely identify it.

  • Finally, a kernel module does not have to expose anything in sysfs. Only the modules that must be discoverable from userspace need that, strictly. But if it does, the module decides what to expose, and it's parent and grandparents determine where in sysfs it will be under the devices root.

like image 101
kkm Avatar answered Oct 21 '25 09:10

kkm


Does that mean I do not need all the other drivers? Does that mean that my laptop uses a CMOS compatible hardware?

Exactly, if you only care about that RTC, then rtc_cmos is all you need. rtc-efi is probably a valid alternative if your PC is recent enough.

also, why does modinfo rtc_cmos return nothing?

Because the driver is probably compiled statically in the kernel instead of as a module. Check for CONFIG_RTC_DRV_CMOS=y in your configuration.

like image 28
Alexandre Belloni Avatar answered Oct 21 '25 09:10

Alexandre Belloni