Linux内核system_call中断处理过程
在相应的test.c中添加getpid和getpid-asm的函数,使Menu实现getpid和getpid-asm的命令。
添加完成后,修改menu目录下的Makefile文件中的 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img变为qemu-system-i386 -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
然后执行在menu目录下:终端输入make rootfs
运行效果:
sys_call 调用处理过程
应用程序告诉内核自己需要执行一个系统调用时,通知内核的机制是靠软中断实现的:通过引发一个异常促使系统切换到内核去执行异常处理程序。该异常处理程序实际就是系统调用处理程序。在x86系统上。通过int$0x80指令触发该中断。这条指令会触发一个异常导致系统切换到内核态并执行第128号异常处理程序----系统调用处理程序。系统调用处理程序叫sys_call(),它与硬件体系结构紧密相关,在x86-64位系统上在entry_64.S文件中,用汇编语言编写。
system_call函数通过将给定的系统调用号(eax的值)与NR_syscalls做比较来检查其有效性。如果它大于或等于NR_syscalls,该函数返回-ENOSYS。否则执行相应的系统调用:call *sys_call_table(,%rax,4)。由于系统调用表中的表项是以32位(4字节)类型存放的,所以内核需要将给定的系统调用号乘以4,然后用所得结果在该表中查询其位置。
除了系统调用号以外,大部分系统调用都还需要一些外部的参数输入,所以需要把这些参数从用户空间传给内核。最简单的方法就是像传递系统调用参数那样也存放在寄存器里。在x83-32系统上,ebx,ecx,edx,esi,edi按照顺序存放前五个参数。需要六个或者以上的参数,应该用一个单独的寄存器存放指向所有这些参数在用户空间地址的指针。给用户空间的返回值也通过寄存器传递。在x86系统上存放在eax寄存器里。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。