这个作业属于哪个课程 | <2020-2021-1Linux内核原理与分析)> |
---|---|
这个作业要求在哪里 | <2020-2021-1Linux内核原理与分析第六周作业> |
这个作业的目标 | 给MenuOS增加命令,使用gdb跟踪分析系统调用,分析system_call工作过程 |
作业正文 | ... https://www.cnblogs.com/hyuxin/p/13970375.html |
实验五
一、给MenuOS增加命令
上周我选择的是getpid这个系统调用,所以这周使用gdb跟踪分析sys_getpid
1.首先更新menu代码到最新版
2.在main函数中增加MenuConfig
3.增加上周写的两个pid函数
4.make roofts进行编译
5.输入help回车可以看到增加了两个命令pid和pid-asm
运行命令可以得到进程号
二、使用gdb跟踪分析sys_getpid
1.进入gdb调试,在start_kernel处设置断点进行调试
2.在sys_getpid处进行断点调试
3.执行pid命令,没有退出调试
4.执行getpid命令,调试退出
5.结束调试,发现了getpid函数,并返回了进程号
三、system_call过程分析
ENTRY(system_call)
RING0_INT_FRAME
ASM_CLAC
pushl_cfi %eax # 保存系统调用号
SAVE_ALL # 保存现场,将用到的所有CPU寄存器保存到栈中
GET_THREAD_INFO(%ebp)
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
jnz syscall_trace_entry
cmpl $(NR_syscalls), %eax #检查系统调用号(系统调用号应小于NR_syscalls)
jae syscall_badsys #不合法,跳入异常处理
syscall_call:
call *sys_call_table(,%eax,4) #合法,对照系统调用号在系统调用表中寻找相应的系统调用的内核处理函数
syscall_after_call:
movl %eax,PT_EAX(%esp) #保存返回值到栈中
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
流程示意图如下:
四、总结
当一个系统调用发生时,进入内核处理这个系统调用,系统调用的内核服务程序在服务结束返回到用户态之前,可能会发生进程调度。在进程调度中会发生进程上下文的切换。而具体的系统调用与系统调用号绑定,然后都记载在一个系统调用表内,每次由系统调用号去找系统调用表然后查找到所对应的系统调用的位置。