贺邦 + 原创做品转载请注明出处 + 《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000linux
将上一个系统调用函数和asm版本的实现整合进入menu的内核中:函数
上面的一段代码,MenuConfig这个函数是菜单(也就是制做出来的内核)的初始化配置函数,第一个参数是命令,第二个参数是该命令的描述,第三个参数是这个命令相对应的handler,也就是回调函数,是经过一个函数指针进行实现的。ExecuteMenu这个函数是为了启动这个menu引擎,实际上是一个循环等待用户输入命令的过程。ui
将上周写的两个函数分别命名为int getuidc() int getuid_asm,将这两个函数写入test.c文件中:spa
而后,修改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:code
在如上流程中,system_exit:是系统调用结束前的进程切换模块,其代码以下:进程
testl $_TIF_WORK_SYSCALL_EXIT, %ecx jz work_pending TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_ANY) # could let syscall_trace_leave() call # schedule() instead movl %esp, %eax call syscall_trace_leave jmp resume_userspace END(syscall_exit_work)
系统调用完成后,经过汇编命令iret返回主程序,至此,系统调用实现任务并返回。回调函数
总之,系统调用做为一种中断处理过程,可以反映出通常的中断处理机制,对于通常的中断处理,一样是由四个主要步骤完成的,首先进入中断,保护好现场,第二步调用中断的服务程序,第三步,完成中断退出前的进程切换工做,第四步,返回主程序并恢复现场