2.8 开机启动时间设置
开机启动时间是大部分与时间相关的计算的基础。操作系统中一些程序的运算需要时间参数;很多事务的处理也都要用到时间,比如文件修改的时间、文件最近访问的时间、i节点自身的修改时间等。有了开机启动时间,其他时间就可据此推算出来。
具体执行步骤是:CMOS是主板上的一个小存储芯片,系统通过调用time_init()函数,先对它上面记录的时间数据进行采集,提取不同等级的时间要素,比如秒(time.tm_sec)、分(time.tm_min)、年(time.tm_year)等,然后对这些要素进行整合,并最终得出开机启动时间(startup_time)。
执行代码如下:
- //代码路径:init/main.c:
- void main(void)
- {
- …
- time_init();
- …
- }
- #define CMOS_READ(addr) ({ \ //读CMOS实时时钟信息
- outb_p(0x80|addr,0x70); \ //0x80|addr读CMOS地址,0x70写端口
- inb_p(0x71); \ //0x71读端口
- })
- #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)//十进制转二进制
- 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); //开机时间,从1970年1月1日0时计算
- }
- //代码路径:include\asm\io.h: //嵌入汇编参看trap_init的注释
- #define outb_p(value,port) \ //将value写到port
- __asm__ ("outb %%al,%%dx\n" \
- "\tjmp 1f\n" \ //jmp到下面的第一个1:处,目的是延迟
- "1:\tjmp 1f\n" \
- "1:"::"a" (value),"d" (port))
- #define inb_p(port) ({ \
- unsigned char _v; \
- __asm__ volatile ("inb %%dx,%%al\n" \ // volatile,禁止编译器优化下列代码
- "\tjmp 1f\n" \ //延迟
- "1:\tjmp 1f\n" \
- "1:":"=a" (_v):"d" (port)); \
- _v; \
- })
计算过程及开机启动时间在内存中的存储位置如图2-16所示。