标签:
每次使用 date 命令设置主机时间,再次重启后时间就和设置的不一样了!查看启动时的日志:
对应的代码为 arch/i386/isa/clock.c 的 startrtclock 函数:
/* Check diagnostic status */ outb (IO_RTC, RTC_DIAG); if (s = inb (IO_RTC+1)) printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS);
为什么 RTC 的诊断状态会不对呢?
经过调试和更高版本的NetBSD代码比对之后,发现问题的原因为同一个文件里的 resettodr 函数:
rtclk.rtc_min = dectohexdec(n%60); rtclk.rtc_hr = dectohexdec(n/60); n = (time.tv_sec - diff) / (3600 * 24); /* days */ rtclk.rtc_dow = (n + 4) % 7; /* 1/1/70 is Thursday */ for (j = 1970, i = yeartoday(j); n >= i; j++, i = yeartoday(j)) n -= i; rtclk.rtc_yr = dectohexdec(j - 1900); if (i == 366) month[1] = 29; for (i = 0; n >= month[i]; i++) n -= month[i]; month[1] = 28; rtclk.rtc_mon = dectohexdec(++i); rtclk.rtc_dom = dectohexdec(++n);
红色粗体部分,直接设置年份为当前年份和 1900 年的差值。但是从 RTC 读取的时候,却又是:
sec = hexdectodec(rtclk.rtc_sec); min = hexdectodec(rtclk.rtc_min); hr = hexdectodec(rtclk.rtc_hr); dom = hexdectodec(rtclk.rtc_dom); mon = hexdectodec(rtclk.rtc_mon); yr = hexdectodec(rtclk.rtc_yr); yr = (yr < 70) ? yr+100 : yr; n = sec + 60 * min + 3600 * hr; n += (dom - 1) * 3600 * 24; if (yeartoday(yr) == 366) month[1] = 29;
保存在 RTC 里的年份数值只是实际年份的后两位,所以修改代码为:
rtclk.rtc_min = dectohexdec(n%60); rtclk.rtc_hr = dectohexdec(n/60); n = (time.tv_sec - diff) / (3600 * 24); /* days */ rtclk.rtc_dow = (n + 4) % 7; /* 1/1/70 is Thursday */ for (j = 1970, i = yeartoday(j); n >= i; j++, i = yeartoday(j)) n -= i; rtclk.rtc_yr = dectohexdec( ( j - 1900 ) % 100 ); if (i == 366) month[1] = 29; for (i = 0; n >= month[i]; i++) n -= month[i]; month[1] = 28; rtclk.rtc_mon = dectohexdec(++i); rtclk.rtc_dom = dectohexdec(++n);
重编译并更新内核之后,问题解决。
标签:
原文地址:http://www.cnblogs.com/StupidTortoise/p/4321069.html