首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 认证考试-> 软件水平考试
如何在linux系统中添加新的系统调用_linux教程
作者:网友供稿 点击:0
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 

  系统调用是应用程序和操作系统内核之间的功能接口。其主要目的是使得用户可以使用操作系统提供的有关设备管理、输入/输入系统、文件系统和进程控制、通信以及存储管理等方面的功能,而不必了解系统程序的内部结构和有关硬件细节,从而起到减轻用户负担和保护系统以及提高资源利用率的作用。


  Linux操作系统作为自由软件的代表,它优良的性能使得它的应用日益广泛,不仅得到专业人士的肯定,而且商业化的应用也是如火如荼。在Linux中,大部分的系统调用包含在Linux的libc库中,通过标准的C函数调用方法可以调用这些系统调用。那么,对Linux的发烧友来说,如何在Linux中增加新的系统调用呢?
  1 Linux系统调用机制

  在Linux系统中,系统调用是作为一种异常类型实现的。它将执行相应的机器代码指令来产生异常信号。产生中断或异常的重要效果是系统自动将用户态切换为核心态来对它进行处理。这就是说,执行系统调用异常指令时,自动地将系统切换为核心态,并安排异常处理程序的执行。Linux用来实现系统调用异常的实际指令是:


  Int $0x80

  这一指令使用中断/异常向量号128(即16进制的80)将控制权转移给内核。为达到在使用系统调用时不必用机器指令编程,在标准的C语言库中为每一系统调用提供了一段短的子程序,完成机器代码的编程工作。事实上,机器代码段非常简短。它所要做的工作只是将送给系统调用的参数加载到CPU寄存器中,接着执行int $0x80指令。然后运行系统调用,系统调用的返回值将送入CPU的一个寄存器中,标准的库子程序取得这一返回值,并将它送回用户程序。

  为使系统调用的执行成为一项简单的任务,Linux提供了一组预处理宏指令。它们可以用在程序中。这些宏指令取一定的参数,然后扩展为调用指定的系统调用的函数。

  这些宏指令具有类似下面的名称格式:


  _syscallN(parameters)

  其中N是系统调用所需的参数数目,而parameters则用一组参数代替。这些参数使宏指令完成适合于特定的系统调用的扩展。例如,为了建立调用setuid()系统调用的函数,应该使用:


  _syscall1( int, setuid, uid_t, uid )

  syscallN( )宏指令的第1个参数int说明产生的函数的返回值的类型是整型,第2个参数setuid说明产生的函数的名称。后面是系统调用所需要的每个参数。这一宏指令后面还有两个参数uid_t和uid分别用来指定参数的类型和名称。

  另外,用作系统调用的参数的数据类型有一个限制,它们的容量不能超过四个字节。这是因为执行int $0x80指令进行系统调用时,所有的参数值都存在32位的CPU寄存器中。使用CPU寄存器传递参数带来的另一个限制是可以传送给系统调用的参数的数目。这个限制是最多可以传递5个参数。所以Linux一共定义了6个不同的_syscallN()宏指令,从_syscall0()、_syscall1()直到_syscall5()。

  一旦_syscallN()宏指令用特定系统调用的相应参数进行了扩展,得到的结果是一个与系统调用同名的函数,它可以在用户程序中执行这一系统调用。
  2 添加新的系统调用
  如果用户在Linux中添加新的系统调用,应该遵循几个步骤才能添加成功,下面几个步骤详细说明了添加系统调用的相关内容。

  (1) 添加源代码

  第一个任务是编写加到内核中的源程序,即将要加到一个内核文件中去的一个函数,该函数的名称应该是新的系统调用名称前面加上sys_标志。假设新加的系统调用为mycall(int number),在/usr/src/linux/kernel/sys.c文件中添加源代码,如下所示:


  asmlinkage int sys_mycall(int number) 

  { 

  return number; 

  }

  作为一个最简单的例子,我们新加的系统调用仅仅返回一个整型值。

  (2) 连接新的系统调用

  添加新的系统调用后,下一个任务是使Linux内核的其余部分知道该程序的存在。为了从已有的内核程序中增加到新的函数的连接,需要编辑两个文件。

  在我们所用的Linux内核版本(RedHat 6.0,内核为2.2.5-15)中,第一个要修改的文件是:


  /usr/src/linux/include/asm-i386/unistd.h

  该文件中包含了系统调用清单,用来给每个系统调用分配一个唯一的号码。文件中每一行的格式如下:


  #define __NR_name NNN

  其中,name用系统调用名称代替,而NNN则是该系统调用对应的号码。应该将新的系统调用名称加到清单的最后,并给它分配号码序列中下一个可用的系统调用号。我们的系统调用如下:


  #define __NR_mycall 191

  系统调用号为191,之所以系统调用号是191,是因为Linux-2.2内核自身的系统调用号码已经用到190。

  第二个要修改的文件是:

  /usr/src/linux/arch/i386/kernel/entry.S


  该文件中有类似如下的清单:


  .long SYMBOL_NAME()

  该清单用来对sys_call_table[]数组进行初始化。该数组包含指向内核中每个系统调用的指针。这样就在数组中增加了新的内核函数的指针。我们在清单最后添加一行:


  .long SYMBOL_NAME(sys_mycall)

  (3) 重建新的Linux内核

  为使新的系统调用生效,需要重建Linux的内核。这需要以超级用户身份登录。


  #pwd 
  /usr/src/linux 
  #

  超级用户在当前工作目录(/usr/src/linux)下,才可以重建内核。


  #make config 
  #make dep 
  #make clearn 
  #make bzImage

  编译完毕后,系统生成一可用于安装的、压缩的内核映象文件:


  /usr/src/linux/arch/i386/boot/bzImage
  (4) 用新的内核启动系统
  要使用新的系统调用,需要用重建的新内核重新引导系统。为此,需要修改/etc/lilo.conf文件,在我们的系统中,该文件内容如下:


  boot=/dev/hda 
  map=/boot/map 
  install=/boot/boot.b 
  prompt 
  timeout=50 

  image=/boot/vmlinuz-2.2.5-15 
  label=linux 
  root=/dev/hdb1 
 read-only 

  other=/dev/hda1 
  label=dos 
  table=/dev/had

  首先编辑该文件,添加新的引导内核:


  image=/boot/bzImage-new 
  label=linux-new 
  root=/dev/hdb1 
  read-only

  添加完毕,该文件内容如下所示:


  boot=/dev/hda 
  map=/boot/map 
  install=/boot/boot.b 
  prompt 
  timeout=50 

  image=/boot/bzImage-new 
  label=linux-new 
  root=/dev/hdb1 
  read-only 

  image=/boot/vmlinuz-2.2.5-15 
  label=linux 
  root=/dev/hdb1 
  read-only 

  other=/dev/hda1 
  label=dos 
  table=/dev/hda

  这样,新的内核映象bzImage-new成为缺省的引导内核。为了使用新的lilo.conf配置文件,还应执行下面的命令:


  #cp /usr/src/linux/arch/i386/boot/zImage /boot/bzImage-new

  其次配置lilo:

  

  # /sbin/lilo

  现在,当重新引导系统时,在boot:提示符后面有三种选择:linux-new 、linux、dos,新内核成为缺省的引导内核。

  至此,新的Linux内核已经建立,新添加的系统调用已成为操作系统的一部分,重新启动Linux,用户就可以在应用程序中使用该系统调用了。

  (5)使用新的系统调用

  在应用程序中使用新添加的系统调用mycall。同样为实验目的,我们写了一个简单的例子xtdy.c。


  /* xtdy.c */ 

  #include 

  _syscall1(int,mycall,int,ret) 

  main() 

  { 

  printf("%d \n",mycall(100)); 

  }

  编译该程序:


  # cc -o xtdy xtdy.c

  执行:


  # xtdy

  结果:


  # 100

  注意,由于使用了系统调用,编译和执行程序时,用户都应该是超级用户身份。


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·省市联动菜单的源代码实现(access数据库版)-ASP教程,数据库相关
·【HTML】打开页面时按照指定的URL直接跳转到另一新页面-ASP教程,脚本编码
·多功能DataGrid打印类(WinForm C#)-.NET教程,C#语言
·我也来谈WEB打印。-ASP教程,打印相关
·C#中的泛型 (From dotNet SDK 2.0 Beta1)-.NET教程,C#语言
·J2EE WEB层的曙光 -- JSF-JSP教程,J2EE/EJB/服务器
·C#:获得文件版本信息及只读文件的删除-.NET教程,C#语言
·[ASP.NET]按键跳转以及按Enter以不同参数提交,及其他感应事件-.NET教程,Asp.Net开发
·谈基于.net平台windows开发中的模式窗体-.NET教程,.NET Framework
·ASP.NET 2.0 中实现 Treeview 与数据库的绑定(含代码)-.NET教程,Asp.Net开发
最新文章
·中文版windows xp系统升级sp3新鲜体验_windows xp
·十个提高windows vista系统性能的秘密_windows vista
·用搏客blog月收入200美圆_网赚技巧
·google 禁止使用在线广告宣传adsense推介_网赚技巧
·做广告联盟的站长必读规则_网赚技巧
·刘润:用c2c模式运作捐献公益组织_站长访谈
·seo资料站长丘仕达访谈:整站优化心得_站长访谈
·易被忽视的优化网站设计的五种方法_站长心得
·photoshop非主流照片:可爱红脸蛋美女_photoshop教程
·如何让网民爱上你的网站?(1)_站长心得
相关主题
  • 如何在linux下架设web mail_qmail
  • 如何在linux系统下用dma方式传输数据_linux教程
  • 如何在linux系统上进行快速磁带备份_linux教程
  • 如何在linux/freebsd下玩模拟器游戏_linux教程
  • 如何在Linux下架设Web Mail-网管专栏,邮件服务
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