Linux系统调用的system_call处理过程分析

董涛 

原创作品转载请注明出处

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

 

基于实验楼网站提供的《Linux内核分析》实验平台,编辑上周写的两个函数(以库函数uid_t getuid()和C代码中嵌入汇编代码两种方式,返回一个调用程序的真实用户ID),并将这两个函数写入基于Linux内核的操作系统menu中的test.c文件中,在menu操作系统中实现userid和userid_asm两个命令,可以通过这两个命令实现对当前用户ID的查看。

先看截图:

截图一、将上周写的两个函数分别命名为int getuidc() int getuid_asm,将这两个函数写入test.c文件中,截图如下:

 

然后,修改main()函数中的配置命令,加入两个命令usrid和userid_asm,分别有函数getuidc和函数getuid_asm实现。截图如下:

 

通过make rootfs脚本命令运行一下,可以看出通过userid命令和userid_asm命令都可以获取程序的用户id,截图如下:

下面,详细分析一下menu操作系统通过user命令和user_asm命令对系统内核服务的调用。在操作系统启动过程中,首先对系统调用进行初始化,系统调用实质上是一种中断,是通过\int\main.c \start_kernel文件中的trap_int()函数声明的,trap_int()函数指向\arch\x86\kernel\traps.c文件中的set_system_trap_gate(SYSCALL_VECTOR,&system_call)函数,在这一过程中,通过参数SYS_CALL传递系统调用中断向量,&system_call是汇编代码入口。在本例的menu操作系统中,中断向量int 0x80指向系统调用system_call,接下来的流程如下图所示:

Linux系统调用的system_call处理过程分析_第1张图片

 

在如上流程中,system_exit:是系统调用结束前的进程切换模块,其代码如下:

6syscall_exit_work:
657	testl $_TIF_WORK_SYSCALL_EXIT, %ecx
658	jz work_pending
659	TRACE_IRQS_ON
660	ENABLE_INTERRUPTS(CLBR_ANY)	# could let syscall_trace_leave() call
661					# schedule() instead
662	movl %esp, %eax
663	call syscall_trace_leave
664	jmp resume_userspace
665END(syscall_exit_work)

系统调用完成后,通过汇编命令iret返回主程序,至此,系统调用实现任务并返回。

总之,系统调用作为一种中断处理过程,能够反映出一般的中断处理机制,对于一般的中断处理,同样是由四个主要步骤完成的,首先进入中断,保护好现场,第二步调用中断的服务程序,第三步,完成中断退出前的进程切换工作,第四步,返回主程序并恢复现场。OK。

你可能感兴趣的:(liunx)