《Linux内核分析》 第五节 扒开系统调用的三层皮(下)

黄胤凯   原创作品转载请注明出处   《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

 

上周说了系统调用的三层皮:xyz    system_call    sys_xyz

本周学习内容如下:

一、给MenusOS增加time和time-asm命令

  • 给MenuOS增加time和time-asm命令需要

    1. 更新menu代码
    2. 在main函数中增加menuconfig
    3. 增加对应的time和timeasm函数
    4. make rootfs

二、使用GDB跟踪系统调用内核函数sys_time

实验报告

  • 分析system_call中断处理过程

    1. 使用gdb跟踪分析一个系统调用内核函数(您上周选择那一个系统调用),系统调用列表参见http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/syscalls/syscall_32.tbl ,推荐在实验楼Linux虚拟机环境下完成实验。
    2. 根据本周所学知识分析系统调用的过程,从system_call开始到iret结束之间的整个过程,并画出简要准确的流程图
  • 博客内容的具体要求如下:

    1. 题目自拟,内容围绕系统调用system_call的处理过程进行;
    2. 博客内容中需要仔细分析system_call对应的汇编代码的工作过程,特别注意系统调用返回iret之前的进程调度时机等。
    3. 总结部分需要阐明自己对“系统调用处理过程”的理解,进一步推广到一般的中断处理过程
  • 用实验楼的虚拟机打开shell,更新menu,给MenuOS增加Pid和PidAsm

    1
    2
    3
    4
    5
    6
    cd LinuxKernel
    rm menu -rf
    git clone https://github.com/mengning/menu.git
    cd menu
    vi test.c
    make rootfs

     

  •   
  • 使用gdb跟踪分析

    1
    qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

      

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    gdb
     
    file linux-3.18.6/vmlinux加载调试用的符号表
     
    target remote:1234
     
    b start_kernel 设置断点
     
    c
     
    b sys_getpid

      

  • 分析内核调用汇编代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
  •   实验截图

   

 

 

  • 从系统调用到中断返回的函数流程图

 

posted on 2016-03-27 20:39  我是HKK  阅读(198)  评论(0)    收藏  举报

导航