我理解i386的系统调用过程

linux系统调用函数少,陷入内核效率高,过程大概是这样的:

1,初始化阶段,登录门描述符的处理:

./arch/i386/kernel/traps.c

void __init trap_init(void)

{

...

set_system_gate(SYSCALL_VECTOR,&system_call);

...

}

2,程序中使用 int 0x80指令陷入内核,CPU切换到内核态,执行对应的处理函数,这里为system_call

./arch/i386/kernel/entry.S

...

ENTRY(system_call)
 pushl %eax   # save orig_eax
 SAVE_ALL
 GET_THREAD_INFO(%ebp)
     # system call tracing in operation
 testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
 jnz syscall_trace_entry
 cmpl $(nr_syscalls), %eax
 jae syscall_badsys
syscall_call:
 call *sys_call_table(,%eax,4)
 movl %eax,EAX(%esp)  # store the return value
syscall_exit:
 cli    # make sure we don't miss an interrupt
     # setting need_resched or sigpending
     # between sampling and the iret
 movl TI_flags(%ebp), %ecx
 testw $_TIF_ALLWORK_MASK, %cx # current->work
 jne syscall_exit_work

...

3,其中call *sys_call_table(,%eax,4)调用sys_XXX函数,完成系统调用功能。

系统调用号通过eax寄存器传递给内核,其他参数通过ebx,ecx等,内核通过SAVE_ALL将其保存在内核栈中,因为所有系统调用函数sys_XXX都是asmlinkage的,也就是从栈中取得参数。返回值保存在eax中

#define SAVE_ALL /
 cld; /
 pushl %es; /
 pushl %ds; /
 pushl %eax; /
 pushl %ebp; /
 pushl %edi; /
 pushl %esi; /
 pushl %edx; /
 pushl %ecx; /
 pushl %ebx; / //注意压栈的顺序,
 movl $(__USER_DS), %edx; /
 movl %edx, %ds; /
 movl %edx, %es;

重点:用户态切换到内核态,栈切换,参数传递

参考:情景分析中断/系统调用章节

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值