如何更改/dev/rtc的链接目标?

如何更改/dev/rtc的链接目标?

在我的 Beaglebone Black I 上添加了 I2C 实时时钟不依赖 ntpd 来保持准确的计时。结果是.txt文件中有两个特殊的设备文件/dev。它们是/dev/rtc0和 ,/dev/rtc1但也有 ,/dev/rtc它是 的符号链接/dev/rtc0

在此输入图像描述

/dev/rtc0是板上ARM SOC内的实时时钟,/dev/rtc1是I2C设备。目前,我正在使用手动读取时间并将时间写入 I2C 时钟的脚本,但我更希望符号链接/dev/rtc指向/dev/rtc1.

因此问题是,如何才能做到这一点?我的 beaglebone black 上的 Linux 发行版是 Arch Linux,它使用 systemd 进行所有内务处理。

当我删除符号链接并创建一个新的符号链接时,毫不/dev/rtc1奇怪,它会在下次重新启动后重置,并且到目前为止我没有找到任何配置文件或系统单元。

非常感谢您的帮助。

答案1

udev 规则提示为我指明了正确的方向。快速回顾后编写 udev 规则我做了以下事情。

udevadm info -a -p /sys/class/rtc/rtc1

输出(缩短)揭示了一些定义 udev 规则的有用属性。

looking at device '/devices/platform/ocp/4802a000.i2c/i2c-1/1-0068/rtc/rtc1':
KERNEL=="rtc1"
SUBSYSTEM=="rtc"
DRIVER==""
ATTR{date}=="2015-12-04"
ATTR{hctosys}=="0"
ATTR{max_user_freq}=="64"
ATTR{name}=="ds1307"
ATTR{since_epoch}=="1449230817"
ATTR{time}=="12:06:57"
...

因此,规则文件需要采用/etc/udev/rules.d/类似于99-rtc1.rules.

文件内容是

KERNEL=="rtc1", SUBSYSTEM=="rtc", DRIVER=="", ATTR{name}=="ds1307", SYMLINK="rtc", MODE="0666"

要测试规则,您可以运行

udevadm test /sys/class/rtc/rtc1

输出中的重要行是

...
creating link '/dev/rtc' to '/dev/rtc1'
atomically replace '/dev/rtc'
...

结果/dev是所需的配置。

在此输入图像描述

答案2

在尝试了很多方法让我的 I2C RTC 在带有内置 RTC 的 Orange Pi PC 上工作后,我设法(一种令人讨厌的方式)让它工作。

  1. 找出内置rtc的路径:
#>find /sys | egrep 'rtc$'
/sys/bus/platform/drivers/sun6i-rtc/1f00000.rtc

您可能会得到很多行,只需关注那些带有“/sys/bus...”的行

  1. 创建一个udev来管理设备的创建和设备链接
#>nano /etc/udev/rules.d/99-rtc1.rules

粘贴此内容:

KERNEL=="rtc1", SUBSYSTEM=="rtc", DRIVER=="", ATTR{name}=="rtc-ds1307 0-0068", ATTR{hctosys}=="0", SYMLINK+="rtc", SYMLINK+="rtc0", MODE="0666"
  1. 现在,您必须创建一个 systemd 服务:
#>nano /etc/systemd/system/rtc.service

以下内容需根据您的内置 rtc0 和 rtc1 i2c 设备进行编辑ExecStart

[Unit]
Description=Initialize ds1307 RTC and sincronize system clock
DefaultDependencies=no
Requires=systemd-modules-load.service
After=systemd-modules-load.service
#Before=sysvinit.target
ConditionPathExists=/sys/class/i2c-adapter
#Conflicts=shutdown.target

[Service]
Type=oneshot
RemainAfterExit=yes
User=root
WorkingDirectory=/root
ExecStart=/bin/sh -c "echo -n "1f00000.rtc" > /sys/bus/platform/drivers/sun6i-rtc/unbind && echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device && hwclock --rtc /dev/rtc --hctosys --utc"

[Install]
WantedBy=multi-user.target
  1. 启用该服务: #>systemctl enable rtc.service
  2. 启动服务: #>systemctl start rtc.service
  3. 您可以使用以下内容检查/dev/rtc*设备是否已相应更改:ls -lah /dev/rtc*
lrwxrwxrwx 1 root root      4 Apr  3 18:19 /dev/rtc -> rtc1
lrwxrwxrwx 1 root root      4 Apr  3 18:19 /dev/rtc0 -> rtc1
crw-rw-rw- 1 root root 253, 1 Apr  3 18:19 /dev/rtc1

现在 rtc 和 rtc0 指向 rtc1!

  1. 检查 hwclock 是否正在使用hwclock --verbose
hwclock from util-linux 2.37.2
System Time: 1680548612.161304
Trying to open: /dev/rtc0
Using the rtc interface to the clock.
Last drift adjustment done at 1680540088 seconds after 1969
Last calibration done at 1680540088 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
ioctl(4, RTC_UIE_ON, 0): Invalid argument
Waiting in loop for time from /dev/rtc0 to change
...got clock tick
Time read from Hardware Clock: 2023/04/03 19:03:33
Hw clock time : 2023/04/03 19:03:33 = 1680548613 seconds since 1969
Time since last adjustment is 8525 seconds
Calculated Hardware Clock drift is 0.000000 seconds
2023-04-03 19:03:32.766066+00:00

要使用系统时间更新时钟,只需使用hwclock -w从 rtc 使用更新hwclock -s

您必须将模块添加到 /etc/modules echo "rtc-ds1307" >> /etc/modules

相关内容