linux系统调用过程理解

用户可以通过两种方式使用系统调用:

第一种方式是通过C库函数,包括系统调用在C库中的封装函数和其他普通函数。(如write,read,kill,mkdir等函数)

第二种方式是使用_syscall宏。2.6.18版本之前的内核,在include/asm-i386/unistd.h文件中定义有7个_syscall宏,分别是:

_syscall0(type,name)  
_syscall1(type,name,type1,arg1)  
_syscall2(type,name,type1,arg1,type2,arg2)  
_syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)  
_syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  
_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5)  
_syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6)

这里介绍第二种方式(其实第一种方式本质上就是第二种方式,只不过C库函数对其进行了封装)

先举个例子

如下图,testsyscall调用后,根据宏定义_syscall0会将返回值int和函数名传入。后面会讲到syscall

以下就是如何产生int80中断

根据汇编中传入的宏定义找到对应的系统调用号,这个时候已经由汇编产生int80软中断,切换到内核态了。然后再通过调用号在system_call_table中根据偏移量找到对应的内核态中该系统调用函数,如open就找到了sys_open

 

 

参数传递:

函数需要传入几个参数,就调用对应个数的syscalln(),其中n的范围从0到6。代表需要传递给系统调用的参数个数,这是由于该宏必须了解到底有多少参数按照什么次序压入寄存器

 

对于每个宏来说,都有2+ n个参数。

第一个参数对应着系统调用的返回值类型。

第二个参数是系统调用的名称。再以后是按照系统调用参数的顺序排列的每个参数的类型和名称。

 

(我的理解:第0个,第1个参数是固定的,后面2-6的值就是参数。)

 

 

如上图所示,type是返回类型,name就是系统调用名称。(就是说open函数调用后在汇编里会组合为_NR_open)

 


发布了28 篇原创文章 · 获赞 9 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章