当前位置: 首页 > news >正文

为Linux-3.10.1内核添加系统调用

转载自 灵跃云 :原文链接   

1.    写在前面

        系统调用是操作系统提供给用户程序调用的一组“特殊”接口。通过这组“特殊”接口,用户程序可以获得操作系统内核提供的服务,如文件系统相关系统调用提供的打开文件、关闭文件或读写文件服务,时钟相关的系统调用提供的获取系统时间、设置系统时间服务等。

        从逻辑上来说,系统调用可被看成是一个内核与用户空间程序交互的接口——好比一个中间人,把用户进程的请求传达给内核,待内核把请求处理完毕后再将处理结果送回给用户进程。

        一个系统调用的典型调用过程如下图所示。

 

        系统调用的作用:

        系统服务之所以需要通过系统调用提供给用户空间,其根本原因是为了对系统进行“保护”。我们知道操作系统的运行空间分为内核空间与用户空间,它们各自运行在不同的级别中,逻辑上相互隔离,故用户进程在通常情况下不允许访问内核数据、不允许使用内核函数,它们只能在用户空间操作用户数据,调用用户空间的函数。但是很多情况下,用户进程需要获得系统服务(调用系统程序),这时就必须利用系统提供给用户的“特殊”接口——系统调用,其特殊性在于规定了用户进程进入内核的具体位置,即用户访问内核的路径是事先规定好的,只能从规定位置进入内核,而不准许肆意跳入内核。有了上述陷入内核的统一访问路径限制,才能有效保证系统内核的安全。我们可以形象地描述上述机制:作为一个游客,你可以买票要求进入野生动物园,但你必须老老实实的坐在观光车上,按照规定的路线观光游览。当然,不准下车,因为那样太危险,不是让你丢掉小命,就是让你吓坏了野生动物。

        在前述文章“Linux-3.10.1内核的编译和安装”(详见http://www.lingyuecloud.com/Index/details/id/58.html)中,我们知道利用Linux内核的开源特性,可以对Linux系统进行定制化开发、编译和安装。例如,通过修改Linux内核源码,我们定制化开发了一个新功能,那么如何在应用程序中使用这个新功能呢?为此,我们还需要为“应用程序”与“内核中新增的新功能”建立桥梁——即一个能够连接两者的系统调用。

        假设我们已经获得了Linux-3.10.1的源码包linux-3.10.1.tar.bz2,解压该源码包后得到linux-3.10.1文件夹,并切换到该文件夹下(如何获取包linux-3.10.1.tar.bz2?如何解压?请详见http://www.lingyuecloud.com/Index/details/id/58.html——“Linux-3.10.1内核的编译和安装”)。接下来,灵跃桌面云将以Linux-3.10.1内核为例,详细描述为内核添加一个新的系统调用的过程,下述所有操作都在linux-3.10.1目录下进行。

 

2.    环境说明

 

注:在下述描述中,涉及在服务器Ubuntu 12.04操作系统环境上的所有操作,均以root身份登录并执行。

 

3.    为Linux-3.10.1内核添加一个系统调用

 

3.1  系统调用号

 

        Linux系统调用号的作用是在系统调用过程中,将其数值作为下标的在系统调用表中进行索引,从而得到处理该系统调用的函数的地址。

        每个系统调用都有一个唯一的系统调用号,应用程序可以通过系统调用号调用指定的系统调用。

3.2  系统调用表

 

        与Windows系统中的SSDT(System Services Descriptor Table)的作用一样,Linux系统调用表保留着处理各个系统调用的函数的入口地址;其实际上是一个二维的指针数组[X][Y],X代表系统调用号,Y代表系统调用函数的入口地址。

3.3  添加系统调用lingyuecloudsyscall

 

        1)        添加自定义的系统调用源代码

        在“linux-3.10.1/kernel”目录下的sys.c文件中添加自定义的系统调用lingyuecloudsyscall的实现函数。

        打开sys.c文件,添加以下示例代码:

        #vim kernel/sys.c

asmlinkage long sys_lingyuecloudsyscall (int number){
printk("hello lingyuecloud!Call number is %d\n",number);
return number;

}

 

        2)        修改系统调用表

        系统调用表文件在“linux-3.10.1/arch/x86/syscalls”目录下的syscall_64.tbl文件中。

        打开syscall_64.tbl,添加新的系统调用指针,如下所示:

        #vim arch/x86/syscalls/syscall_64.tbl

