这个问题是这个答案的后续。总的来说,我的目标是了解我的系统(Debian/Raspberry Pi 5“书虫”)是否正在根据系统时间更新我的 RTC/硬件时钟。请注意,RPi 5(与其 Pi 祖先不同)确实有一个内置的RTC/硬件时钟。
以下是我目前能够确定的情况:
1. 我觉得我已经确定系统时钟正在从 hwclock 更新:
$ dmesg | grep "system clock"
[ 1.588793] rpi-rtc soc:rpi_rtc: setting system clock to 2025-02-18T04:59:13 UTC (1739854753)
然而,经过一番搜索dmesg
,我找不到任何迹象表明 hwclock 正在从系统时间更新。不过,我确实找到了对时钟的引用fake-hardware
(这似乎很奇怪)。:
[ 4.037230] systemd[1]: Starting fake-hwclock.service - Restore / save the current clock...
2. 内核显然配置为“双向”进行时钟更新:
$ cat /boot/config-$(uname -r) | grep -i HCTOSYS
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
$ cat /boot/config-$(uname -r) | grep -i SYSTOHC
CONFIG_RTC_SYSTOHC=y
CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
我突然想到内核可能仅在关机期间执行 SYSTOHC 同步,并且可能没有被捕获dmesg
...但这是一个 WAG。
有人能解释一下如何确认内核正在(或未)更新 hwclock/RTC 吗?
好吧,如果设置了该配置变量并且内核没有改变,那么就正如你所说的那样:RTC每 11 分钟从系统时钟更新一次(暂停和其他事件除外)。
当然,您可以不信任您的内核编译器,或者怀疑
ntp_synced()
上面链接的代码中的检查是否正确。sudo perf stat -e rtc:rtc_set_time
将计算内核的 RTC 时间设置函数被调用的所有次数。让它运行 > 11 分钟,然后ctrlc:如果计数 > 0,则您的 RTC 已设置。我从我回答的第一个链接中阅读了 Linux 源代码。在那里,尝试了两种方法来设置 RTC,一种是他们称之为“旧版”的东西,另一种是较新的东西。
我快速检查了一下,发现遗留的东西没有在 arm 上实现,所以你的内核使用的是较新的方式,
update_rtc
所以我阅读了该函数的源代码。它调用
rtc_set_time
,其中包含以下行这表明有一个跟踪点“
rtc_set_time
”。所以我去寻找一个:找到了!
安装adjtimex工具,运行
adjtimex -p
,并记下“状态”值。该工具比较旧,有点简陋,甚至无法将状态标志解码为文本,因此您必须使用计算器或 Python 或其他 REPL 来检查它是否包含值 64 (STA_UNSYNC)。如果标志不存在,则时钟保持同步;如果标志存在,则时钟不同步,并且 RTC 更新被禁用。(不幸的是,这不是“系统时钟同步:”项目报告的内容
timedatectl
,尽管我正要建议这一点。它故意忽略了 STA_UNSYNC 指示,只考虑了最大误差。)通常,STA_UNSYNC 是默认设置的,并且 RTC 不受内核的影响,除非您运行 NTP 守护程序(timesyncd、chrony、ntpd)来调整系统时钟并清除标志以启用 RTC 更新。
请注意,流行的chrony NTP 守护程序并不总是依赖内核来更新 RTC;它的默认配置曾经是 chrony 守护程序本身会进行 hwclock 调整,同时保持 STA_UNSYNC 设置(即禁用内核更新)。
替代实验方法:将
hwclock
RTC 设置为明显错误的时间,然后等待约 11 分钟(内核的通常更新间隔),然后再次读出 RTC 值。如果现在是正确的,那么肯定有东西更新了它。如果它只在关机时完成,那么它根本不是由内核完成的——这是发行版的启动/关机脚本的一部分。
正如您所指出的,早期版本的 Pi 没有真正的 RTC。但它们仍需要在某处存储粗略的系统时间,这样系统就不会每次都启动到 1970 年。因此,磁盘上的文件充当不滴答作响的 RTC。
(即使没有 fake-hwclock.service,Systemd 实际上也内置了此功能。)