Skip to content
LinuxDeep Dive Published Updated 6 min readViews unavailable

Linux RTC Class: Separate Hardware Clock, System Time, and Wake Alarms

Diagnose Linux RTC behavior by distinguishing /dev/rtcN devices, wall-clock time, UTC policy, ioctl alarms, and hardware wake capability.

Linux systems can have multiple real-time clocks (RTCs), each with different power domains, alarms, and bus connections. The RTC class provides a portable interface for hardware clocks, but it does not mean every device can wake the machine, track subsecond time, or act as the authoritative system clock. A date command reports the system’s wall clock; /dev/rtcN addresses a hardware RTC. Confusing them can produce wrong time after boot, timezone errors, or a system that never wakes for a scheduled alarm.

The diagnostic task is to identify the actual RTC device, determine how the kernel and userspace choose among multiple clocks, validate the hardware’s capabilities, and test alarm delivery through the entire suspend path.

RTC class and device identity

Portable RTC-class devices are exposed as /dev/rtc0, /dev/rtc1, and so on, with attributes under /sys/class/rtc/rtcN. The older /dev/rtc interface is associated with PC-compatible RTC functionality and is not portable to all architectures. A system can contain an integrated SoC clock plus one or more external I2C or SPI RTCs. Do not assume rtc0 is the board’s most accurate or battery-backed clock without checking the platform.

Inspect devices and driver identity:

ls -l /dev/rtc*
for d in /sys/class/rtc/rtc*; do
    test -d "$d" || continue
    printf '\n### %s\n' "$d"
    for key in name date time hctosys; do
        test -r "$d/$key" && printf '%s=' "$key" && cat "$d/$key"
    done
    readlink -f "$d/device/driver" 2>/dev/null
done
cat /proc/driver/rtc 2>/dev/null

Available attributes depend on the driver. The hctosys attribute, where present, helps identify whether that RTC was selected for hardware-clock-to-system-clock initialization. /proc/driver/rtc can expose details for the system clock RTC, but its availability and content vary. Device enumeration order alone is not a stable identity; match the driver, firmware node, bus address, and board design.

Hardware clock versus system clock

The RTC generally maintains time while the system is powered off or in a low-power state, while the kernel system clock runs during normal operation. At boot, platform policy and kernel configuration can copy time from an RTC into the system clock. Userspace services can later synchronize system time from NTP or another source and may update the RTC according to distribution policy.

RTC hardware normally stores UTC rather than local time. Local-time RTC policy exists for compatibility with systems that dual boot, but it introduces daylight-saving and timezone ambiguity. Keep the platform’s convention explicit. If the RTC contains local time while the kernel interprets it as UTC, the apparent offset can shift seasonally. Do not “fix” a timezone mismatch by manually setting the clock before checking /etc/adjtime, systemd-timesyncd or chrony configuration, and boot-time hctosys behavior.

The RTC may offer only whole-second resolution, while the system clock can use a higher-resolution clocksource. A few seconds of difference between RTC and system time after network synchronization is not automatically a hardware failure. Record the clocks, timezone policy, time-sync state, and suspend duration when investigating drift.

Read and validate RTC time safely

Use read-only tools first. hwclock --show can query a hardware clock through the userspace interface, but behavior depends on the implementation and selected RTC. Compare it with date -u, not only local time, and note whether network time synchronization is active. Never set an RTC merely to make one command’s output match another before determining which clock is authoritative.

The kernel RTC ioctl interface supports reading time, setting time, alarms, and interrupt features according to device capabilities. Not every RTC implements every ioctl, and drivers can report unsupported operations. Consult the current kernel documentation and the specific chip datasheet. If you need to test a write or alarm, use a development board and record the previous state first.

For timekeeping accuracy, take repeated samples over a known interval and compare against a trusted external reference. Temperature, crystal tolerance, board loading, and oscillator configuration affect drift. A one-time discrepancy may be a timezone or synchronization issue; a consistent rate error suggests oscillator or calibration behavior. Do not claim a specific parts-per-million accuracy without manufacturer specifications and measurement evidence.

Alarm and wakeup behavior

RTC alarm capability and system wake capability are separate. A chip can schedule an alarm while the system is running but lack a routed wake signal or platform firmware configuration to wake the processor from suspend. Conversely, a platform may route an RTC interrupt to a wake controller only in certain suspend states.

Some RTC class devices expose wake-alarm sysfs attributes, and tools such as rtcwake can set an alarm and request a suspend mode. Availability and semantics are platform-dependent. Start with the device’s wakealarm support and /sys/class/rtc/rtcN/device/power/wakeup state where present, then inspect platform wake routing. Do not assume an alarm on rtc0 can wake the system if another RTC drives the wake pin.

Test alarms in a controlled environment. Confirm the alarm is armed, suspend into the exact target state, measure the wake time, and inspect kernel logs afterward. Test each relevant RTC separately if the platform has multiple clocks. An alarm that fires in the running system may not wake from deep suspend because the power domain or interrupt route was disabled.

Do not perform repeated wake cycles on a production device without considering battery and service impact. A wake alarm can increase power use, and an incorrect periodic alarm can prevent a device from remaining suspended. Clear or disarm alarms after tests and verify the RTC reports no stale pending alarm.

Common failure patterns

Time is offset by a whole timezone. Check UTC versus local-time policy and userspace time synchronization before changing the hardware clock.

Clock is correct after network start but wrong at early boot. Inspect which RTC the kernel reads for hctosys, whether the provider probed in time, and whether initramfs or userspace later corrected it.

RTC time resets after power removal. Check battery voltage, battery contact, chip backup supply, and board design. Software cannot preserve time if the backup domain loses power.

Alarm is accepted but suspend does not wake. Verify wakeup capability, interrupt routing, device wake policy, and the exact suspend state. An ioctl success alone is not end-to-end wake proof.

/dev/rtc is missing while /dev/rtc0 exists. The legacy PC-compatible interface may not be provided. Use the portable RTC-class node or the supported userspace tool.

Two RTCs disagree. Identify each device and its role. One may be battery-backed, another may be the system-time source, and another may provide an alarm. Do not synchronize one from the other until policy is clear.

Validation workflow

  1. Inventory RTC class devices, bus addresses, drivers, and available sysfs/ioctl features.
  2. Determine which RTC initializes system time and whether the configured convention is UTC.
  3. Record hardware RTC, system UTC, local time, and network synchronization status.
  4. Validate drift across a measured interval against an external reference.
  5. Test alarm programming and wake from each required suspend state on a non-production system.
  6. Verify alarm cleanup, subsequent timekeeping, and battery-backup behavior.

For production acceptance, retain board revision, RTC part number, kernel/driver, timezone convention, hctosys choice, alarm support, suspend state, and drift measurement. Keep both a software recovery path and a hardware replacement plan where RTC battery loss is possible.

The RTC class standardizes access but cannot collapse multiple hardware clocks into one policy. Identify which clock stores time, which one initializes the kernel, which supports alarms, and which interrupt reaches the wake controller. That distinction turns vague “Linux time is wrong” reports into testable device and configuration questions.

Related:

Sources:

Comments