实验2 添加系统调用小组题目
配置
openEuler 20.03内核
openEuler 20.03 64bit with ARM
12vCPUs | 24GiB | 华为云云服务器
题目
题目1:修改或返回指定进程的优先级(nice值和prio值)(详见教材P328)
提示:可能参考的内核函数:set_user_nice()
添加系统调用的主要步骤为
- 修改系统调用表
- 申明系统调用服务例程原型
- 实现系统调用服务例程
修改系统调用表
以root用户在kernel-kernel-4.19目录下工作:
vim arch/x86/entry/syscalls/syscall_64.tbl
添加系统调用号337 的系统调用,系统调用名为mysetnice,服务例程入口为sys_mysetnice
#this is the PID_shiyan job
337 64 mysetnice __x64_sys_mysetnice
申明系统调用服务例程原型
执行命令
vim include/linux/syscalls.h
添加以下代码
/* this is the PID_shiyan job*/
asmlinkage long sys_mysetnice(pid_t pid,int flag,int nicevalue,void __user*prio,void __user*nice);
实现系统调用服务例程
执行命令
vim kernel/sys.c
添加
SYSCALL_DEFINE5(mysetnice,pid_t,pid,int,flag,int,nicevalue,void __user*,prio,void __user*,nice){
struct pid * kpid;
struct task_struct * task;
kpid = find_get_pid(pid);/* 返回pid */
task = pid_task(kpid, PIDTYPE_PID);/* 返回task_struct */
int n;
n = task_nice(task);/* 返回进程当前nice值 */
int p;
p = task_prio(task);/*返回进程当前prio值*/
if(flag == 1)
{
printk("Change nice: %d ,prio: %d ",n,p);
set_user_nice(task, nicevalue);/* 修改进程nice值 */
n = task_nice(task);/*重新取得进程nice值*/
p = task_prio(task);/*重新获取进程prio值 这里和参考资料不一样!!! */
printk("to nice: %d ,prio: %d\n",n,p);
copy_to_user(nice,&n,sizeof(n));/*将nice值拷贝到用户空间*/
copy_to_user(prio,&p,sizeof(p));/*将prio值拷贝到用户空间*/
return 0;
}
else if(flag == 0)
{
printk("nice : %d ,prio: %d\n",n,p);
copy_to_user(nice,&n,sizeof(n));/*将nice值拷贝到用户空间*/
copy_to_user(prio,&p,sizeof(p));/*将prio值拷贝到用户空间*/
return 0;
}
return EFAULT;
}
编译内核
设置配置文件
make menuconfig
按照原来的方式编译,可参考原来的博客。
make -j12
make -j12 modules
make modules_install
make install
测试
新建测试文件夹
mkdir PID_shiyan
进入目录
cd PID_shiyan
编辑测试文件
vim test.c
测试代码如下:
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <stdlib.h>
/*337 mystenice asmlinkage long sys_mysetnice(pid_t pid,int flag,int nicevalue,void __user *prio,void __user *nice);*/
int main()
{
pid_t pid;
char strin[100];
int nicevalue = 3100;
int flag = 2;
int p = 0;
int n = 0;
int *prio;
int *nice;
prio = &p;
nice = &n;
while(1)
{
printf("输入0查看nice和prio,输入1修改nice和prio,输入其他值退出。\n");
/*
* 获取flag;
* */
scanf("%d",&flag);
if(flag != 0 && flag != 1)
{
return 0;
}
/*
* 获取pid
* */
printf("请输入pid:\n");
scanf("%d",&pid);
/*
* 获取nice;
* */
if(flag == 1)
{
printf("请输入nice:\n");
scanf("%d",&nicevalue);
if(nicevalue < -20 || nicevalue > 19)
{
printf("nice值非法\n");
continue;
}
}
/*
* 调用添加的系统调用;
* */
syscall(337,pid,flag,nicevalue,prio,nice);
/*
* 输出最新的prio以及nice;
* */
printf("现在的nice为%d\n现在的prio为%d\n输入任意建继续\n",n,p);
getchar();
fgets(strin,100,stdin);
system("clear");
}
}
利用top查看目前进程信息
top
编译测试代码
gcc tese.c
运行
./a.out