分析system_call中断处理过程

来源:互联网 发布:小提琴音准软件 编辑:程序博客网 时间:2024/05/16 04:43

黄二玉+原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”

预备知识

中断向量,中断向量表,系统调用号

中断向量是指中断服务程序入口地址,一个中断向量占据4字节空间(x86)。
中断向量表是由多个中断向量组成的一张表。系统调用号是该中断向量在该表的位置(从0开始)。
因此系统调用号按为右移两位在加上表的基址可以得到相应的中断向量的位置,该位置上存放了中断向量,即中断处理程序的入口地址;
         中断向量表

linux系统调用的过程

简化后的代码如下(Linux/arch/x86/kernel/entry_32.S):

490 ENTRY(system_call)        ...494         SAVE_ALL    /*保存现场*/        ...501 syscall_call:502         call *sys_call_table(,%eax,4) /* 调用中断向量表,并且执行中断处理程序*/503 syscall_after_call:504         movl %eax,PT_EAX(%esp)           /*把返回的值放在ax中*/505 syscall_exit:        ...512         testl $_TIF_ALLWORK_MASK, %ecx  # current->work513         jne syscall_exit_work        ....515 restore_all:516         TRACE_IRQS_IRET        ...532 irq_return:533         INTERRUPT_RETURN        ...588 ENDPROC(system_call)        ...593 work_pending:594         testb $_TIF_NEED_RESCHED, %cl595         jz work_notifysig596 work_resched:597         call schedule        ...606         jz restore_all607         testb $_TIF_NEED_RESCHED, %cl608         jnz work_resched610 work_notifysig:   ....640 END(work_pending)...656 syscall_exit_work:657         testl $_TIF_WORK_SYSCALL_EXIT, %ecx658         jz work_pending...662         movl %esp, %eax663         call syscall_trace_leave664         jmp resume_userspace665 END(syscall_exit_work)

可以用下面的流程图表示:
流程图

例子

int getpid(){    int a;    asm volatile(    "mov $20,%%eax\n\t"    "int $128\n\t"    "mov %%eax,%0\n\t"    :"=m"(a)    );

在命令行输入break sys_getpidcn可以进行一步一步的执行;
getpid

总结

cpu通过int $128进入内核,找到system_call(),并调用它,在内核中首先执行system_call(),接着根据系统调用号在中断向量表中找到对应的系统调用服务例程sys_getpid(),然后执行该例程,执行完后,检查是否有新的中断,如果有再进行处理,等所有的中断处理完成后返回用户态。

0 0
原创粉丝点击