《Linux内核分析》 第五节 扒开系统调用的三层皮(下)
《Linux内核分析》 第五节 扒开系统调用的三层皮(下)
20135307
一、给MenusOS增加time和time-asm命令
-
给MenuOS增加time和time-asm命令需要
- 更新menu代码
- 在main函数中增加menuconfig
- 增加对应的time和timeasm函数
- make rootfs
二、使用GDB跟踪系统调用内核函数sys_time
实验报告
-
分析system_call中断处理过程
- 使用gdb跟踪分析一个系统调用内核函数(您上周选择那一个系统调用),系统调用列表参见http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/syscalls/syscall_32.tbl ,推荐在实验楼Linux虚拟机环境下完成实验。
- 根据本周所学知识分析系统调用的过程,从system_call开始到iret结束之间的整个过程,并画出简要准确的流程图
-
博客内容的具体要求如下:
- 题目自拟,内容围绕系统调用system_call的处理过程进行;
- 博客内容中需要仔细分析system_call对应的汇编代码的工作过程,特别注意系统调用返回iret之前的进程调度时机等。
- 总结部分需要阐明自己对“系统调用处理过程”的理解,进一步推广到一般的中断处理过程
-
用实验楼的虚拟机打开shell,更新menu,给MenuOS增加Pid和PidAsm
cd LinuxKernel rm menu -rf git clone https://github.com/mengning/menu.git cd menu vi test.c make rootfs
-
使用gdb跟踪分析
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
gdb file linux-3.18.6/vmlinux加载调试用的符号表 target remote:1234 b start_kernel 设置断点 c b sys_getpid
- 分析内核调用汇编代码
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 restore_all_notrace: #ifdef CONFIG_X86_ESPFIX32 movl PT_EFLAGS(%esp), %eax# mix EFLAGS, SS and CS # Warning: PT_OLDSS(%esp) contains the wrong/random values if we # are returning to the kernel. # See comments in process.c:copy_thread() for details. 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# returning to user-space with LDT SS #endif restore_nocheck: RESTORE_REGS 4# skip orig_eax/error_code irq_return: INTERRUPT_RETURN
- 实验截图
- 从系统调用到中断返回的函数流程图
总结
当操作系统接收到系统调用请求后,会让处理器进入内核模式,从而执行诸如I/O操作,修改基址寄存器内容等指令,而当处理完系统调用内容后,操作系统会让处理器返回用户模式,来执行用户代码。当系统调用完成后,把控制权交回到发起调用的用户进程前,内核又会有一次调度。如果发现有优先级更高的进程或当前进程的时间片用完,那么会选择优先级更高的进程或重新选择进程执行.