实验部分:
给MenuOS增加Name和Name-asm命令:
- 更新menu代码到最新版
- 在main函数中增加Menuconfig
- 增加对应的Name和NameAsm函数
- make rootfs
实验截图:
系统调用机制的初始化:
♦\init\main.c start_kernel
trap_init();
♦\arch\x86\kernel\traps.c
#ifdef CONFIG_X86_32
set_system_trap_gate(SYSCALL_VECTOR, &system_call);
set_bit(SYSCALL_VECTOR, used_vectors); #endif
#endif
system_call到iret处理过程:
- 系统调用机制的初始化在start_kernel里面的trap_init()函数里进行,这个函数里面包含了sys_call汇编代码的入口,初始化好了之后,一旦执行int 0x80,CPU就会自动跳转到sys_call来执行。
- sys_call的相关代码的位置是Linux-3.18.6/arch/x86/kernel/entry_32.s,里面的ENTRY(system_call)为int 0x80后的下一条指令,因其不是一个正常的函数,所以CPU还不能对其进行跟踪。
- 由代码可知,系统调用的过程大致分为三个阶段:保存现场SAVE_ALL、调用系统调用相对应的处理函数如time、name等,call *sys_call_table()、恢复现场RESORE_ALL 最后ire结束,返回用户态。在这个过程中,可能 会用到syscall_exit_work,里面有关于进程调度的函数。
流程图:
总结部分:
- 中断处理是用户态进入内核态的主要方式,系统调用作为一种中断处理过程,能够反映出一般的中断处理机制,可以说系统调用是一种特殊的中断。
- int 0x80 与system_call通过中断向量关联起来,系统调用号将xyz 与sys_xyz 关联起来,通过使用系统调用表保存系统服务函数的地址的形式实现。
- 在系统调用返回之前,可能会发生进程调度(call_schedule),其中可能还会发生中断上下文的切换和进程上下文的切换。