实验一:Linux内核编译及添加系统调用
实验一:Linux内核编译及添加系统调用一、实验目的理解Linux系统处理系统调用的流程增加一个系统调用二、实验内容nice,可以理解为谦让度,CPU在选择进程时根据优先级prio选择,当nice值越高,可理解为这个进程越是谦让,即优先级越低添加一个系统调用,实现对指定进程的nice值的修改或读取功能,并返回系最新的nice值,即优先级prio。建议调用原型为:In...
实验一:Linux内核编译及添加系统调用
一、实验目的
- 理解Linux系统处理系统调用的流程
- 增加一个系统调用
二、实验内容
- 
  nice,可以理解为谦让度,CPU在选择进程时根据优先级prio选择,当nice值越高,可理解为这个进程越是谦让,即优先级越低 
- 
  添加一个系统调用,实现对指定进程的nice值的修改或读取功能,并返回系最新的nice值,即优先级prio。 建议调用原型为:  Int mysetnice(pid_t pid, int flag, int nicevalue,void_userprio,void_usernice)  参数含义:  pid:进程ID  flag:若值为0,表示读取nice值;若值为1表示修改nice值。  prio,nice:指向进程当前优先级及nice值。  返回值:系统调用成功时返回0,失败时返回错误码EFAULT。 
- 
  写一个简单的应用程序测试系统调用 
- 
  深入阅读相关函数源码 
三、流程图
四、具体实现
- 
  安装虚拟机及ubuntu按指导来问题不大,在可行前提下,分配处理器选择4核或以上 大小分配60G左右! https://jingyan.baidu.com/article/f96699bb147a73894e3c1b2e.html 
- 
  开启系统,打开terminal,进入管理员模式 打开termintal: ctrl+alt+t 管理员模式: 输入 sudo su 输入用户密码进入管理员模式 
- 
  下载解压内核 下载内核: 输入 wget http://mirrors.ustc.edu.cn/kernel.org/linux/kernel/v4.x/linux-4.4.196.tar.xz 解压内核: 输入 tar -xvJf linux-4.4.196.tar.xz 
- 
  系统调用 装各种包 输入 sudo apt-get install vim libncurses5-dev make openssl libssl-dev bison flex ctags 

添加系统调用号 进入内核:cd linux-4.4.196 # 之后的操作都是在这个目录下
 编辑调用表:vim arch/x86/entry/syscalls/syscall_64.tbl
 输入G (跳末行)上行到300多行 ,输入i (进入编辑模式)
 输入如图
 按ESC键 退出编辑模式 输入 :wq 保存并退出
申明系统调用 vim include/linux/syscalls.h
 输入 G i 添加如下
asmlinkage long sys_mysetnice(pid_t pid,int flag,int nicevalue,void __user * prio,void __user * nice);
 按ESC键 退出编辑模式 输入 :wq 保存并退出
实现调用 vim kernel/sys.c
 输入 G i 添加如下
SYSCALL_DEFINE5 (mysetnice,pid_t,pid,int,flag,int,nicevalue,void __user*,prio,void __user*,nice){
    //SYSCALL_DEFINEN中N表示系统调用所需要的参数个数,我们的是5个
     struct task_struct *p;//进程结构体指针
     struct pid *id;//pid结构体
     int m,n;
     id=find_get_pid(pid);//通过传入的pid_t pid得到id结构体 
     p=pid_task(id,PIDTYPE_PID);//通过id得到指定进程,PIDTYPE_PID指的是进程类型的pid 
     m=task_nice(p);     //通过p得到nice值 
     n=task_prio(p);     //通过p得到prio值(优先级) 
     if(flag==0){//读取 
        copy_to_user(nice,(void*)&m,sizeof(m));//将m的地址强转为void *类型 
        copy_to_user(prio,(void*)&n,sizeof(n));
        return 0;
     }
     else if(flag==1){//修改 
        printk("nice value before modified:%d\n",m); 
        set_user_nice(p,nicevalue);//修改nice的值
        return 0;
     } 
     printk("syscall failed!");
     return EFAULT; 
}
 按ESC键 退出编辑模式 输入 :wq 保存并退出
- 
  配置编译内核 输入 make mrproper 输入 make clean 输入 make menuconfig (terminal窗口最大化) 选择Save 回车确定 回车确定 选择Exit 

输入 make -j4
 (-j4表示4线程编译,耗费较长,无视warning,跳出error可以ctrl+c结束了,出错了就没必要再编译了,看看是否漏掉步骤,根据跳出的error解决)
- 
  安装内核重启系统 输入 make modules 输入 make modules_install 输入 make install 输入 update-grub2 输入 reboot 重启后 ctrl+alt+t 打开terminal 输入 sudo su 进入管理员模式 输入 uname -a 如果显示的是下载的内核 这里是4.4.196 表明编译成功 
- 
  编写函数测试用 输入 vim exp_1_test.c 新建C文件测试调用 输入i (进入编辑模式) 编写代码如下 #include<stdio.h> #include<unistd.h> #include<sys/syscall.h> #define __NR_mysyscall 326 int main(){ int nice,prio; pid_t id; id=getpid(); printf("----------------read-----------------\n\n"); syscall(__NR_mysyscall,id,0,NULL,&prio,&nice); printf("before modified:pid:%d,prio:%d,nice:%d\r\n",id,prio,nice); printf("-----------------set-------------------\n\n"); printf("syscall(__NR_mysyscall,id,1,-8,&prio,&nice);\n"); syscall(__NR_mysyscall,id,1,-8,&prio,&nice); printf("------------------read-----------------\n\n"); syscall(__NR_mysyscall,id,0,NULL,&prio,&nice); printf("modified:pid:%d,prio:%d,nice:%d\r\n",id,prio,nice); return 0; } 按ESC键 退出编辑模式 输入 :wq 保存并退出 输入 gcc exp_1_test.c 编译C文件 输入 ./a.out 查看结果 
- 
  相关内核源码阅读 输入 cd linux-4.4.196 进入目录 输入 sudo ctags -R * (一些准备工作) 输入 vim kernel/sys.c 就是之前实现调用的 这里以查看set_user_nice函数及nice定义为例,可以此类推 

这里光标移动到如图 set_user_nice 函数
输入 ctrl + ] 进入函数 (退出则是c trl +T)
显示如图

光标移动到 MIN_NICE 输入 ctrl + ] 进入
显示如图

更多推荐
 
 



所有评论(0)