LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 894|回复: 6

请教各位大大,开机秒时间有何作用,在init/main.c中调用kerne_mktime计算从1970年到现

[复制链接]
发表于 2005-4-11 16:17:16 | 显示全部楼层 |阅读模式
在init/main.c中调用kerne_mktime计算从1970年到现在的开机时间秒,有何作用,请指教,谢谢!!
发表于 2005-4-11 20:00:56 | 显示全部楼层
你的机器上显示的时间  比如  2005.4.11   20:02   就是根据这个算出来的吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-12 09:02:08 | 显示全部楼层
谢谢!!!
能否详细的说一下,在time_init中的do {
                time.tm_sec = CMOS_READ(0);
                time.tm_min = CMOS_READ(2);
                time.tm_hour = CMOS_READ(4);
                time.tm_mday = CMOS_READ(7);
                time.tm_mon = CMOS_READ(8);
                time.tm_year = CMOS_READ(9);
        } while (time.tm_sec != CMOS_READ(0));
        BCD_TO_BIN(time.tm_sec);
        BCD_TO_BIN(time.tm_min);
        BCD_TO_BIN(time.tm_hour);
        BCD_TO_BIN(time.tm_mday);
        BCD_TO_BIN(time.tm_mon);
        BCD_TO_BIN(time.tm_year);
这儿不是从CMOS中读出了时间,并且转换为二进制了吗?为何还要算距离1970年的时间?
回复 支持 反对

使用道具 举报

发表于 2005-4-12 09:10:50 | 显示全部楼层
CMOS里面存储的时间是相距1970年的时间,记得是这样,至于CMOS里面为什么这样存储时间,就不清楚了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-12 16:37:16 | 显示全部楼层
谢谢!
在这方面我还是有点不是很明白,我看的1.0的linux内核
在main()中调用time_init(),函数的
do {
time.tm_sec = CMOS_READ(0);
time.tm_min = CMOS_READ(2);
time.tm_hour = CMOS_READ(4);
time.tm_mday = CMOS_READ(7);
time.tm_mon = CMOS_READ(8);
time.tm_year = CMOS_READ(9);
} while (time.tm_sec != CMOS_READ(0));
BCD_TO_BIN(time.tm_sec);
BCD_TO_BIN(time.tm_min);
BCD_TO_BIN(time.tm_hour);
BCD_TO_BIN(time.tm_mday);
BCD_TO_BIN(time.tm_mon);
BCD_TO_BIN(time.tm_year);
/*是从CMOS中读出了现在de时间,并且转换为二进制,不知到是否正确*/
time.tm_mon--;
        startup_time = kernel_mktime(&time);
函数kernel_mktime,计算的是从1970年到现在的时间秒
#define MINUTE 60
#define HOUR (60*MINUTE)
#define DAY (24*HOUR)
#define YEAR (365*DAY)

/* interestingly, we assume leap-years */
static int month[12] = {
        0,
        DAY*(31),
        DAY*(31+29),
        DAY*(31+29+31),
        DAY*(31+29+31+30),
        DAY*(31+29+31+30+31),
        DAY*(31+29+31+30+31+30),
        DAY*(31+29+31+30+31+30+31),
        DAY*(31+29+31+30+31+30+31+31),
        DAY*(31+29+31+30+31+30+31+31+30),
        DAY*(31+29+31+30+31+30+31+31+30+31),
        DAY*(31+29+31+30+31+30+31+31+30+31+30)
};

long kernel_mktime(struct tm * tm)
{
        long res;
        int year;

        year = tm->tm_year - 70;
/* magic offsets (y+1) needed to get leapyears right.*/
        res = YEAR*year + DAY*((year+1)/4);
        res += month[tm->tm_mon];
/* and (y+2) here. If it wasn't a leap-year, we have to adjust */
        if (tm->tm_mon>1 && ((year+2)%4))
                res -= DAY;
        res += DAY*(tm->tm_mday-1);
        res += HOUR*tm->tm_hour;
        res += MINUTE*tm->tm_min;
        res += tm->tm_sec;
        return res;
}
根据返回值startup_time,用来干啥?还有就是在上面的计算中year = tm->tm_year - 70;如果tm->tm_year 小于70,是不是出现问题?
谢谢!!
回复 支持 反对

使用道具 举报

发表于 2005-4-12 20:50:08 | 显示全部楼层
不好意思,看这代码的意思,我是说错了

do {
time.tm_sec = CMOS_READ(0);
time.tm_min = CMOS_READ(2);
time.tm_hour = CMOS_READ(4);
time.tm_mday = CMOS_READ(7);
time.tm_mon = CMOS_READ(8);
time.tm_year = CMOS_READ(9);
}
来看,BIOS里面存放的是 年月日 格式的时间

1.0我不清楚,不过我想原理大概差不多,在 2.6 里面系统启动的时候读取BIOS,
读取的目的只是为了初始化一个墙上时钟  xtime
他是一个结构体

struct timespec   xtime;
struct timespe{
         time_t   tv_sec;
         long   tv_nsec;
}
      这个结构里面的就是相距1970年1月1日的秒和微秒,从此后,系统不会再去读BIOS时间而是一直使用这个xtime,看了一下你贴的代码,觉得那个res和这个xtime的作用是一样的这个就是以后系统中(开机期间)使用的时间了。
      例如你要知道当前时间,系统就会读出xtime,然后再转化成你看到的时间,当然转换的工作应该是用户程序去做的
      我觉得这样做的目的在于,我们不可能每次要当前时间都去读BIOS,所以要有一个变量来记录,至于为什么选择这样的变量(xtime , res),我觉得因为这样方便吧,而且这个变量随着时间推移,系统要一个维护的,每个tick (时钟中断) 需要增加 ,xtime这样的变量,加起来容易一些吧,不需要太多的操作,简单的加就可以了,比起维护一个 年月日 格式的时间开销小很多
      个人看法,不知你觉得那?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-13 09:02:12 | 显示全部楼层
谢谢!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表