实验五:内核时间管理
任务1:调用内核时钟接口打印当前时间
编写内核模块,调用内核时钟接口,打印出系统当前时间。格式示例:2020-03-09 11:54:31;
源代码
current_time.c
#include <linux/module.h>
#include <linux/time.h>
#include <linux/time64.h>
#include <linux/rtc.h>
MODULE_LICENSE("GPL");
struct timespec64 tv;
struct rtc_time tm;
static int __init currenttime_init(void)
{
int year, mon, day, hour, min, sec;
printk("Start current_time module...\n");
get_timespec64(&tv,NULL);
rtc_time64_to_tm(tv.tv_sec, &tm);
year = tm.tm_year + 1900;
mon = tm.tm_mon + 1;
day = tm.tm_mday;
hour = tm.tm_hour + 8;
min = tm.tm_min;
sec = tm.tm_sec;
printk("Current time: %d-%02d-%02d %02d:%02d:%02d\n", year, mon, day, hour, min, sec);
return 0;
}
static void __exit currenttime_exit(void)
{
printk("Exit current_time module...\n");
}
module_init(currenttime_init);
module_exit(currenttime_exit);
Makefile
ifneq ($(KERNELRELEASE),)
obj-m := current_time.o
else
KERNELDIR ?= /root/kernel-5.10.0-13.0.0
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
.PHONY:clean
clean:
-rm *.mod.c *.o *.order *.symvers *.ko
内核模块加载结果
出现以上错误:
get_timespec64(&tv,NULL);
rtc_time64_to_tm(tv.tv_sec, &tm);
加入#include <linux/time64.h>,替换这两个函数即可
任务2:编写timer,在特定时刻打印 hello,world
编写内核模块程序,实现一个timer,该定时器延时10秒后打印“hello,world”
源代码
timer_example.c
#include <linux/module.h>
#include <linux/timer.h>
MODULE_LICENSE("GPL");
struct timer_list timer;
void print(struct timer_list *timer)
{
printk("hello,world!\n");
}
static int __init timer_init(void)
{
printk("Start timer_example module...\n");
timer.expires = jiffies + 10 * HZ;
timer.function = print;
add_timer(&timer);
return 0;
}
static void __exit timer_exit(void)
{
printk("Exit timer_example module...\n");
}
module_init(timer_init);
module_exit(timer_exit);
Makefile
ifneq ($(KERNELRELEASE),)
obj-m := timer_example.o
else
KERNELDIR ?= /root/kernel-5.10.0-13.0.0
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
.PHONY:clean
clean:
-rm *.mod.c *.o *.order *.symvers *.ko
内核模块加载结果
任务3:调用内核时钟接口,监控累加计算代码的运行时间
调用内核时钟接口,编写内核模块,监控实现累加计算sum=1+2+3+...+100000 所花时间
源代码
sum_time.c
#include <linux/module.h>
#include <linux/time.h>
MODULE_LICENSE("GPL");
#define NUM 100000
struct timeval tv;
static long sum(int num)
{
int i;
long total = 0;
for (i = 1; i <= NUM; i++)
total = total + i;
printk("The sum of 1 to %d is: %ld\n", NUM, total);
return total;
}
static int __init sum_init(void)
{
int start;
int start_u;
int end;
int end_u;
long time_cost;
long s;
printk("Start sum_time module...\n");
gettimeofday(&tv,null);
start = (int)tv.tv_sec;
start_u = (int)tv.tv_usec;
printk("The start time is: %d s %d us \n", start, start_u);
s = sum(NUM);
gettimeofday(&tv,null);
end = (int)tv.tv_sec;
end_u = (int)tv.tv_usec;
printk("The end time is: %d s %d us \n", end, end_u);
time_cost = (end - start) * 1000000 + end_u - start_u;
printk("The cost time of sum from 1 to %d is: %ld us \n", NUM, time_cost);
return 0;
}
static void __exit sum_exit(void)
{
printk("Exit sum_time module...\n");
}
module_init(sum_init);
module_exit(sum_exit);
Makefile
ifneq ($(KERNELRELEASE),)
obj-m := sum_time.o
else
KERNELDIR ?= /root/kernel-5.10.0-13.0.0
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
.PHONY:clean
clean:
-rm *.mod.c *.o *.order *.symvers *.ko
内核模块加载结果
运行结果可以看出,从 1 到 100000 的累加和所花时间是2260ns。