13)时间初始化

time_init

启动后系统就会记录显示时间,这部分就是又这里实现的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// init/main.c
#define CMOS_READ(addr) ({ \
outb_p(0x80|addr,0x70); \
inb_p(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);
}

根据上面的代码,我们只需要了解 CMOS_READBCD_TO_BIN

CMOS_READ

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

CMOS_READ是一个宏 先向寄存器写一个值,再读出一个值

outb_p 和 inb_p 是Linux内核中用于访问I/O端口的函数。这些函数通常在包含 <asm/io.h> 头文件的代码中使用。

outb_p(value, port):这个函数用于向指定的端口(port)输出一个字节(value)。p 后缀表示这个调用是“慢速”的,它在执行输出操作之前会等待任何正在进行的I/O操作完成。这对于确保在慢速设备或复杂的硬件环境中数据正确传输非常重要。

inb_p(port):这个函数从指定的端口(port)读取一个字节的数据。同样,p 后缀表示这个调用是“慢速”的,它会等待任何正在进行的I/O操作完成之后才读取数据。

outb_p(0x80|addr, 0x70):将CMOS地址(addr)与0x80进行按位或操作,这是为了指定这是一个读操作(CMOS芯片通常使用最高位作为读/写标志位)。然后,这个组合后的地址被发送到0x70端口,以便选择要读取的CMOS寄存器。

inb_p(0x71):在指定了要读取的寄存器之后,从0x71端口读取一个字节的数据,这个数据就是从之前选定的CMOS寄存器中读取的。

CMOS存储器中存储时间是通过一个实时时钟(RTC, Real-Time Clock)芯片完成的。RTC芯片负责计时,即使系统关闭电源或重启,它也依靠CMOS电池供电,确保时间持续走动。

RTC存储时间的方式

  1. 数据格式
    • 时间通常以 BCD(Binary-Coded Decimal,二进制编码十进制) 格式存储。
      • 例如:上午8:35 会存储为08:35,每个位的值直接用4位二进制表示(08 → 0000 1000)。
    • 存储的内容包括:
      • 秒、分钟、小时
      • 星期、日期、月份和年份
  2. 内存地址映射
    • RTC芯片通过特定的内存地址映射到CMOS中,比如常见的芯片(如MC146818)会占用CMOS的0x00到0x0F地址区域。每个地址保存一个时间字段:
      • 0x00:秒
      • 0x02:分钟
      • 0x04:小时
      • 0x06:星期
      • 0x07:日期
      • 0x08:月份
      • 0x09:年份

BCD_TO_BIN

上面有提到RTC使用BCD的格式来储存时间,所以BCD_TO_BIN就是用来转换数据格式的,将BCD转换成二进制数据

最后一步 kernel_mktime 也很简单,就是根据刚刚的那些时分秒数据,计算从 1970 年 1 月 1 日 0 时起到开机当时经过的秒数,作为开机时间,存储在 startup_time 这个变量里。


13)时间初始化
https://carl-5535.github.io/2024/10/14/Linux0.11/13)时间初始化/
作者
Carl Chen
发布于
2024年10月14日
许可协议