杭电Linux操作系统添加系统调用实验

一:题目介绍

修改或返回指定进程的优先级(nice值和prio值)(详见教材P328)

         提示:可能参考的内核函数:set_user_nice()

二:思路分析

图1:系统调用总流程

描述:本实验主要实现了系统调用的添加,其过程书上已经详细给出,先在系统调用表中添加系统调用号,再申明添加的系统调用,最后开始编写内核函数。至此添加系统调用已经完成,之后为了使用它,将内核编译和安装。重启之后使用内核并编写测试文件来调用系统调用。

图2:内核函数流程

描述:在该内核函数中,先根据输入的pid值指定进程,并返回进程控制块,借此来获得该进程的nice和prio值。之后再根据输入的flag标志来判断是否要更改指定进程的nice和prio值。若flag=0,则不更改,通过copy_to_user()函数将其写入用户空间以便使用,若flag=1,则通过set_user_nice()函数进行更改,之后再利用copy_to_user()函数将其写入用户空间以便使用。该代码中主要使用了五个信号量。其中四个为功能实现中使用者需要输入的值:pid(指定进程),nice(需要输出进程的值),flag(判断是否要更改的值),nicevalue(更改后的进程的nice值)。还有一个需要输出的进程的prio值,但由于prio根据nice值的更改而更改,所以该值不要使用者输入,自动变化。

三:遇到问题及解决方法

问题:gcc版本太高出解决方法:gcc9版本太高有些不兼容,之后下载gcc8解决。

问题:一开始将问题想的太简单,对内核函数传参传入nice时,想在内核函数中直接将nice值修改,但是运行后失败 

解决方法:查询后是发现内核空间和用户空间不能直接互访,所以必须使用copy_to_user ()函数来在内核函数内改变nice值。

问题:No rule to make target 'debian/certs/benh@debian.org.cert.pem', needed by 'certs/x509_certificate_list'. Stop.

解决方法:进入.Config将CONFIG_SYSTEM_TRUSTED_KEYS设为空

问题:虚拟机内存较小,导致编译内核以及安装之后无法打开

解决方法:重新建立一个虚拟机将内存设置为60G,内核设置4个

问题:虚拟机重启之后无法转换到指定的内核

解决方法:修改grub文件将GRUB_TIMEOUT_STYLE注释掉,并将GRUB_TIMEOUT改为10

四:代码及注释

内核函数及注释:

SYSCALL_DEFINE5(setorlook,pid_t,pid,int,flag,int,nicevalue,void __user*,prio,void __user*,nice)
{
	int n;
	int p;
	struct pid * kpid;
	struct task_struct * task;
	kpid = find_get_pid(pid);/*得到pid */
	task = pid_task(kpid, PIDTYPE_PID);/* 返回task_struct */
	n = task_nice(task);/* 返回进程当前nice值 */
	p = task_prio(task);/*返回进程当前prio值*/
	if(flag == 1)
	{
		set_user_nice(task, nicevalue);/* 修改进程nice值 */
		n = task_nice(task);/*重新取得进程nice值*/
		p = task_prio(task);/*重新取得进程prio值*/
		copy_to_user(nice,&n,sizeof(n));/*将nice值拷贝到用户空间*/
		copy_to_user(prio,&p,sizeof(p));/*将prio值拷贝到用户空间*/
		return 0;  
	}
	else if(flag == 0)
	{
		copy_to_user(nice,&n,sizeof(n));/*将nice值拷贝到用户空间*/
		copy_to_user(prio,&p,sizeof(p));/*将prio值拷贝到用户空间*/
		return 0;
	}
	return EFAULT;
}

测试代码:

#define _GNU_SOURCE
#include<unistd.h>
#include<sys/syscall.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{
	pid_t pid;
	int nicevalue;
	int flag;
	int n=0;
	int p=0;
	int *prio;
	int *nice;
	prio = &p;
	nice = &n;
	printf("请输入你所指定的pid: \n");
	scanf("%d",&pid);
	printf("指定的pid输入成功\n");
	printf("请输入flag   (flag为1时修改信息,为0时查看信息):\n");
	scanf("%d",&flag);
	if(flag==1){
	printf("请输入nice值:\n");
	scanf("%d",&nicevalue);
	printf("nice输入成功\n");
	}
	else{
	    nicevalue=0;
	}
	syscall(335,pid,flag,nicevalue,prio,nice);
	printf("pid为%d的进程目前的nice为%d,prio为%d\n",pid,n,p);
	return 0;
}

五:实验结果

图三:包含更改和查看进程的实验结果 

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值