Opened 16 years ago

Closed 15 years ago

#2266 closed task (fixed)

Set system time before bootscripts run

Reported by: DJ Lucas Owned by: bdubbs@…
Priority: normal Milestone: 6.5
Component: Book Version: SVN
Severity: normal Keywords:
Cc:

Description

x86_64 does not necessarily support /dev/rtc due to the new device options (though udev creates a symlink). It seems that util-linux-ng-2.14 does support a '--rtc=$device' option. This does give us the possibility of using a pre-created device node in /dev/ so that the clock is set very early for boot logging, but some text would have to be written about the options and a new DEVICE= line added to /etc/sysconfig/clock. See the previous discussion in #2189 for background info.

Change History (10)

in reply to:  description comment:1 by bryan@linuxfromscratch.org, 16 years ago

Couple of comments:

Replying to dj@linuxfromscratch.org:

x86_64 does not necessarily support /dev/rtc due to the new device options (though udev creates a symlink).

Not entirely true.

It's not that x86_64 kernels don't support /dev/rtc. They do, if your kernel was configured to match the device you're creating. The issue is that my particular kernel has CONFIG_RTC and CONFIG_GEN_RTC both disabled, since I turned on CONFIG_RTC_CLASS along with CONFIG_RTC_INTF_DEV ("/dev interface") and CONFIG_RTC_DRV_CMOS (rtc-cmos module). This is an option on 32-bit as well, along with lots of other non-x86 CPUs, although they would use something other than rtc-cmos for the driver (that's sort of the whole point of the RTC class).

(So it's not a 32-bit vs. 64-bit thing. It's a new option in the kernel that changes the way it works with RTCs.)

Under this setup, /dev/rtc does exist (as a symlink to rtc0, as you said), but the major and minor numbers are different. So a static node created for the old CONFIG_RTC setup won't work with a kernel that only has the new RTC class drivers, and a node created for the RTC class drivers won't work with a kernel that only has the old CONFIG_RTC code enabled.

It seems that util-linux-ng-2.14 does support a '--rtc=$device' option. This does give us the possibility of using a pre-created device node in /dev/ so that the clock is set very early for boot logging, but some text would have to be written about the options and a new DEVICE= line added to /etc/sysconfig/clock.

I'm not sure that helps, unless we create two devices and have the user choose between them. (Which means that any time the user recompiles their kernel, their choice may need to change.) And even two devices won't work if the RTC stuff is built as a module -- udev loads the module today. (At least for rtc-cmos it does, based on the PNP BIOS modalias.)

(Other details below.)

From your BTW question in #2189 -- no, this has nothing to do with HPETs. It's a different subsystem for real-time clock drivers, which was created to make adding new drivers easier (e.g. for embedded systems, which use all kinds of crazy real-time clock chips). It also supports multiple devices, and works on any CPU that will let the kernel talk to the RTC chip (not just x86_32 and x86_64).

Looks like it was added in 2.6.17, according to LWN. See also the original proposal, along with a change to make it support multiple devices. (Note that the udev rule there isn't great, but current versions of udev have rules that work.)

I'll try a newer util-linux and see if the --directisa option works, but if it does, relying on it will break Ken's PPC systems as well. ;-P

comment:2 by bryan@linuxfromscratch.org, 16 years ago

Confirmed -- current util-linux-ng (2.14.1) still does not work if /dev/rtc and /dev/rtc0 are both missing (it does fall back to rtc0 now).

Looking at the source, hwclock decides at compile time which clock methods are valid; it only enables direct ISA access for x86-32 (__i386__) and Alpha (__alpha__). It may be possible to add __x86_64__ to this list (but as above, that leaves PPC in the dark).

See the end of hwclock/cmos.c in util-linux-ng, function probe_for_cmos_clock. The "cmos clock" in that code is the --directisa method (see hwclock.c).

(And I suspect none of this is good for 6.4. But I think the solution to #2189 is fine for that.)

in reply to:  description comment:3 by alexander@…, 16 years ago

Replying to dj@linuxfromscratch.org:

This does give us the possibility of using a pre-created device node in /dev/

No, this doesn't. The major number for /dev/rtc0 is dynamic (i.e., depends on kernel configuration and can change after recompilation), so this device can be created properly only by udev.

comment:4 by DJ Lucas, 16 years ago

The original hwclock (from which the util-linux version was forked in 1999) does currently allow direct access for PPC, x86_64, and SPARC. There is a bug mentioned in the changelog about directisa being broken...basically if two processes access it at the same time, however, I don't know if this would cause an issue for our intended use. It seems to me, at least on Linux, nothing will access the system clock until the device node is available anyway. I have found no evidence for or against this issue in the util-linux version.

comment:5 by bdubbs@…, 16 years ago

I propose to solve this ticket in the way that ubuntu does:

  1. Remove the start function from the /etc/rc.d/init.d/setclock bootscript
  2. Add /etc/udev/rules.d/85-hwclock.rules:
# This file causes the hardware clock to be set when /dev/rtc 
# is available.
KERNEL=="rtc", ACTION=="add", RUN+="set_hwclock"
  1. Add set_hwclock. ubuntu has it in /lib/udev/, but perhaps we should put it in /sbin. udev has some code that allows running a program/script from /lib/udev/ without a path.

ubuntu's set_hwclock looks like:

#!/bin/sh
# udev helper for hwclock
#
# This is based on the hwclock.sh init script, 
# but somewhat simplified.

[ ! -x /sbin/hwclock ] && exit 0
. /etc/default/rcS

[ "$GMT" = "-u" ] && UTC="yes"
case "$UTC" in
    no|"")      GMT="--localtime"
                UTC=""
                ;;
    yes)        GMT="--utc"
                UTC="--utc"
                ;;
    *)          exit 1 ;;
