实验一:Linux内核编译及添加系统调用

实验一: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
下载解压内核
增加系统调用
申明系统调用
编写函数实现系统调用
配置内核
编译内核及模块
安装内核重启系统
编写函数测试系统调用
阅读相关函数源码

四、具体实现

  • 安装虚拟机及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

实验一:Linux内核编译及添加系统调用_第1张图片

添加系统调用号 进入内核:cd linux-4.4.196 # 之后的操作都是在这个目录下

​ 编辑调用表:vim arch/x86/entry/syscalls/syscall_64.tbl

​ 输入G (跳末行)上行到300多行 ,输入i (进入编辑模式)

​ 输入如图
实验一:Linux内核编译及添加系统调用_第2张图片

​ 按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

实验一:Linux内核编译及添加系统调用_第3张图片

输入 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
    #include
    #include
    #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定义为例,可以此类推

实验一:Linux内核编译及添加系统调用_第4张图片

这里光标移动到如图 set_user_nice 函数

输入 ctrl + ] 进入函数 (退出则是c trl +T)

显示如图

实验一:Linux内核编译及添加系统调用_第5张图片

光标移动到 MIN_NICE 输入 ctrl + ] 进入

显示如图

实验一:Linux内核编译及添加系统调用_第6张图片

你可能感兴趣的:(实验一:Linux内核编译及添加系统调用)