zoukankan      html  css  js  c++  java
  • 《Linux内核分析》 week5作业-system call中断处理过程

     一.使用gdb跟踪分析一个系统调用内核函数

      1.在test.c文件中添加time函数与采用c语言内嵌汇编的time函数.具体实现请看下图.

      2.然后在main函数中添加MenuConfig函数,进行注册。这样当Menuos运行起来时,界面就会多出time与time-asm选项。

      3.通过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
    •  b sys_time

    gdb单步调试命令n,继续运行c,跳入函数内核s.

    二.分析system_call代码的执行过程

      当用户调用一个系统调用时,系统会自动通过int $0x80进入内核,同时通过中断向量进入system_call函数.然后开始执行system_call过程。

    490ENTRY(system_call)
    491    RING0_INT_FRAME            # can't unwind into user space anyway
    492    ASM_CLAC
    493    pushl_cfi %eax            # save orig_eax
    494    SAVE_ALL                        #保存寄存器上下文环境
    495    GET_THREAD_INFO(%ebp)           
    496                    # system call tracing in operation / emulation
    497    testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
    498    jnz syscall_trace_entry
    499    cmpl $(NR_syscalls), %eax
    500    jae syscall_badsys
    501syscall_call:
    502    call *sys_call_table(,%eax,4)  #通过eax寄存器存储的具体系统调用号来去system_call表中去执行具体的系统调用
    503syscall_after_call:
    504    movl %eax,PT_EAX(%esp)        #系统调用执行完之后用eax保存返回值
    505syscall_exit:
    506    LOCKDEP_SYS_EXIT
    507    DISABLE_INTERRUPTS(CLBR_ANY)    # make sure we don't miss an interrupt
    508                    # setting need_resched or sigpending
    509                    # between sampling and the iret
    510    TRACE_IRQS_OFF
    511    movl TI_flags(%ebp), %ecx
    512    testl $_TIF_ALLWORK_MASK, %ecx    # current->work,判断当前是否需要继续执行syscall_exit_word过程
    513    jne syscall_exit_work    #若需要,则进入syscall_exit_work过程
    514
    515restore_all:
    516    TRACE_IRQS_IRET   #恢复上下文环境 

    这段代码的总体流程就是:

    •   保存当前进程环境(SAVE_ALL)
    •   执行具体的系统调用,并保存返回值
    •   判断当前是否还需要执行其他的任务(即syscall_exit_work).
    •   恢复上下文环境。

    接下来具体看看syscall_exit_work执行了哪些具体任务

    656syscall_exit_work:
    657    testl $_TIF_WORK_SYSCALL_EXIT, %ecx
    658    jz work_pending                  #进入work_pending
    659    TRACE_IRQS_ON
    660    ENABLE_INTERRUPTS(CLBR_ANY)    # could let syscall_trace_leave() call
    661                    # schedule() instead
    662    movl %esp, %eax
    663    call syscall_trace_leave
    664    jmp resume_userspace
    665END(syscall_exit_work)

    work_pending的主要工作是判断当前进程是否有信号或者进程通信的任务来处理。

    593work_pending:
    594    testb $_TIF_NEED_RESCHED, %cl
    595    jz work_notifysig   #如果有信号处理,则进入work_notifysig过程
    596work_resched:    
    597    call schedule           #是否需要进行进程调度,如果有进程调度的任务,则进入
    598    LOCKDEP_SYS_EXIT
    599    DISABLE_INTERRUPTS(CLBR_ANY)    # make sure we don't miss an interrupt
    600                    # setting need_resched or sigpending
    601                    # between sampling and the iret
    602    TRACE_IRQS_OFF
    603    movl TI_flags(%ebp), %ecx
    604    andl $_TIF_WORK_MASK, %ecx    # is there any work to be done other
    605                    # than syscall tracing?
    606    jz restore_all                #返回进行上下文
    607    testb $_TIF_NEED_RESCHED, %cl 
    608    jnz work_resched
    609

     

    因此在进程执行完某个系统调用的过程后,在返回值之前,会检查是否进程有信号需要处理和是否有进程调度的任务需要执行。

    三.实验总结

     更加进一步地深入学习了在用户调用一个系统调用时,内核底层的执行过程。 

      

  • 相关阅读:
    USACO07FEB银牛派对
    求环总结
    NOIP2015信息传递(拓扑排序 / 并查集)
    APIO2012dispatching (左偏树)
    [编程题]山寨金闪闪 (面试题)
    【小米oj】简单直接全排列
    【小米oj】寻找归一数字
    【小米oj】dreamstart 的催促
    【小米oj】打羽毛球的小爱同学
    【小米oj】石头收藏家
  • 原文地址:https://www.cnblogs.com/sixue/p/4465961.html
Copyright © 2011-2022 走看看