最近在学习 操作系统
看到每个进程都有 pid 等很多属性。 那我们可以做到修改或者添加进程的某个属性, 进而影响操作系统的运行吗?
本文 以 Android 系统为例,尝试为进程添加级别属性。
第一步 是要找到进程属性的定义的地方。在/include/linux/sched.h内的 task_struct 结构体内定义了许多属性。那首先,笔者在此处添加了p_level属性。
第二步是 在相同文件夹下,可以观测到有一个syscall.h 文件。这个头文件内定义了系统调用的函数列表。我们定义的P_level显然需要基本的 set 和 get 功能。此时我们需要将这两个函数添加进入syscall的头文件内。
第三步 对于系统调用而言。一般会有一个tbl的表格,表明了所有的系统调用的代号。我们自己生成的调用函数,也要保存在内才行。对于64位的系统,一般在 /arch/x86/entry/syscalls/syscall_64.tbl 内会定义。
如果有需要的话,比如设定默认的属性时。还需要修改kernel内的fork.c文件。此我们就将它默认值设为0了
此时我们基本完成了系统设置的内容。我们在 syscall 表内添加了我们自定义的call,然后在syscall的头文件内定义了函数名。在进程的属性结构体内添加了自定义的属性。那下面,我们要做的就是实现我们定义的函数了。
# include <linux/kernel.h>
# include <linux/sched.h>
# include <linux/pid.h>
asmlinkage int sys_set_P_level(int pid, int level){
struct task_struct *task;
//若小于0, 则返回err
if (level < 0) return -1;
/* 普通用户时 */
if (current_euid().val !=0){
//当前进程?
if (pid == current->pid){
//当前进程要比设置的level高
int temp = current->P_level>=level ? level : -1;
if(temp != -1) current->P_level = level;
return temp;
}
else{
for_each_process(task){
//寻找进程,而且要修改的级别小于当前进程时方可修改
if(task->pid == pid && current->P_level > task->P_level){
int temp = current->P_level>=level ? level : -1;
if(temp != -1) task->P_level = level;
return temp;
}
}
return -1;
}
}
/* 当用户是root user时,自带最高级别属性*/
else{
for_each_process(task){ //寻找对应进程
if(task->pid == pid ) {
task->P_level = level;
return task->P_level;
}
}
//未找到则返回err
return -1;
}
}
asmlinkage int sys_get_P_level (int pid){
/* 对于get函数 就很简单
遍历进程池
若找到则return P_level, otherwise return -1;
*/
}