您的位置 首页 嵌入式

如安在Linux体系中增加新的体系调用

系统调用是应用程序和操作系统内核之间的功能接口。其主要目的是使得用户可以使用操作系统提供的有关设备管理、输入/输入系统、文件系统和进程

体系调用是运用程序和操作体系内核之间的功用接口。其主要意图是使得用户能够运用操作体系供给的有关设备办理、输入/输入体系、文件体系和进程操控、通讯以及存储办理等方面的功用,而不用了解体系程序的内部结构和有关硬件细节,然后起到减轻用户担负和维护体系以及进步资源利用率的作用。

Linux操作体系作为自由软件的代表,它优秀的功能使得它的运用日益广泛,不只得到专业人士的必定,并且商业化的运用也是如火如荼。在Linux中,大部分的体系调用包括在Linux的libc库中,经过规范的C函数调用办法能够调用这些体系调用。那么,对Linux的本站来说,如安在Linux中增加新的体系调用呢?

1 Linux体系调用机制

Linux体系中,体系调用是作为一种反常类型完结的。它将履行相应的机器代码指令来发生反常信号。发生中止或反常的重要作用是体系主动将用户态切换为核心态来对它进行处理。这就是说,履行体系调用反常指令时,主动地将体系切换为核心态,并组织反常处理程序的履行。Linux用来完结体系调用反常的实践指令是:

QUOTE:

Int $0x80

这一指令运用中止/反常向量号128(即16进制的80)将操控权搬运给内核。为到达在运用体系调用时不用用机器指令编程,在规范的C言语库中为每一体系调用供给了一段短的子程序,完结机器代码的编程作业。事实上,机器代码段十分简略。它所要做的作业只是将送给体系调用的参数加载到CPU寄存器中,接着履行int $0x80指令。然后运转体系调用,体系调用的回来值将送入CPU的一个寄存器中,规范的库子程序获得这一回来值,并将它送回用户程序。

为使体系调用的履行成为一项简略的使命,Linux供给了一组预处理宏指令。它们能够用在程序中。这些宏指令取必定的参数,然后扩展为调用指定的体系调用的函数。

这些宏指令具有相似下面的称号格局:

QUOTE:

_syscallN(parameters)

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

QUOTE:

_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文件中增加源代码,如下所示:

QUOTE:

asmlinkage int sys_mycall(int number)

{

return number;

}

作为一个最简略的比如,咱们新加的体系调用只是回来一个整型值。

(2) 衔接新的体系调用

增加新的体系调用后,下一个使命是使Linux内核的其余部分知道该程序的存在。为了从已有的内核程序中增加到新的函数的衔接,需求修正两个文件。

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

QUOTE:

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

该文件中包括了体系调用清单,用来给每个体系调用分配一个仅有的号码。文件中每一行的格局如下:

QUOTE:

#define __NR_name NNN

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

QUOTE:

#define __NR_mycall 191

体系调用号为191,之所以体系调用号是191,是由于Linux-2.2内核本身的体系调用号码现已用到190。

第二个要修正的文件是:

QUOTE:

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

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

QUOTE:

.long SYMBOL_NAME()

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

QUOTE:

.long SYMBOL_NAME(sys_mycall)

(3) 重建新的Linux内核

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

QUOTE:

#pwd

/usr/src/linux

#

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

QUOTE:

#make config

#make dep

#make clearn

#make bzImage

编译结束后,体系生成一可用于装置的、紧缩的内核映象文件:

QUOTE:

/usr/src/linux/arch/i386/boot/bzImage

(4) 用新的内核发动体系

要运用新的体系调用,需求用重建的新内核从头引导体系。为此,需求修正/etc/lilo.conf文件,在咱们的体系中,该文件内容如下:

QUOTE:

boot=/dev/hda

map=/boot/map

install=/boot/boot.b

prompt

timeout=50

image=/boot/vmlinuz-2.2.5-15

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/324293.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部