操作系统实验一
一、前言
记录杭电操作系统实验一:编译内核&增加nice系统调用.本文仅严格记录本人成功的实验流程,方便日后修改.
二、实验准备
三、主要参考资料
四、 实验过程
4.1编译内核
编译内核严格按照Ubuntu 18.04环境下编译Linux内核以及添加系统调用这篇参考资料进行,直至重启系统后使用命令
uname -a
显示最新内核耗时:晚上睡觉前开始
sudo make
一觉醒来就搞定了部分截图:
4.2增加系统调用
主要参考资料:添加一个系统调用,实现对指定进程的nice值的修改或读取功能,并返回系统最新的nice值即优先级prio
以下命令在/usr/src/linux-5.3.6中执行
4.2.1 题目描述
- 添加一个系统调用,实现对指定进程的nice值的修改或读取功能,并返回系统最新的nice值即优先级prio。
建议调用原型为:int mysetnice(pid_t pid, int flag, int nicevalue,void_user*prio,void_user*nice)
参数含义:
pid
:进程IDflag
:若值为0,表示读取nice值;若值为1表示修改nice值。prio
,nice:指向进程当前优先级及nice值。返回值
:系统调用成功时返回0,失败时返回错误码EFAULT。
- 写一个简单的应用程序测试
4.2.2 步骤描述
- 修改系统调用表
- 申明系统调用服务例程原型
- 实现系统调用服务例程
- 重新编译
- 编写测试函数进行测试
4.2.3 具体操作
修改系统调用表
sudo vim arch/x86/entry/syscalls/syscall_64.tbl
一定要使用__x64 否则报如下错误
申明系统调用服务例程原型
sudo vim include/linux/syscalls.h
添加以下代码
asmlinkage long sys_mysetnice(pid_t pid,int flag,int nicevalue,void __user*prio,void __user*nice);
实现系统调用服务例程
vim kernel/sys.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26SYSCALL_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)
{
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;
}编译
使用ccache加快编译
参考文档:ubuntu 使用ccache加快linux内核编译速度 注意将
usr
改为自己的用户名,6G改为10G1
2
3
4
5
6$sudo make clean
#仍采用原内核配置文件
$sudo make localmodconfig #使用localmodconfig加速编译
$sudo make -j8 #使用多线程编译
$sudo make modules_install
$sudo make install整个过程大概只用了30分钟,编译完内核后一定要重启!!!!!
编写测试函数
vim test.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int main(){
pid_t pid;
int nicevalue;
int flag;
int p = 0;
int n = 0;
int *prio;
int *nice;
prio = &p;
nice = &n;
/*
* 获取pid
* */
printf("请输入pid:\n");
scanf("%d",&pid);
/*
* 获取nice;
* */
printf("pid赋值成功\n请输入nice:\n");
scanf("%d",&nicevalue);
/*
* 获取flag;
* */
printf("nice赋值成功\n请输入flag:\n");
scanf("%d",&flag);
/*
* 调用添加的系统调用;
* */
syscall(334,pid,flag,nicevalue,prio,nice);
/*
* 输出最新的prio以及nice;
* */
printf("现在的nice为%d\n,prio为%d\n",n,p);
return 0;
}编译运行
1
2
3top
gcc test.c
$./a.out