【OS】实验五:内核时间管理

1,154 阅读1分钟

实验五:内核时间管理

任务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

内核模块加载结果

image-20211225174450149

image-20211225174502678

出现以上错误:

	get_timespec64(&tv,NULL);
	rtc_time64_to_tm(tv.tv_sec, &tm);

加入#include <linux/time64.h>,替换这两个函数即可

image-20211225181025467

任务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

内核模块加载结果

image-20211225195234181

任务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

内核模块加载结果

image-20211225225000096

运行结果可以看出,从 1 到 100000 的累加和所花时间是2260ns。