2019-2020-1 20199326《Linux内核原理与分析》第六周作业

本周学习了庖丁解牛Linux内核分析第五章:系统调用的三层机制(下),是上一章的延续

实验内容:使用gdb跟踪分析一个系统调用内核函数

上周实验我选择的getpid这个系统系统调用,这次准备使用gdb跟着系统调用内核函数sys_getpid

先更新一下menu文件夹

然后修改一下test.c,把上周写的两个关于getpid系统调用的函数加入,并在main里声明

然后进行编译

编译完成后,输入help,可以看到,menuos多了两个命令pid和pid-asm

接下来要开始跟踪系统调用函数sys_getpid,首先先用qemu启动内核,并让其处于初始暂停状态

另一个shell里输入gdb命令,进入gdb后,建立和menuos的调试连接

然后分别在start_kernel和sys_getpid处设置断点,并输入c继续执行

实验楼的虚拟机环境每次执行到这一步都卡住了,实在没有办法,我就只能用书来对system_call汇编代码进行简单分析

system_call汇编代码分析

ENTRY(system_call)
RINGO_INT_FRAME
ASM_CLAC
push1_cfi %eax   /*保存系统调用号*/
SAVE_ALL  /*保存现场,将用到的所有CPU寄存器保存到栈中*/
GET_THREAD_INFO(%ebp)   /*ebp用于存放当前进程thread_info结构的地址*/
test1 $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
jnz syscall_trace_entry
cmp1 $(nr_syscalls),%eax   /*检查系统调用号(系统调用号应小于NR_syscalls)*/
jae syscall_badsys   /*不合法,跳入异常处理*/
syscall_call:
 call *sys_call_table(,%eax,4)   /*合法,对照系统调用号在系统调用表中寻找相应的系统调用的内核处理函数*/
 movl %eax,PT_EAX(%esp)/*保存返回值到栈中*/
 syscall_exit:  
 testl $_TIF_ALLWORK_MASK, %ecx/*检查是否需要处理信号*/
 jne syscall_exit_work /*需要,进入 syscall_exit_work*/
 restore_all: 
 TRACE_IRQS_IRET /*不需要,执行restore_all恢复,返回用户态*/
 irq_return:
 INTERRUPT_RETURN /*相当于iret*/

system_call流程示意图

猜你喜欢

转载自www.cnblogs.com/funmary/p/11743070.html