linux中system_call中断处理过程

       上次我们分析了系统调用大致过程,现在我们把这两个系统调用的代码放到MenuOS中,并用gdb跟踪调试来看看从system_call开始到iret结束之间的整个过程。

       边看实验过程边分析:

      首先我们要将系统里面的menu目录删去,然后从github上更新到新版的menu。


       

      接着,把我们之前写好的getpid()的c版本和asm版本加入到menu中,最后make rootfs启动系统。这样系统中就增加了两个命令。输入pid或者pid-asm就能看到当前进程号。





   

       MenuOS系统装好之后,就该分析这个系统特别是系统调用的过程了。我们还是用老办法,先冻结内核加载,再gdb跟踪调试。




       启动gdb,加载3.18.6内核符号表,设置gdbsever远程调试端口,在start_kernel处设置断点等等就不再赘述,前面的文章有详细操作。直接来看结果。






       我们主要来看看在系统调用处,这里是getpid()函数处设置断点之后,处理过程是怎样的。




       系统启动过后,输入pid命令:




       这块出了点状况。当我输入pid时是可以得到pid号的,而输入pid-asm却被冻结。原因可能是c版本中的getpid不是通过调用int 0x80进入中断的,而我们的汇编程序是指定了用int 0x80指令。不过这并不影响我们继续分析。用list列出此处代码也能窥晓一二。一直用s单步执行程序,一步步的观察执行情况:




       用finish结束,再接着s单步执行,直到能显示当前进程号。我们还可以载system_call处设置断点,接着s单步执行:






       观察完整个过程后,主要的还是对整个过程的理解。

      1、用户通过执行int 0x80汇编指令,使自己从用户态切换到了内核态。通过执行ireq汇编指令,从系统调用中退出。

      2、当用户进程发出int 0x80指令时,cpu切换到内核态并开始从地址system_call处开始执行指令。

      3、system_call()函数首先把系统调用号和这个异常处理程序可以用到的所有CPU寄存器保存到相应栈中,再对用户态进程传来的系统调用号进行有效性检查,最后调用与eax中所包含的系统调用号对应的特定服务例程。

      4、当系统调用服务例程结束时,system_call()函数从eax获得返回值。如果所有标志都没有被设置,函数跳到restore_all处执行,并执行ireq。如果有被设置的标志,那么在返回前将有一些工作要完成。

       





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值