linux0.11内核源码修仙传第九章——时间初始化

🚀 前言

    本文主要解释了计算机断电重启后能准确读取时间的原因,内容很短,对应于书中的第17回。希望各位给个三连,拜托啦,这对我真的很重要!!!

🏆 计算机时间从哪里来

    熟悉嵌入式的都知道硬件上有一个模块叫实时时钟(Real Time Clock,RTC),也叫CMOS时钟。这个模块的电源是独立的,采用纽扣电池供电。当操作系统关机时,就用这个来记录时间。其工作原理类似电子手表,通过石英晶体振荡记录时间流逝。

🏆 时间初始化

    知道了上电后时间从哪里来后,我们只需要关注内核中如何获取即可。内核中时间初始化的源码如下:

static void time_init(void)
{
	struct tm time;

	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);
	time.tm_mon--;
	startup_time = kernel_mktime(&time);
}

   这个函数里面最多的就是CMOS_READ以及BCD_TO_BIN宏函数,按照字面意思,CMOS_READ就是读取CMOS的数据,分别是年,月,日,小时,分钟,秒;BCD_TO_BIN就是将BCD码(CMOS RAM中存放数据的编码格式)转换为我们常用的二进制。

    首先是CMOS_READ函数:

#define CMOS_READ(addr) ({ \
outb_p(0x80|addr,0x70); \
inb_p(0x71); \
})

    可以看到这个宏函数是先写再读,实际上这也是CPU与外设交互的做法,都是通过端口写入值让外设干嘛,再从另一个端口读值接收外设的反馈。按照CMOS手册要求的读写端口进行读写即可,就像上面代码的循环里面一样。

    接下来看BCD_TO_BIN 函数:

#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)

    由于是BCD码,即四位表示十进制的一位,因此首先先把后四位与15(0b1111)做与运算,后面将前面4位后移并乘10表示十位,最后将十位与个位进行相加。

    最后还有一个函数:

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;
}

    这个函数在时间初始化的最后,这就是一个简单的换算,目的是为了计算从1970年1月1日0时起至开机当前经过的秒数,作为开机时间存储在变量中。

🎯总结

    本文是一个很简单的模块——时间初始化。其核心就是CPU访问外设是通过端口的,先向端口写入一个指令表示我要干什么,然后再去另一个端口读取反馈数据。


📖参考资料

[1] linux源码趣读
[2] 一个64位操作系统的设计与实现
[3] Linux内核的时间管理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值