时间子系统9_timekeeper初始化

简介:
//Timekeeping
//	Timekeeping子系统负责更新xtime, 调整误差, 及提供get/settimeofday接口.
//Times in Kernel
//kernel的time基本类型:
//	1) system time
//		A monotonically increasing value that represents the amount of time the system has been running. 
//		单调增长的系统运行时间, 可以通过time source, xtime及wall_to_monotonic计算出来.
//	2) wall time
//		A value representing the the human time of day, as seen on a wrist-watch. Realtime时间: xtime.
//	3) time source
//		A representation of a free running counter running at a known frequency, usually in hardware, e.g GPT. 
//		可以通过clocksource->read()得到counter值
//	4) tick
//		A periodic interrupt generated by a hardware-timer, typically with a fixed interval defined by HZ: jiffies
//	这些time之间互相关联, 互相可以转换:
//		system_time = xtime + cyc2ns(clock->read() - clock->cycle_last) + wall_to_monotonic;
//		real_time = xtime + cyc2ns(clock->read() - clock->cycle_last)
//		也就是说real time是从1970年开始到现在的nanosecond, 而system time是系统启动到现在的nanosecond.
//		这两个是最重要的时间, 由此hrtimer可以基于这两个time来设置过期时间. 所以引入两个clock base.
//	参考:http://blog.csdn.net/hongjiujing/article/details/7070746

//	全局timekeeper
1.1 struct timekeeper timekeeper;
//	timekeeper框架初始化
//		初始化clocksource
//	调用路径:start_kernel->timekeeping_init
//	函数任务:
//		1.使用默认时间源初始化全局timekeeper
//		2.初始化墙上时间xtime
//		3.初始化wall_to_monotonic,使其与xtime相加得到系统启动以来的单调时间
//	注:
//		Network Time Protocol(NTP)是用来使计算机时间同步化的一种协议,
//		它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,
//		它可以提供高精准度的时间校正(LAN上与标准间差小于1毫秒,WAN上几十毫秒).
1.2 static void __init timekeeping_init(void)
{
	struct clocksource *clock;
	unsigned long flags;
	struct timespec now, boot;
	//通过cmos获取当前时间
	read_persistent_clock(&now);
	//系统启动时的时间
	read_boot_clock(&boot);
	write_seqlock_irqsave(&xtime_lock, flags);
	//ntp初始化
	ntp_init();
	//x86架构下默认的时钟源,jiffies_clocksource
	clock = clocksource_default_clock();
	//使能时钟源
	if (clock->enable)
		clock->enable(clock);
	//使用clocksource初始化全局timekeeper
	timekeeper_setup_internals(clock);
	//初始化墙上时间
	xtime.tv_sec = now.tv_sec;
	xtime.tv_nsec = now.tv_nsec;
	raw_time.tv_sec = 0;
	raw_time.tv_nsec = 0;
	//如果体系结构没有提供read_boot_clock,设置启动时间为当前时间
	if (boot.tv_sec == 0 && boot.tv_nsec == 0) {
		boot.tv_sec = xtime.tv_sec;
		boot.tv_nsec = xtime.tv_nsec;
	}
	//通过将wall_to_monotonic加到xtime,获取系统启动以来的单调时间
	set_normalized_timespec(&wall_to_monotonic,
				-boot.tv_sec, -boot.tv_nsec);

	total_sleep_time.tv_sec = 0;
	total_sleep_time.tv_nsec = 0;
	write_sequnlock_irqrestore(&xtime_lock, flags);
}

//	timekeeper初始化
//	函数任务:
//		1.绑定timekeeper到clocksource
//		2.换算NTP间隔为clocksource的cycle
//	调用路径:timekeeping_init->timekeeper_setup_internals
//	注:
//		1.timekeeper.cycle_interval,一个NTP间隔对应的时钟cycle
//		2.timekeeper.xtime_interval, 一个NTP间隔对应的时钟cycle*mult
//		3.timekeeper.raw_interval,	一个NTP间隔(近似值)
1.3 static void timekeeper_setup_internals(struct clocksource *clock)
{
	cycle_t interval;
	u64 tmp;
	//timekeeper使用提供的时钟源
	timekeeper.clock = clock;
	clock->cycle_last = clock->read(clock);

	//NTP_INTERVAL_LENGTH转换为clocksource的cycle
	tmp = NTP_INTERVAL_LENGTH;
	tmp <<= clock->shift;
	tmp += clock->mult/2;
	do_div(tmp, clock->mult);
	if (tmp == 0)
		tmp = 1;

	//一个NTP间隔对应的时钟cycle
	interval = (cycle_t) tmp;
	timekeeper.cycle_interval = interval;

	//一个NTP间隔对应的xtime间隔
	timekeeper.xtime_interval = (u64) interval * clock->mult;
	//
	timekeeper.raw_interval =
		((u64) interval * clock->mult) >> clock->shift;

	timekeeper.xtime_nsec = 0;
	//使用时钟源的shift
	timekeeper.shift = clock->shift;
	//累积的时间相对于NTP的误差
	timekeeper.ntp_error = 0;
	timekeeper.ntp_error_shift = NTP_SCALE_SHIFT - clock->shift;
	timekeeper.mult = clock->mult;

}

目录
相关文章
|
3月前
|
传感器 Linux API
如何实现 MCU软件中多个模块初始化函数的优雅调用
如何实现 MCU软件中多个模块初始化函数的优雅调用
|
10月前
|
Android开发 C++
Android系统的Ashmem匿名共享内存子系统分析(3)- Ashmem子系统的 C/C++访问接口
Android系统的Ashmem匿名共享内存子系统分析(3)- Ashmem子系统的 C/C++访问接口
126 0
|
监控 API
驱动开发:对象回调监控文件访问
无论在用户层还是内核层,操作文件的流程基本一致,除了在API函数上的区别(用户层调用用户层API,内核层调用内核API)以外其他基本一致,先讲解一下文件系统执行的流程。实现文件的监控呢,比如当文件被访问时自动触发回调,看如下代码实现方式。
198 0
|
监控 Windows
驱动开发:监控进程与线程对象操作
监控进程对象和线程对象操作,可以使用`ObRegisterCallbacks`这个内核回调函数,通过回调我们可以实现保护calc.exe进程不被关闭,具体操作从`OperationInformation->Object`获得进程或线程的对象,然后再回调中判断是否是计算器,如果是就直接去掉`TERMINATE_PROCESS`或`TERMINATE_THREAD`权限即可。
291 0
驱动开发:监控进程与线程对象操作
|
Java 程序员 调度
线程的创建方式,状态周期管理
进程是计算机中的程序,关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。
105 0
线程的创建方式,状态周期管理
|
Linux Windows 内存技术
PCIe初始化枚举和资源分配流程分析
本文主要是对PCIe的初始化枚举、资源分配流程进行分析,代码对应的是alikernel-4.19,平台是arm64 ## 1. PCIe architecture ### 1.1 pcie的拓扑结构 在分析PCIe初始化枚举流程之前,先描述下pcie的拓扑结构。 如下图所示: ![11.png](https://ata2-img.oss-cn-zhangjiakou.aliyuncs
6543 1
PCIe初始化枚举和资源分配流程分析