1.增加 Menu 内核命令行
调试系统调用。
步骤:删除menu
git clone (tab)
make rootfs
这就是我们将 fork
函数写入 Menu
系统内核后的效果,通过命令行,实现了操作系统调用过程。
2.GDB 追踪内核调用 sys_fork
通过查询操作系统内核调用函数 API,我们知道 fork
函数的系统调用是 sys_fork,下面我们就通过 GDB
来追踪 sys_fork
的调用过程。
由图可知,sys_fork
在底层调用的是 do_fork
函数。
3.分析内核调用汇编源码
ENTRY(system_call)
RING0_INT_FRAME # can't unwind into user space anyway
ASM_CLAC
pushl_cfi %eax # save orig_eax
SAVE_ALL #保存现场
GET_THREAD_INFO(%ebp) # system call tracing in operation / emulation
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) # store the return value
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
restore_all:
TRACE_IRQS_IRET #恢复现场
irq_return:
INTERRUPT_RETURN #中断返回
总结:
本次实验使用GDB跟踪了系统调用执行的整个过程,同时又从源代码级别比较深入的了解到完成系统调用内核所做的工作。Linux中是以0x80号软中断引发的系统调用的,即0x80号中断的处理程序就是位于kernel/entry_32.S中system_call函数。这个函数首先是保存现场,然后通过eax查找对应哪一个系统调用,然后查找sys_call_table调用对应的系统调用。等完成调用之后检查是否有信号发生或者需要进程调度,如果有就进入相应的处理程序,如果没有就恢复现场完成了整个系统调用
李海空原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000