• 2018-2019-1 20189203《linux内核原理与分析》第六周作业


    第一部分

    • 给Menu OS增加命令
      输入命令
    git clone http://github.com/mengning/menu.git
    make rootfs```
    - 查看增加的time 和time_asm命令
     ![](https://img2018.cnblogs.com/blog/1504872/201811/1504872-20181118181353017-941660215.png)
    ![](https://img2018.cnblogs.com/blog/1504872/201811/1504872-20181118181400092-349504569.png)
    # 第二部分 实验(使用gdb跟踪调用内核函数)
    ## 1.操作
    我选用的是上周使用的rename,首先编辑menu中的test.c文件,给MenuOS增加rename和rename_asm命令,如图
     ![](https://img2018.cnblogs.com/blog/1504872/201811/1504872-20181118181407466-1147089241.png)
    运行可以看到MenuOS中新增两条命令:
     ![](https://img2018.cnblogs.com/blog/1504872/201811/1504872-20181118181414223-761815648.png)
    使用gdb跟踪sys_rename,在sys_rename处设置断点,在MenuOS中执行rename命令,停在SyS_rename处,然后单步执行。 
    ![](https://img2018.cnblogs.com/blog/1504872/201811/1504872-20181118181744253-38164919.png)
    ## 2.系统调用处理过程分析。
    系统调用机制的初始化是在 start_kernel 中的 trap_init()里进行的,如下程序,SYSCALL_VECTOR系统调用的中断向量,&system_call是 system_call的入口,一旦执行int 0x80,CPU就会立即跳转到此处。
    ``` #ifdef CONFIG_X86_32
       set_system_trap_gate(SYSCALL_VECTOR, &system_call); 
       set_bit(SYSCALL_VECTOR, used_vectors);
    #endif
    

    将system_call代码简化并加以分析:

         RING0_INT_FRAME    
         ASM_CLAC        
         pushl_cfi %eax            //保存系统调用号;
         SAVE_ALL                  //将用到的所有CPU寄存器保存到栈中
         GET_THREAD_INFO(%ebp)     //ebp用于存放当前进程thread_info结构的地址
         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) //对照系统调用号在系统调用表中寻找相应服务例程
         movl %eax,PT_EAX(%esp)        //保存返回值到栈中
     syscall_exit:  
         testl $_TIF_ALLWORK_MASK, %ecx   //检查是否需要处理信号
         jne syscall_exit_work        //需要,进入 syscall_exit_work,这里是最常见的系统调度时机
     restore_all: 
         TRACE_IRQS_IRET              //恢复现场 
     irq_return:
         INTERRUPT_RETURN             //iret
    

    从entry(system_call)开始看这段代码,根据系统调用号来查sys_call_table表中的位置,调用系统调用对应的系统函数,在syscall_exit里面判断当前的任务是否需要处理syscall_exit_work,进入syscall_exit_work,这是最常见的进程调度时机点。
    System_call流程图如下图所示:

    如图,流程图中涉及syscall_exit_work内部处理的一些关键点,大致的过程是syscall_exit_work需要跳转到work_pending,里面有work_notifysig处理信号。还有work_resched是需要重新调度的,这里是进程调度的时机点call schedule,调度完后之后就会跳转到restore_all,恢复现场返回系统调用到用户态。

  • 相关阅读:
    在Window上Vim包的选择
    如何在apache官网下载将将jar包
    hdu1870
    hdu1710(Binary Tree Traversals)
    poj 3252 Round Numbers 【推导·排列组合】
    3905
    Find them, Catch them
    Argus
    Team Queue
    Terrible Sets
  • 原文地址:https://www.cnblogs.com/23du/p/9978734.html
Copyright © 2020-2023  润新知