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

作业信息

这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)>
这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第六周作业>
这个作业的目标 <使用gdb跟踪分析一个系统调用内核函数>
作业正文 本博客链接

实验过程

向MenuOS中添加命令

删除并重新git新版本的menu文件夹

修改相应的test.c文件,添加相应的getPid命令

使用make rootfs重新编译生成镜像

打开系统进行测试

使用gdb进行调试


源码分析

在linux-3.18.6/arch/x86/kernel/entry_32.S中可以查看到system_call的汇编源码:

ENTRY(system_call)
	RING0_INT_FRAME	
	ASM_CLAC
	pushl_cfi %eax			
	SAVE_ALL
	GET_THREAD_INFO(%ebp)
	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
	jnz syscall_trace_entry
	cmpl $(NR_syscalls), %eax
	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)
	TRACE_IRQS_OFF
	movl TI_flags(%ebp), %ecx
	testl $_TIF_ALLWORK_MASK, %ecx
	jne syscall_exit_work
restore_all:
	TRACE_IRQS_IRET
restore_all_notrace:
	movl PT_EFLAGS(%esp), %eax	# mix EFLAGS, SS and CS
	movb PT_OLDSS(%esp), %ah
	movb PT_CS(%esp), %al
	andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
	cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
	CFI_REMEMBER_STATE
	je ldt_ss
#endif
restore_nocheck:
	RESTORE_REGS 4
irq_return:
	INTERRUPT_RETURN

系统进入系统调用时(system_call),会首先保存现场,执行save_all宏,然后进行调用中断服务程序syscall_call,接着执行syscall_exit,当执行到这里准备退出时,会进行判断需不需要响应其他中断或者信号,如果不需要则直接进行restore_all恢复现场并且irq_return,正式返回到系统调用的地方;如果需要响应其他中断,则需要执行syscall_exit_work,看看有没有work_resched或者work_notifysig,看看当前进程需不需要调度,如果需要就执行call_schedule,如果需要响应某个信号,则进行work_notifysig,接着再跳转至restore_all接着执行并退出。这个就是系统调用时汇编代码级别的大致执行过程。具体可以按流程图:

原文地址:https://www.cnblogs.com/yanzs/p/13977065.html