314   64     lingyuecloudsyscall      sys_ lingyuecloudsyscall;

        如下图所示:

 

        其中,314为lingyuecloudsyscall的系统调用号,应用程序可通过此调用号调用lingyuecloudsyscall系统调用,也可以使用其它的系统调用号,但注意不能与已有的系统调用号重复。64表示适配于64位系统内核环境,相关描述详情可查阅https://en.wikipedia.org/wiki/X32_ABI。

        3)        添加系统调用lingyuecloudsyscall的函数声明

        在“linux-3.10.1/include/linux/”目录下的syscalls.h文件中添加函数声明。

        打开syscalls.h,在倒数第二行添加下面内容:

        #vim include/linux/syscalls.h

asmlinkage long sys_lingyuecloudsyscall(int num);

        如下图所示:

 

        4)        重新编译

        5)        内核

        编译过程详见http://www.lingyuecloud.com/Index/details/id/58.html——“Linux-3.10.1内核的编译和安装”。

        6)        测试系统调用

        编写测试程序lingyuecloud_test.c:

#include<stdio.h>

#include<linux/unistd.h>

#include<sys/syscall.h>

int main()

{

      long a;

      a = syscall(314,100);  //调用第314号系统调用,即sys_lingyuecloudcall();

      printf("The number is%d\n",a);

      return 0;

}

 

        编译测试程序:

        #gcc -o lingyuecloud lingyuecloud_test.c

        测试结果如下图所示:

 

        如果能够看到上述结果,表示你的第一个自定义系统调用已经添加成功。

 

转载于:https://www.cnblogs.com/easyFancy/p/8427794.html

相关文章:

  • enterprise library 5 unity使用方法
  • 设计的MOS管三极管简单开关电路驱动能力不够2
  • 大数据||HDFS||NameNode启动过程详解
  • [短彩信]C#短彩信模块开发设计(2)——配置
  • Java里面CompletableFuture详解
  • 10个最受欢迎的Java类
  • 国内 CDN 产品发展历史和现状整理
  • [译] 用 Java 创造你的第一个区块链-第一部分
  • vi
  • 文件上传下载
  • Flex与后台交互 鼠标忙时状态
  • 18.Azure备份(MARS)代理(下)
  • 5个能够有效帮助你快速创建超棒CSS3动画效果的类库
  • 用js实现页面跳转的几种方式
  • Bzoj1758: [Wc2010]重建计划
  • Electron入门介绍
  • java第三方包学习之lombok
  • laravel with 查询列表限制条数
  • LeetCode18.四数之和 JavaScript
  • PaddlePaddle-GitHub的正确打开姿势
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • 阿里云应用高可用服务公测发布
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 网络应用优化——时延与带宽
  • 微信小程序实战练习(仿五洲到家微信版)
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • ​VRRP 虚拟路由冗余协议(华为)
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • .Net Memory Profiler的使用举例
  • .Net 代码性能 - (1)
  • []我的函数库
  • [2544]最短路 (两种算法)(HDU)
  • [c]扫雷
  • [CISCN 2019华东南]Web11
  • [Java基础] Java中List.remove报错UnsupportedOperationException
  • [js]- 两个对象的合并(Object.assign)
  • [JS7] 显示从0到99的100个数字
  • [linux]资料收纳
  • [LuoguP1141]01迷宫
  • [OLEDB] 目前还找找不到处理下面错误的办法
  • [Operating System] {ud923} P4L4: Datacenter Technologies
  • [RoarCTF 2019]PHPShe
  • [SPOJ]COT2
  • [Spring]一文明白IOC容器和思想
  • [UIM]论文解读:subword Regularization: Multiple Subword Candidates
  • [编程题]抄送列表 - 牛客网题解
  • [大牛翻译系列]Hadoop(22)附录D.2 复制连接框架
  • [豆趣]世界上仅存5只恐龙