esac

case "$BADYEAR" in
    no|"")      BADYEAR="" ;;
    yes)        BADYEAR="--badyear" ;;
    *)          exit 1 ;;
esac

# Copies Hardware Clock time to System Clock using the correct
# timezone for hardware clocks in local time, and sets kernel
# timezone. DO NOT REMOVE.
/sbin/hwclock --hctosys $GMT $HWCLOCKPARS $BADYEAR

We probably want to just ignore badyear (man hwclock) as we do now. I wouldn't think too many users have hw with a bios from 95 or 96.

Note: The hwclock.sh init script has:

# Set this to any options you might need to give to hwclock, 
# such as machine hardware clock type for Alphas.
HWCLOCKPARS=

in reply to:  5 ; comment:6 by Bryan Kadzban, 16 years ago

Replying to bdubbs@…:

I propose to solve this ticket in the way that ubuntu does:

Which would allow setting the time earlier, at least. Not quite before any of the bootscripts run, but maybe early enough.

(With initramfs, OTOH... ah, never mind. :-) )

KERNEL=="rtc", ACTION=="add", RUN+="set_hwclock"

Duplicate this for SUBSYSTEM=="rtc" (or just s/KERNEL/SUBSYSTEM/ and leave one rule -- I don't know if that will work with CONFIG_GEN_RTC), and this looks good.

  1. Add set_hwclock. ubuntu has it in /lib/udev/, but perhaps we should put it in /sbin.

I'd prefer /lib/udev, but only because I don't think anything else is going to call this...

ubuntu's set_hwclock looks like:

I'd prefer to keep this similar to our current setclock script: include /etc/sysconfig/clock (not rcS), use the UTC set there instead of this crazy GMT thing, use CLOCKPARAMS throughout, but probably get rid of the initscript-specific includes (/etc/sysconfig/rc and the variable containing the main bootscript functions file).

We probably want to just ignore badyear (man hwclock) as we do now. I wouldn't think too many users have hw with a bios from 95 or 96.

Agreed.

I assume the Ubuntu hwclock bootscript still allows setting the clock at shutdown?

Hmm -- would it be simpler to add RUN+="/etc/rc.d/init.d/setclock start" to the udev rule, and just kill the start symlinks? That way we only have one file to maintain...

in reply to:  6 ; comment:7 by bdubbs@…, 16 years ago

Replying to bryan@…:

Replying to bdubbs@…:

  1. Add set_hwclock. ubuntu has it in /lib/udev/, but perhaps we should put it in /sbin.

I'd prefer /lib/udev, but only because I don't think anything else is going to call this...

I was suggesting /sbin because I thought we were keeping /lib/udev for the distributed files only.

ubuntu's set_hwclock looks like:

I'd prefer to keep this similar to our current setclock script: include /etc/sysconfig/clock (not rcS), use the UTC set there instead of this crazy GMT thing, use CLOCKPARAMS throughout, but probably get rid of the initscript-specific includes (/etc/sysconfig/rc and the variable containing the main bootscript functions file).

Of course we would change it for LFS. I was just quoting the ubuntu file.

I assume the Ubuntu hwclock bootscript still allows setting the clock at shutdown?

Yes.

Hmm -- would it be simpler to add RUN+="/etc/rc.d/init.d/setclock start" to the udev rule, and just kill the start symlinks? That way we only have one file to maintain...

That's a good idea. We just need to kill the S links. We still need the K links.

in reply to:  7 comment:8 by Bryan Kadzban, 16 years ago

Replying to bdubbs@…:

Replying to bryan@…:

Replying to bdubbs@…:

  1. Add set_hwclock. ubuntu has it in /lib/udev/, but perhaps we should put it in /sbin.

I'd prefer /lib/udev, but only because I don't think anything else is going to call this...

I was suggesting /sbin because I thought we were keeping /lib/udev for the distributed files only.

Ah.

Either way would work for me, though I think of udev-specific scripts/binaries as being in /lib/udev just because that's the only place you can get to them without a path (AFAIK it doesn't honor $PATH). But this is mostly-irrelevant anyway; see below...

Of course we would change it for LFS. I was just quoting the ubuntu file.

Oh, I get it. OK.

Hmm -- would it be simpler to add RUN+="/etc/rc.d/init.d/setclock start" to the udev rule, and just kill the start symlinks? That way we only have one file to maintain...

That's a good idea. We just need to kill the S links. We still need the K links.

Right. It also neatly sidesteps everything above. :-)

comment:9 by bdubbs@…, 16 years ago

Milestone: 7.06.5
Owner: changed from lfs-book@… to bdubbs@…
Status: newassigned

comment:10 by bdubbs@…, 15 years ago

Resolution: fixed
Status: assignedclosed

Fixed in r8902.

Note: See TracTickets for help on using tickets.