1,在 32 位系统中,jiffies 是一个 32 位的无符号整数。
/*
* Have the 32 bit jiffies value wrap 5 minutes after boot
* so that the jiffies_wrap test works correctly.
*/
extern u64 jiffies_64;
extern unsigned long volatile jiffies;
#if BITS_PER_LONG < 64
// 对于 32 位系统,初始值设置为 (unsigned long)(-300*HZ)
// 即距离 0 溢出仅剩 300 秒(5分钟)
# define INITIAL_JIFFIES ((unsigned long)(unsigned int)(-300*HZ))
#else
// 对于 64 位系统,初始值就是 0
# define INITIAL_JIFFIES 0
#endif
注:HZ 是内核每秒的时钟中断频率(通常是 200 ),查看内核宏配置
CIONFIG_HZ=200
实际的 jiffies 变量定义在内核的主时间文件中。
-
文件路径:
kernel/time/timer.c/* * The current time: * wall_to_monotonic is what we need to add to xtime (or xtime corrected * for sub jiffie times) to get to monotonic time. Monotonic is pegged * at zero at system boot. */ // 这里使用上面的宏 INITIAL_JIFFIES 进行初始化 unsigned long volatile __cacheline_aligned jiffies = INITIAL_JIFFIES;
为什么不为 0: 为了在 32 位系统启动后的 5 分钟内 强制触发一次时间回绕,从而尽早测试和暴露内核代码中关于时间比较的 Bug。
-
32 位最大值:
4294967295(0xFFFFFFFF0xFFFFFFFF) -
初始值计算:
Initial=Max_Value−Offset+1Initial=Max_Value−Offset+1
所以,初始值=4294967296−60000=4294907296
-
打开文件:
init/main.c -
找到函数
start_kernel,在函数末尾(在rest_init();之前)加入以下代码:/* --- Debug Code Start --- */ printk(KERN_EMERG "=== System Boot Debug Info ===\n"); printk(KERN_EMERG "HZ is %d\n", HZ); printk(KERN_EMERG "Current jiffies is %lu\n", jiffies); /* --- Debug Code End --- */
预期打印结果
当你启动内核,连接串口后,你会看到类似以下的输出(数字是计算好的):
[ 0.000000] === System Boot Debug Info ===
[ 0.000000] HZ is 200
[ 0.000000] Current jiffies is 4294907296
5 分钟后打印是啥?
-
计算过程:
Current=Initial+60,000Current=Initial+60,000
Current=4,294,907,296+60,000Current=4,294,907,296+60,000
Current=4,294,967,296Current=4,294,967,296
-
溢出判定:
- 32 位无符号整数的最大值是
4,294,967,295(0xFFFFFFFF0xFFFFFFFF)。 - 当数值达到
4,294,967,296时,刚好超过了最大值 1。 - 根据模运算,它会回绕到 0。
- 32 位无符号整数的最大值是
打印结果为:
Current jiffies is 0