在内核入口函数start_kernel中调用trap_init实现系统调用的初始化工作
void __init trap_init(void)
{
...
set_system_trap_gate(SYSCALL_VECTOR, &system_call);
....
}
也就是IDT中0x80用来实现系统调用,实现系统调用的函数为system_call,为汇编实现
ENTRY(system_call)
RING0_INT_FRAME # can't unwind into user space anyway
pushl %eax # save orig_eax
CFI_ADJUST_CFA_OFFSET 4
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)/*跳转到具体的系统调用函数*/
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
........
具体的系统调用函数存放在sys_call_table表中,在调用system_call具体的系统调用号存放在eax寄存器中。