2020-2021-1 20209328 《Linux内核原理与分析》第六周作业
作业信息
这个作业属于哪个课程 | <2020-2021-1Linux内核原理与分析)> |
---|---|
这个作业要求在哪里 | <2020-2021-1Linux内核原理与分析第六周作业> |
这个作业的目标 | <使用gdb跟踪分析一个系统调用内核函数,分析system_call对应的汇编代码的工作过程,以及系统调用返回iret之前的进程调度时机> |
作业正文 | ... https://www.cnblogs.com/matahh/p/13972279.html |
一.实验目的 | |
使用gdb跟踪分析一个系统调用内核函数,从system_call开始到iret结束之间的整个过程,并画出简要准确的流程图,要仔细分析system_call对应的汇编代码的工作过程,特别注意系统调用返回iret之前的进程调度时机等。 | |
二.实验内容 | |
1.给MenuOS添加命令 |
rm -rf menu //强制删除当前的menu目录
git clone http://github.com/mengning/menu.git //克隆
make roofts //自动编译并自动生成跟文件系统
将getpid加入到test.c
2.用gdb来跟踪系统调用内核的函数sys_time
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S //内核启动
(gdb)file linux-3.18.6/vmlinux
(gdb)target remote:1234
(gdb)b start_kernel //加入断点
接下来就可以在sys_time 设置断点
gdb调试也可以看到Breakpoint在linux-3.18.6/kernel/time/time.c中的这个文件。因为是用宏来实现的,所以无法直接看到sys_time.
3.分析总结
分析system_call对应的汇编代码的工作过程,特别注意系统调用返回iret之前的进程调度时机等。
内核执行int 0x80后系统跳转到system_call入口,首先系统进行保存现场的工作(包括将用户态进程的各寄存器保存在内核堆栈上),之后系统执行sys_call_table,该函数通过系统调用号来查找实际的系统调用函数,当该函数返回时,系统保存其返回值,然后到syscall_exit_work,这里会有一个判断,即此时系统是否还有没有完成的额外工作,如果有的话,首先进入work_pending,这里是检查是否有等待调度的进程,因为这里是内核设置的进程调度的一个时机。该段程序循环调度需要调度的进程,如果已经没有需要调度的进程,紧接着需要检查是否有挂起的信号(比如进程间通信的一些信号)等待处理。处理完毕后,本次系统调用也就接近了尾声,此时恢复上下文,然后将CPU控制权交给用户态。至此该段代码执行完毕。
画出流程图: