On Thu, 2003-05-15 at 19:13, Tim Weippert wrote: > HI there, > > i have both Debian (SID) and Mac OS X on a Powerbook G4. I have read > that Mac OS X use UTC to save/set the hardware clock. > > I thought i have to say my Debian installation, that the clock will be > set to GMT and then calc the right time depend on the timezone, but it > is strange, the time isn't correct, it's about 20 hours in the future. > > I can't figure out what i have to do to have the right time wihtin Mac > OS X and Debian (CEST Timezone Europe/Berlin)?
What happens is a bit "weird". For historical reasons, MacOS stores an offset to GMT (timezone) in the nvram. MacOS used to store the current timezone there, and used to store the RTC as local time. MacOS X does not use this offset (nor, I think, recent versions of MacOS 9). _However_, for compatibility, what MacOS X do is, on boot, to add that offset to the time read from the RTC, and when writing back to the RTC, to substract it. So the time in the RTC isn't really "local time", it's just relative to whatever offset is stored in the nvram, which can be quite junk in fact. On the other hand, the Linux kernel will apply that offset when reading from the RTC initially at boot. BUT, it will not apply it to whatever is done via /dev/rtc and thus will not apply it when reading/writing to nvram. So the offset isn't "transparent" unlike what MacOS X does. I originally wrote it like OS X does (and before OS X was around) but got so badly flamed about it that I reverted to the current mecanism, and I fell that changing it now would piss off more people. The solution to really have an UTC RTC is to write a 0 in that offset field in nvram. I don't think OS X will ever change it back to anything else (though I suspect MacOS 9 will, so be careful). I started writing a tool to write that, but I never finished it. Enclosed is what I have to read the MachineLocation structure from nvram, feel free to hack the tool to write it back. Note that the format of the structure is a bit weird, I'd suggest you read some MacOS litterature on the subject, though all you really want is probably just to set it all to 0 Ben
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <errno.h> /* Some offsets in XPRAM */ #define PMAC_XPRAM_MACHINE_LOC 0xe4 #define PMAC_XPRAM_SOUND_VOLUME 0x08 /* Machine location structure in XPRAM */ struct pmac_machine_location { unsigned int latitude; /* 2+30 bit Fractional number */ unsigned int longitude; /* 2+30 bit Fractional number */ unsigned int delta; /* mix of GMT delta and DLS */ }; /* /dev/nvram ioctls */ #define PMAC_NVRAM_GET_OFFSET _IOWR('p', 0x40, int) /* Get NVRAM partition offset */ enum { pmac_nvram_OF, /* Open Firmware partition */ pmac_nvram_XPRAM, /* MacOS XPRAM partition */ pmac_nvram_NR /* MacOS Name Registry partition */ }; int main(int argc, char *argv[]) { int fd, rc, offset; int goff, dst; struct pmac_machine_location loc; fd = open("/dev/nvram", O_RDWR); if (fd < 0) { perror("Can't open /dev/nvram"); return ENODEV; } offset = pmac_nvram_XPRAM; rc = ioctl(fd, PMAC_NVRAM_GET_OFFSET, &offset); if (rc != 0) { perror("Can't get XPRAM offset"); close(fd); return ENXIO; } printf("XPRAM offset in nvram: %d\n", offset); lseek(fd, offset + PMAC_XPRAM_MACHINE_LOC, SEEK_SET); rc = read(fd, &loc, sizeof(loc)); if (rc != sizeof(loc)) { perror("Can't read machine location record"); close(fd); return EIO; } printf("Machine location:\n"); printf("latitude : %08lx\n", loc.latitude); printf("longitude : %08lx\n", loc.longitude); dst = loc.delta >> 24; loc.delta &= 0x00ffffff; if (loc.delta & 0x00800000) loc.delta |= 0xff000000; goff = *((int *)&loc.delta); printf("offset : %d\n", goff); printf("dst : %d\n", dst); close(fd); return 0; }