您的位置:首页 > 运维架构 > Linux

Linux系统内核分析实验——system_call中断处理过程

2017-03-18 18:09 567 查看
在linux中,当一个系统调用发生时,linux内核会做什么事?

linux system_call处理代码,该处理函数大量直接操作寄存器

ENTRY(system_call)
RING0_INT_FRAME         # can't unwind into user space anyway
ASM_CLAC
pushl_cfi %eax          # save orig_eax
SAVE_ALL
GET_THREAD_INFO(%ebp)
# system call tracing in operation / emulation
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
jnz syscall_trace_entry
cmpl $(NR_syscalls), %eax
jae syscall_badsys
syscall_call:
call *sys_call_table(,%eax,4)
syscall_after_call:
movl %eax,PT_EAX(%esp)      # store the return value
syscall_exit:
LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY)    # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
TRACE_IRQS_OFF
movl TI_flags(%ebp), %ecx
testl $_TIF_ALLWORK_MASK, %ecx # current->work
jne syscall_exit_work

restore_all:
TRACE_IRQS_IRET
restore_all_notrace:
#ifdef CONFIG_X86_ESPFIX32
movl PT_EFLAGS(%esp), %eax  # mix EFLAGS, SS and CS
# Warning: PT_OLDSS(%esp) contains the wrong/random values if we
# are returning to the kernel.
# See comments in process.c:copy_thread() for details.
movb PT_OLDSS(%esp), %ah
movb PT_CS(%esp), %al
andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
CFI_REMEMBER_STATE
je ldt_ss           # returning to user-space with LDT SS
#endif
restore_nocheck:
RESTORE_REGS 4          # skip orig_eax/error_code
irq_return:
INTERRUPT_RETURN


大致流程:

1. 进入system_call

2. 保护现场SAVE_ALL

3. 根据eax中的调用号在系统调用表中调用相应功能

4. 存储返回值

5. 调用syscall_exit_work,进行中断检测与进程调度

6. 回复现场,返回用户态
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: