实验一: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

在这里插入图片描述

添加系统调用号 进入内核: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 + ] 进入

显示如图

在这里插入图片描述

  • 11
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实验linux 内核编译添加系统调用 设计目的 Linux 是开源操作系统,用户可以根据自身系统需要裁剪、修改内核,定制出功能更加 合适、运行效率更高的系统,因此,编译 linux 内核是进行内核开发的必要基本功。 在系统中根据需要添加新的系统调用是修改内核的一种常用手段,通过本次实验,读 者应理解 linux 系统处理系统调用的流程以及增加系统调用的方法。 内容要求 (1) 添加一个系统调用实现指定进程的 nice 的修改或读取功能,并返回进程最 新的 nice 及优先级 prio。建议调用原型为: int mysetnice(pid_t pid, int flag, int nicevalue, void __user * prio, void __user * nice); 参数含义: pid:进程 ID。 flag:若为 0,表示读取 nice ;若为 1,表示修改 nice 。 Prio、nice:进程当前优先级及 nice 。 返回:系统调用成功时返回 0,失败时返回错误码 EFAULT。 (2) 写一个简单的应用程序测试(1)中添加系统调用。 (3) 若程序中调用linux内核函数,要求深入阅读相关函数源码。 实验linux 内核模块编程 设计目的 Linux 提供的模块机制能动态扩充 linux 功能而无需重新编译内核,已经广泛应用在 linux 内核的许多功能的实现中。在本实验中将学习模块的基本概念、原理及实现技术,然后利 用内核模块编程访问进程的基本信息,从而加深对进程概念的理解、对模块编程技术的掌 握。 内容要求 (1) 设计一个模块,要求列出系统中所有内核线程的程序名、PID 号、进程状态及 进程优先级。 (2) 设计一个带参数的模块,其参数为某个进程的 PID 号,该模块的功能是列出该 进程的家族信息,包括父进程、兄弟进程和子进程的程序名、PID 号。 (3) 请根据自身情况,进一步阅读分析程序中用到的相关内核函数的源码实现实验linux 进程管理 设计目的 (1) 熟悉 linux 的命令接口。 (2) 通过对 linux 进程控制的相关系统调用的编程应用,进一步加深对进程概念的理解, 明确进程和程序的联系和区别,理解进程并发执行的具体含义。 (3) 通过 Linux 管道通信机制、消息队列通信机制、共享内存通信机制的使用,加深 对不同类型的进程通信方式的理解。 (4) 通过对 linux 的 Posix 信号量的应用,加深对信号量同步机制的理解。 (5)请根据自身情况,进一步阅读分析相关系统调用内核源码实现。 设计内容 (1)熟悉 linux 常用命令:pwd,useradd,passwd, who, ps, pstree, kill, top, ls, cd, mkdir, rmdir, cp, rm, mv, cat, more, grep 等。 (2) 实现一个模拟的 shell: 编写三个不同的程序 cmd1.c,cmd2.c,cmd3.c,每个程序的功能自定,分别编译成可执 行文件 cmd1,cmd2,cmd3。然后再编写一个程序,模拟 shell 程序的功能,能根据用户输 入的字符串(表示相应的命令名),去为相应的命令创建子进程并让它去执行相应的程序,而父进程则等待子进程结束,然后再等待接收下一条命令。如果接收到的命令为 exit,则父 进程结束;如果接收到的命令是无效命令,则显示“Command not found”,继续等待。 (3) 实现一个管道通信程序: 由父进程创建一个管道,然后再创建 3 个子进程,并由这三个子进程利用管道与父进程 之间进行通信:子进程发送信息,父进程等三个子进程全部发完消息后再接收信息。通信的 具体内容可根据自己的需要随意设计,要求能试验阻塞型读写过程中的各种情况,测试管道 的默认大小,并且要求利用 Posix 信号量机制实现进程间对管道的互斥访问。运行程序,观 察各种情况下,进程实际读写的字节数以及进程阻塞唤醒的情况。 (4) 利用 linux 的消息队列通信机制实现两个线程间的通信: 编写程序创建两个线程:sender 线程和 receive 线程,其中 sender 线程运行函数 sender(), 它创建一个消息队列,然后,循环等待用户通过终端输入一串字符,将这串字符通过消息队 列发送给 receiver 线程,直到用户输入“exit”为止;最后,它向 receiver 线程发送消息“end”, 并且等待 receiver 的应答,等到应答消息后,将接收到的应答信息显示在终端屏幕上,删除 相关消息队列,结束程序的运行。Receiver 线程运行 rece

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值