欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    Linux系统调用-详细全过程.ppt

    • 资源ID:33120183       资源大小:422KB        全文页数:43页
    • 资源格式: PPT        下载积分:20金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要20金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    Linux系统调用-详细全过程.ppt

    LinuxLinux系统调用系统调用_ _详细全过程详细全过程u系统调用系统调用( (SYSTEM CALL)SYSTEM CALL) nOSOS内核中都有一组实现系统功能的过程,内核中都有一组实现系统功能的过程,系统调用就是对上述过程的调用。编程人系统调用就是对上述过程的调用。编程人员利用系统调用,向员利用系统调用,向OSOS提出服务请求,由提出服务请求,由OSOS代为完成。代为完成。u一般情况下,进程是不能够存取系统内核一般情况下,进程是不能够存取系统内核的。它不能存取内核使用的内存段,也不能的。它不能存取内核使用的内存段,也不能调用内核函数,调用内核函数,CPUCPU的硬件结构保证了这一的硬件结构保证了这一点。只有系统调用是一个例外。点。只有系统调用是一个例外。 Linux系统调用系统调用- -功能功能u系统调用是用户态进入内核态的唯一入口系统调用是用户态进入内核态的唯一入口:一夫一夫当关,万夫莫开。常用系统调用:当关,万夫莫开。常用系统调用:n控制硬件控制硬件: :如如write/readwrite/read调用。调用。n设置系统状态或读取内核数据设置系统状态或读取内核数据getpid()getpid()、getpriority()getpriority()、setpriority()setpriority()、sethostname()sethostname()n进程管理进程管理: :如如 fork()fork()、clone()clone()、execve()execve()、exit()exit()等等u优点优点 n编程容易,从硬件设备的低级编程中解脱出来编程容易,从硬件设备的低级编程中解脱出来n提高了系统的安全性,可以先检查请求的正确性提高了系统的安全性,可以先检查请求的正确性5.1 Linux系统调用系统调用- -功能功能陷入指令系统子程序sub 0A0sub 1A1sub nAnsub iAi.陷入处理机构1)保护处理机现场2)取系统调用功能号并寻找子程序入口3)恢复处理机现场并返回入口地址表A0A2Ai.An.系统调用.用户程序5.2 Int 5.2 Int 0 x800 x80指令指令uLinuxLinux中实现系统调用利用了中实现系统调用利用了i386i386体系结体系结构中的软件中断。即调用了构中的软件中断。即调用了int $0 x80汇编指令。汇编指令。u这条汇编指令将产生向量为这条汇编指令将产生向量为128128的编程异的编程异常,常,CPUCPU便被切换到内核态执行内核函数,便被切换到内核态执行内核函数,转到了系统调用处理程序的入口:转到了系统调用处理程序的入口:system_call()system_call()。uint $0 x80int $0 x80指令将用户态的执行模式转变为内指令将用户态的执行模式转变为内核态,并将控制权交给系统调用过程的起点核态,并将控制权交给系统调用过程的起点system_call()system_call()处理函数。处理函数。system_call()system_call()函数函数usystem_cal()system_cal()检查系统调用号,该号码告诉内核检查系统调用号,该号码告诉内核进程请求哪种服务。进程请求哪种服务。u内核进程查看系统调用表内核进程查看系统调用表(sys_call_table)(sys_call_table)找到找到所调用的内核函数入口地址。所调用的内核函数入口地址。u接着调用相应的函数,在返回后做一些系统检查,接着调用相应的函数,在返回后做一些系统检查,最后返回到进程。最后返回到进程。系统调用和普通函数调用系统调用和普通函数调用uAPIAPI是用于某种特定目的的函数,供应用程序调用,是用于某种特定目的的函数,供应用程序调用,而系统调用供应用程序直接进入系统内核。而系统调用供应用程序直接进入系统内核。uLinuxLinux内核提供了一些内核提供了一些C C语言函数库,这些库对系统语言函数库,这些库对系统调用进行了一些包装和扩展,因为这些库函数与系调用进行了一些包装和扩展,因为这些库函数与系统调用的关系非常紧密,所以习惯上把这些函数也统调用的关系非常紧密,所以习惯上把这些函数也称为系统调用。称为系统调用。u有的有的APIAPI函数在用户空间就可以完成工作,如一些函数在用户空间就可以完成工作,如一些用于数学计算的函数,因此不需要使用系统调用。用于数学计算的函数,因此不需要使用系统调用。u有的有的APIAPI函数可能会进行多次系统调用。函数可能会进行多次系统调用。u不同的不同的API API 函数也可能会有相同的系统调用。比如函数也可能会有相同的系统调用。比如malloc()malloc(),calloc()calloc(),free()free()等函数都使用相同的等函数都使用相同的方法分配和释放内存。方法分配和释放内存。系统命令、内核函数系统命令、内核函数u系统调用与系统命令系统调用与系统命令n系统命令相对系统命令相对APIAPI来说,更高一层。每个系统命令来说,更高一层。每个系统命令都是一个执行程序,如都是一个执行程序,如lsls命令等。这些命令的实现命令等。这些命令的实现调用了系统调用。调用了系统调用。u系统调用与内核函数系统调用与内核函数n系统调用是用户进入内核的接口层,它本身并非内系统调用是用户进入内核的接口层,它本身并非内核函数,但是它由内核函数实现。核函数,但是它由内核函数实现。n进入内核后,不同的系统调用会找到各自对应的内进入内核后,不同的系统调用会找到各自对应的内核函数,这些内核函数被称为系统调用的核函数,这些内核函数被称为系统调用的“服务例服务例程程”。如系统调用。如系统调用getpidgetpid实际调用的服务例程为实际调用的服务例程为sys_getpid()sys_getpid(),或者说系统调用,或者说系统调用getpid()getpid()是服务例是服务例程程sys_getpid()sys_getpid()的封装例程。的封装例程。封装例程封装例程(wrapper routine)(wrapper routine)u由于陷入指令是一条特殊指令,依赖操作系统实现由于陷入指令是一条特殊指令,依赖操作系统实现的平台,如在的平台,如在i386i386体系结构中,这条指令是体系结构中,这条指令是int int $0 x80($0 x80(陷入指令陷入指令) ),不是用户在编程时应该使用的,不是用户在编程时应该使用的语句,因为这将使得用户程序难于移植。语句,因为这将使得用户程序难于移植。u在标准在标准C C库函数库函数中,为每个系统调用设置了一个中,为每个系统调用设置了一个封封装例程装例程,当一个用户程序执行了一个系统调用时,当一个用户程序执行了一个系统调用时,就会调用到就会调用到C C函数库中的相对应的封装例程。函数库中的相对应的封装例程。系统调用过程系统调用过程系统调用过程系统调用过程xyz()system_call: sys_xyz() ret_from_sys_call:iretxyz()int 0 x80sys_xyz()在应用程序在应用程序 在标准库在标准库 系统调用系统调用 系统调用系统调用调用中的调用中的 中的封装例程中的封装例程 处理程序处理程序 服务例程服务例程系统调用系统调用用户态用户态 内核态内核态system_call()system_call()函数(见教材函数(见教材P234P234页)页)u首先将系统调用号首先将系统调用号(eax)(eax)和可以用到的所有和可以用到的所有CPUCPU寄存寄存器保存到相应的堆栈中(由器保存到相应的堆栈中(由SAVE_ALLSAVE_ALL完成);完成);u对用户态进程传递过来的系统调用号进行有效性检对用户态进程传递过来的系统调用号进行有效性检查查(eax(eax是系统调用号,它应该小于是系统调用号,它应该小于 NR_syscallsNR_syscalls)u如果是合法的系统调用,再进一步检测该系统调用如果是合法的系统调用,再进一步检测该系统调用是否正被跟踪;是否正被跟踪;u根据根据eaxeax中的系统调用号调用相应的服务例程。中的系统调用号调用相应的服务例程。u服务例程结束后,从服务例程结束后,从eaxeax寄存器获得它的返回值,寄存器获得它的返回值,并把这个返回值存放在堆栈中,让其位于用户态并把这个返回值存放在堆栈中,让其位于用户态eaxeax寄存器曾存放的位置。寄存器曾存放的位置。u然后跳转到然后跳转到ret_from_sys_call()ret_from_sys_call(),终止系统调用,终止系统调用程序的执行。程序的执行。SAVE_ALLSAVE_ALL宏定义宏定义 #define SAVE_ALL #define SAVE_ALL cld; cld; pushl %es; pushl %es; pushl %ds; pushl %ds; pushl %eax; pushl %eax; pushl %ebp; pushl %ebp; pushl %edi; pushl %edi; pushl %esi; pushl %esi; pushl %edx; pushl %edx; pushl %ecx; pushl %ecx; pushl %ebx; pushl %ebx; movl $(_KERNEL_DS),%edx; movl $(_KERNEL_DS),%edx; movl %edx,%ds; movl %edx,%ds; movl %edx,%es;movl %edx,%es; 将寄存器中的参数压入到将寄存器中的参数压入到核心栈中核心栈中( (这样内核才能使这样内核才能使用用户传入的参数。用用户传入的参数。) ) 因为在不同特权级之间控因为在不同特权级之间控制转换时,制转换时,INTINT指令不同于指令不同于CALLCALL指令,它不会将外层指令,它不会将外层堆栈的参数自动拷贝到内堆栈的参数自动拷贝到内层堆栈中。层堆栈中。所以在调用系所以在调用系统调用时,必须把参数指统调用时,必须把参数指定到各个寄存器中定到各个寄存器中图10.2 调用总控程序(system_call)执行流程图系统调用表与调用号u这样系统调用处理程序一旦运行,就可以从这样系统调用处理程序一旦运行,就可以从eaxeax中中得到系统调用号,然后再去系统调用表中寻找相得到系统调用号,然后再去系统调用表中寻找相应服务例程。应服务例程。u 一个应用程序调用一个应用程序调用fork()fork()封装例程,那么在执行封装例程,那么在执行int $0 x80int $0 x80之前就把之前就把eaxeax寄存器的值置为寄存器的值置为2(2(即即_NR_fork)_NR_fork)。u这个寄存器的设置是这个寄存器的设置是libclibc库中的封装例程进行的,库中的封装例程进行的,因此用户一般不关心系统调用号因此用户一般不关心系统调用号系统调用表与调用号u核心中为每个系统调用定义了一个唯一的编号,这个编号核心中为每个系统调用定义了一个唯一的编号,这个编号的定义在的定义在linux/include/asm/unistd.hlinux/include/asm/unistd.h中(最大为中(最大为NR_syscallNR_syscall)u同时在内核中保存了一张同时在内核中保存了一张系统调用表,该表中保存了系统系统调用表,该表中保存了系统调用编号和其对应的服务例程地址调用编号和其对应的服务例程地址。第第n n个表项包含系统个表项包含系统调用号为调用号为n n的服务例程的地址。的服务例程的地址。u系统调用陷入内核前,需要把系统调用号一起传入内核。系统调用陷入内核前,需要把系统调用号一起传入内核。而该标号实际上是系统调用表而该标号实际上是系统调用表( ( sys_call_tablesys_call_table) )的下标的下标u在在i386i386上,这个传递动作是通过在执行上,这个传递动作是通过在执行int $0 x80int $0 x80前前把调把调用号装入用号装入eaxeax寄存器寄存器实现。实现。u这样系统调用处理程序一旦运行,就可以从这样系统调用处理程序一旦运行,就可以从eaxeax中得到系中得到系统调用号,然后再去系统调用表中寻找相应服务例程。统调用号,然后再去系统调用表中寻找相应服务例程。系统调用号系统调用号u#define _NR_exit 1u#define _NR_fork 2u#define _NR_read 3u#define _NR_write 4u#define _NR_open 5u#define _NR_close 6u#define _NR_waitpid 7u#define _NR_creat 8u#define _NR_link 9u#define _NR_unlink 10u#define _NR_execve 11u#define _NR_chdir 12u#define _NR_time 13系统调用表系统调用表 (arch/i386/kernel/entry.s)u dataENTRY(sys_call_table).long SYMBOL_NAME(sys_ni_syscall) .long SYMBOL_NAME(sys_exit).long SYMBOL_NAME(sys_fork).long SYMBOL_NAME(sys_read).long SYMBOL_NAME(sys_write).long SYMBOL_NAME(sys_open) .long SYMBOL_NAME(sys_close).long SYMBOL_NAME(sys_waitpid).long SYMBOL_NAME(sys_creat).long SYMBOL_NAME(sys_link).long SYMBOL_NAME(sys_unlink) .long SYMBOL_NAME(sys_execve).long SYMBOL_NAME(sys_chdir).long SYMBOL_NAME(sys_time).long SYMBOL_NAME(sys_mknod) 系统调用表系统调用表记录了各个记录了各个系统调用的服务例程的系统调用的服务例程的入口地址。入口地址。 以系统调用号为偏移量以系统调用号为偏移量能够在该表中找到对应能够在该表中找到对应处理函数地址。处理函数地址。 在在linux/include/linuxlinux/include/linux/sys.h/sys.h中定义的中定义的NR_syscallsNR_syscalls表示该表表示该表能容纳的最大系统调用能容纳的最大系统调用数,一般数,一般NR_syscalls NR_syscalls = 256= 256。系统调用表(sys_call_table)系统调用的返回系统调用的返回u当服务例程结束时,system_call( ) 从eax获得系统调用的返回值,并把这个返回值存放在曾保存用户态 eax寄存器栈单元的那个位置上,然后跳转到ret_from_sys_call( ),终止系统调用处理程序的执行。u当进程恢复它在用户态的执行前,RESTORE_ALL宏会恢复用户进入内核前被保留到堆栈中的寄存器值。其中eax返回时会带回系统调用的返回码(负数说明调用错误,0或正数说明正常完成)系统调用的返回值系统调用的返回值u所有的系统调用返回一个整数值。所有的系统调用返回一个整数值。n正数或正数或0 0表示系统调用成功结束表示系统调用成功结束n负数表示一个出错条件负数表示一个出错条件u这里的返回值与封装例程返回值的约定不同这里的返回值与封装例程返回值的约定不同n内核没有设置或使用内核没有设置或使用errnoerrno变量变量n封装例程在系统调用返回取得返回值之后设置这封装例程在系统调用返回取得返回值之后设置这个变量个变量n当系统调用出错时,返回的那个负值将要存放在当系统调用出错时,返回的那个负值将要存放在errnoerrno变量中返回给应用程序变量中返回给应用程序5.3 5.3 系统调用系统调用- -实例分析实例分析假设源文件名为假设源文件名为getpid.cgetpid.c,内容是:,内容是:#include #include #include #include #include #include #include #include int main(void) int main(void) long ID; long ID; ID = getpid(); ID = getpid(); printf (getpid()=%ldn, ID); printf (getpid()=%ldn, ID); return(0); return(0); 系统调用系统调用- -实例分析实例分析u 该程序调用封装例程该程序调用封装例程getpid()getpid()。该封装例程将。该封装例程将系统调用号系统调用号_NR_getpid_NR_getpid(第(第2020个)压入个)压入EAXEAX寄存寄存器器uCPUCPU通过通过int $0 x80 int $0 x80 进入内核,找到进入内核,找到system_call()system_call(),并调用它,并调用它 (以下进入内核态)(以下进入内核态)3. 3. 在内核中首先执行在内核中首先执行system_call()system_call(),接着执行,接着执行根据系统调用号在调用表中查找到的对应的系根据系统调用号在调用表中查找到的对应的系统调用服务例程统调用服务例程sys_getpid()sys_getpid()。4 4执行执行syssys_ _getpid()getpid()服务例程。服务例程。5 5执行完毕后,转入执行完毕后,转入ret_from_sys_call()ret_from_sys_call()例程,例程,系统调用返回到用户态。系统调用返回到用户态。5.4 5.4 系统调用的参数传递系统调用的参数传递u很多系统调用需要不止一个参数很多系统调用需要不止一个参数n普通普通C C函数的参数传递是通过把参数值写入堆栈函数的参数传递是通过把参数值写入堆栈( (用用户态堆栈或内核态堆栈户态堆栈或内核态堆栈) )来实现的。但因为系统调来实现的。但因为系统调用是一种特殊函数,它由用户态进入了内核态,所用是一种特殊函数,它由用户态进入了内核态,所以以既不能使用用户态的堆栈也不能直接使用内核态既不能使用用户态的堆栈也不能直接使用内核态堆栈堆栈用户态堆栈用户态C函数内核态堆栈内核态C函数系统调用的参数传递系统调用的参数传递n在在int $0 x80int $0 x80汇编指令之前,系统调用的参数被写汇编指令之前,系统调用的参数被写入入CPUCPU的的寄存器寄存器。然后,在进入内核态调用系统调。然后,在进入内核态调用系统调用服务例程之前,内核再把存放在用服务例程之前,内核再把存放在CPUCPU寄存器中的寄存器中的参数拷贝到内核态堆栈中。因为毕竟服务例程是参数拷贝到内核态堆栈中。因为毕竟服务例程是C C函数,它还是要到堆栈中去寻找参数的函数,它还是要到堆栈中去寻找参数的用户态堆栈用户态C函数内核态堆栈内核态C函数寄存器系统调用的参数传递系统调用的参数传递系统调用系统调用使用寄存器来传递参数使用寄存器来传递参数,要传递的参数有:,要传递的参数有:系统调用号系统调用号系统调用所需的参数系统调用所需的参数用于传递参数的寄存器有:用于传递参数的寄存器有:eaxeax:用于保存系统调用号和系统调用返回值:用于保存系统调用号和系统调用返回值系统调用参数保存在:系统调用参数保存在:ebx,ecx,edx,esiebx,ecx,edx,esi和和ediedi中中进入内核态后,进入内核态后,system_callsystem_call通过使用通过使用SAVE_ALLSAVE_ALL宏把这宏把这些寄存器的值保存在内核态堆栈中。些寄存器的值保存在内核态堆栈中。n用寄存器传递参数必须满足两个条件:用寄存器传递参数必须满足两个条件:n 每个参数的长度不能超过寄存器的长度每个参数的长度不能超过寄存器的长度n 参数的个数不能超过参数的个数不能超过6 6个个( (包括包括eaxeax中传递中传递的系统调用号的系统调用号););否则,需要用一个单独的否则,需要用一个单独的寄存器指向进程地址空间中这些参数值所寄存器指向进程地址空间中这些参数值所在的一个内存区即可在的一个内存区即可n返回值必须写到返回值必须写到eaxeax寄存器中寄存器中系统调用的参数传递系统调用的参数传递参数传递举例参数传递举例u 处理处理writewrite系统调用的系统调用的sys_writesys_write服务例程声明如下服务例程声明如下u 该函数期望在栈顶找到该函数期望在栈顶找到fdfd,bufbuf和和countcount参数参数在封装在封装sys_write()sys_write()的封装例程中,将会在的封装例程中,将会在ebxebx、ecxecx和和edxedx寄存寄存器中分别填入这些参数的值,然后在进入器中分别填入这些参数的值,然后在进入system_callsystem_call时,时,SAVE_ALLSAVE_ALL会把这些寄存器保存在堆栈中,进入会把这些寄存器保存在堆栈中,进入sys_writesys_write服务例服务例程后,就可以在相应的位置找到这些参数程后,就可以在相应的位置找到这些参数asmlinkage使得编译器不通过寄存器(x=0)而使用堆栈传递参数SAVE_ALLSAVE_ALLSys_write需要的参数系统调用的参数传递系统调用的参数传递- -举例设设C库中封装的系统调用号为库中封装的系统调用号为3的函数原形如下:的函数原形如下: int sys_func(int para1, int para2)C编译器产生的汇编伪码如:编译器产生的汇编伪码如:movl 0 x8(%esp),%ecx /*将用户态堆栈中的将用户态堆栈中的para2放入放入ecxMovl 0 x4(%esp),%ebx /*#将用户态堆栈中的将用户态堆栈中的para1放入放入ebxMovl $0 x3,%eax /*系统调用号保存在系统调用号保存在eax中中int$0 x80 #引发系统调用引发系统调用Movl %eax,errno /*将结果存入全局变量将结果存入全局变量errno中中Movl $-1,%eax /*eax置为置为-1,表示出错注,表示出错注5.5 5.5 练习:练习:添加一个系统调用添加一个系统调用mysyscallmysyscallu功能要求功能要求 首先,自定义一个系统调用首先,自定义一个系统调用mysyscallmysyscall ,它的功,它的功能是使用户的能是使用户的uiduid等于等于0 0 。然后,编写一段测试程。然后,编写一段测试程序进行调用。序进行调用。u执行步骤如下执行步骤如下n添加系统调用号添加系统调用号n在系统调用表中添加相应的表项在系统调用表中添加相应的表项n实现系统调用服务例程实现系统调用服务例程n重新编译内核,启动新内核重新编译内核,启动新内核n编写一段测试程序检验实验结果编写一段测试程序检验实验结果添加一个系统调用添加一个系统调用mysyscallmysyscall(1 1)添加系统调用号:)添加系统调用号:它位于它位于unistd.hunistd.h,每个系统调用号,每个系统调用号都以都以“_NR_NR_开头开头”,u系统调用的编号命名为系统调用的编号命名为 _NR_mysyscall_NR_mysyscallu改写改写/usr/include/asm/unistd.h/usr/include/asm/unistd.h240240 #define #define _NR_llistxattr_NR_llistxattr 233233241241 #define #define _NR_flistxattr_NR_flistxattr 234234242242 #define #define _NR_removexattr_NR_removexattr 235235243243 #define #define _NR_lremovexattr_NR_lremovexattr 236236244244 #define #define _NR_fremovexattr_NR_fremovexattr 237237245245 #define #define _NR_mysyscall238238添加一个系统调用添加一个系统调用mysyscallmysyscall(2 2)在系统调用表中添加相应的表项)在系统调用表中添加相应的表项u内核中实现该系统调用的例程的名字内核中实现该系统调用的例程的名字 sys_mysyscallsys_mysyscallu改写改写arch/i386/kernel/entry.Sarch/i386/kernel/entry.S398398 ENTRY(sys_call_table) ENTRY(sys_call_table)399399 .long SYMBOL_NAME(sys_ni_syscall) .long SYMBOL_NAME(sys_ni_syscall) 636636 .long SYMBOL_NAME(sys_ni_syscall) .long SYMBOL_NAME(sys_ni_syscall) 637 637 .long SYMBOL_NAME(sys_mysyscall).long SYMBOL_NAME(sys_mysyscall)638 638 639 .rept NR_syscalls-(.-sys_call_table)/4639 .rept NR_syscalls-(.-sys_call_table)/46 640 .long SYMBOL_NAME(sys_ni_syscall)40 .long SYMBOL_NAME(sys_ni_syscall)64641 .endr 1 .endr 添加一个系统调用添加一个系统调用mysyscallmysyscall(3 3)实现实现系统调用服务例程系统调用服务例程 把一小段程序添加在把一小段程序添加在kernel/sys.ckernel/sys.casmlinkage int sys_mysyscall(void)asmlinkage int sys_mysyscall(void) current-uid = current-euid = current-suid = current-current-uid = current-euid = current-suid = current-fsuid = 0;fsuid = 0;return 0;return 0; (4 4)重新编译内核,启动新内核)重新编译内核,启动新内核添加一个系统调用添加一个系统调用mysyscallmysyscall(5 5)编写一段测试程序检验实验结果)编写一段测试程序检验实验结果#include #include _syscall0_syscall0(int,mysyscall)/(int,mysyscall)/* * 注意这里没有分号注意这里没有分号 * */ /int main()int main() mysyscall(); mysyscall();printf(printf(“This is my uid: %d. nThis is my uid: %d. n”, getuid();, getuid(); u_syscall1(int,print_info,int,testflag)u如果要在用户程序中使用系统调用函数,那么在主函数main前必须申明调用_syscall,其中1 表示该系统调用只有一个入口参数,第一个int 表示系统调用的返回值为整型,print_info为系统调用函数名,第二个int 表示入口参数的类型为整型,testflag为入口参数名。系统调用执行系统调用执行- -小结小结u1 1、程序调用库的封装函数、程序调用库的封装函数 u2 2、调用软中断、调用软中断 int $0 x80 int $0 x80 进入内核。进入内核。 u3 3、在内核中首先执行、在内核中首先执行system_call()system_call()函数,接着函数,接着根据系统调用号在系统调用表中查找到对应的系根据系统调用号在系统调用表中查找到对应的系统调用服务例程统调用服务例程 u4 4、执行该服务例程、执行该服务例程 u5 5、执行完毕后,转入、执行完毕后,转入ret_from_sys_callret_from_sys_call例程,例程,从系统调用返回从系统调用返回 作业作业u什么是系统调用?它与普通函数调用有何区别?什么是系统调用?它与普通函数调用有何区别?u什么是系统调用号和系统调用表?什么是系统调用号和系统调用表?u系统调用的参数如何传递到内核?系统调用的参数如何传递到内核?u简述添加系统调用的大致流程。简述添加系统调用的大致流程。43 结束语结束语

    注意事项

    本文(Linux系统调用-详细全过程.ppt)为本站会员(豆****)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开