Linux添加系统调用

简介

设计并实现一个新的内核函数 mycall( ),此函数通过一个引用参数的调用返回当前系统时间,功能上基本与 gettimeofday( )相同。操作系统的实验作业,给的参考资料还在用2.4.x的内核,自己查了一些资料,做了4.15.3内核的添加系统调用,供大家参考。

前提准备

在win10操作系统下使用VMware安装Ubuntu16.04.5 64位。如果你使用的Ubuntu版本过于老旧,可能无法成功。关于如何在虚拟上安装Ubuntu,可以参阅我的另一篇文章写给萌新的教程:win10下使用VMware安装Ubuntu16.04.5 Gnome

注:虚拟机硬盘空间应分配一定的大小,至少30G吧。下图为我编译安装内核后的空间占用情况。


空间使用

下载linux内核4.15.3。可以去tuna镜像站下载,点击此处下载。或者在终端下下载

wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v4.x/linux-4.15.3.tar.xz
# ipv6可用时
wget -6 https://mirrors.tuna.tsinghua.edu.cn/kernel/v4.x/linux-4.15.3.tar.xz

实验步骤

1.解压文件

tar xvJf linux-4.15.3.tar.xz

2.分配系统调用号,修改系统调用表

cd linux-4.15.3/arch/x86/entry/syscalls/
ls
ls

修改syscall_64.tbl文件为其在342行添加一行内容,最前面的333位系统调用号,之前的系统调用号用到了332,所以这里是333

333   64    mycall    sys_mycll
修改syscall_64.tbl后

3.申明系统调用服务例程原型
在linux-4.15.3/include/linux目录下修改syscalls.h文件
在最后的#endif之前添加以下内容

asmlinkage long sys_mycall(struct timeval *tv);

纠错:图片中943行前少了一个a,被我不小心删掉了。


添加原型

4.实现系统调用服务
在linux-4.15.3/kernel/sys.c中添加相应的服务

SYSCALL_DEFINE1(mycall, struct timeval *, tv) {
    struct timeval ktv;
    do_gettimeofday(&ktv);
    if(copy_to_user(tv, &ktv, sizeof(ktv) ) ) {
        return -EFAULT;
    }
    return 0;
}

5.安装相关依赖

sudo apt install libncurses5-dev libssl-dev build-essential openssl  zlibc minizip libidn11-dev libidn11 libelf-dev

6.开始编译
打开终端进入linux-4.15目录下,执行以下命令

# 清楚清除残留的文件,如果编译失败,需要重新编译则需要清除,第一次编译可以不执行
sudo make mrproper 
sudo make clean 

选择配置,注此条命令要求终端具有一定的宽度,否则会失败

sudo make menuconfig
失败示例

成功的话,如下所示,左右移动选择Save回车确认即可


成功

ok确认即可。


2018-12-05_192247.png

之后选择Exit退出即可。
  1. 编译安装
# 编译,这里根据你为虚拟机分配的物理核决定 -jn,相同即可
sudo make –j8 
或者 sudo make
# 安装内核模块
sudo make modules_install
# 安装内核
sudo make install

8.测试新的系统调用
重启系统,编写测试程序test.c

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/time.h>
#include <sys/syscall.h>
#include <stdio.h>
#define __NR_mycall 333 //系统调用号

int main() {

    struct timeval gettime;
    struct timeval mycalltime;
    gettimeofday(&gettime, NULL);
    syscall(__NR_mycall, &mycalltime);
    printf("gettimeofday:%ld %ld \n", gettime.tv_sec, gettime.tv_usec);
    printf("mycall : %ld %ld \n", mycalltime.tv_sec, mycalltime.tv_usec); 
    return 0;
}

编译并运行

gcc test.c
./a.out
测试
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 0. 环境准备 Ubuntu16.04 Desktop x86_64Linux Kernel 4.4.0(tar....
    SilentDawn阅读 3,998评论 0 1
  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 9,506评论 0 5
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 14,405评论 2 33
  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 100,243评论 9 468
  • 生活在一个五六线的小县城,对送礼一定不会陌生。这是一个基本的社会规则。 几年前学驾照,记得那时候,考驾照很火,因为...
    诸葛妙计阅读 3,034评论 0 3

友情链接更多精彩内容