答案1
RTC 时钟将其时间保存在电池供电的 CMOS 内存中(如今它只是一个模拟旧设计的集成度更高的芯片)。CMOS 内存映射在兼容 PC 的计算机上非常标准。根据这些CMOS 内存映射文档:
00h 秒 (BCD 00-59, Hex 00-3B) 注意:第 7 位是只读的 01h 秒闹钟(BCD 00-59,十六进制 00-3B;如果是 C0-FF 则“无所谓”) 02h 分钟(BCD 00-59,十六进制 00-3B) 03h 分钟闹钟(BCD 00-59,十六进制 00-3B;如果是 C0-FF,则“无所谓”) 04h 小时(BCD 00-23,如果为 24 小时模式则为十六进制 00-17) (BCD 01-12,如果是上午 12 点,则为十六进制 01-0C) (BCD 81-92。如果下午 12 点,则为十六进制 81-8C) 05h 小时闹钟(与小时相同;如果为 C0-FF,则“无所谓”) 06h 星期几(01-07 星期日=1) 07h 月份日期(BCD 01-31,十六进制 01-1F) 08h 月 (BCD 01-12,十六进制 01-0C) 09h 年份 (BCD 00-99,十六进制 00-63)
因此,可以通过直接日历数学将这些字段转换为您喜欢的任何格式:Unix 时间戳、DOS 类型的日期/时间格式或其他格式。
请注意,上图中缺少一个字段,即时区和 DST 设置。因此,如果您双启动 Windows 和 Linux,则可能会遇到问题。Windows 默认为您的本地时区,而 Linux 通常假设 RTC 日期/时间为 UTC(我认为这更合理)。
答案2
似乎(从奥斯德夫和Linuxarch/x86/kernel/rtc.c
) Intel x86 平台上的 RTC 将日期时间保存为秒、分、时等单独的值。
要从 RTC 获取以下每个日期/时间值,您应首先验证状态寄存器 A 未处于“更新模式”(位 7,值 = 0x80 为清除状态)。然后以通常的方式选择相关的“CMOS 寄存器”,并从端口 0x71 读取值。
Register Contents
0 Seconds
2 Minutes
4 Hours
6 Weekday
7 Day of Month
8 Month
9 Year
0x32 Century (usually)
0xa Status Register A
0xb Status Register B
所有这些寄存器的内容都使用高级数学(即加法和乘法)转换为 NT 或 Unix 时间戳。有关 Linux 示例,请参阅kernel/time.c:mktime
在内核源代码中。
return ((((unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + year*365 - 719499)*24 + hour)*60 + min)*60 + sec;
此外,您链接的 MSKB 文章有些过时了。从 XP 开始,Windows 不再每小时检查一次 RTC;而是使用 NTP,并且写信给RTC。
答案3
“时间戳”(主要在 *nix 系统或任何类似 C 的语言中)通常表示自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数