zoukankan      html  css  js  c++  java
  • 2019-2020-1 20199310《Linux内核原理与分析》第六周作业

    1.问题描述

    在前面的文章中,学习了系统调用的相关理论知识,并使用库函数API和C代码中嵌入汇编代码两种方式使用getpid()系统调用。本文将内容围绕系统调用system_call的处理过程,在MenuOS中运行getpid命令,通过gdb跟踪调用time函数的过程,并分析system_call代码对应的工作过程。

    2.解决过程

    2.1 在MenuOS中运行getpid命令

    进入LinuxKernel目录,删除menu目录,然后从github上克隆一个menu。该版本中已经写了time和time_asm两个系统调用,进入menu目录,运行make rootfs对menu内文件进行编译,打开MenuOS输入help查询系统调用函数如下所示:

    在menu目录中找到test.c文件打开,写入getPid()方法调用系统调用,函数名应该避免与系统调用函数getpid()重复。

    由于test.c种通过MenuConfig()定义了调用函数名,在MenuOS中直接输入pid可以调用,获得当前进程为1,该进程也叫根进程。它负责产生其他所有用户进程。所有的进程都会被挂在这个进程下。

    2.2 gdb跟踪调用time函数的过程

    退回LinuxKernel目录,shift+ctrl+o切换横屏,然后在终端1执行如下命令:

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

    在终端2打开gdb,在start_kernel设置断点,执行如下命令:

    gdb
    file linux-3.18.6/vmlinux
    target remote:1234
    b start_kernel
    


    可以看到,MenuOS在start_kernel处暂停,继续执行后面的程序,在sys_time函数中设置断点,在MenuOS中输入time后执行gdb,执行情况如下:

    sys_time函数执行至SYSCALL_DEFINE1处,调用list,可以显示当前断点附近代码内容:

    对sys_time函数进行跟踪,最终显示系统时间:


    2.3 system_call代码对应的工作过程分析

    在system_call处设置断点,但是gdb不支持单步跟踪,MenuOS中仍停留在sys_time这个位置:

    编辑linux-3.18.6/arch/x86/kernel/entry_32.S,查看system_call函数代码:



    原因是system_call不是一个正常的函数,只是一段汇编代码的起点,内部没有严格遵守函数调用堆栈基址,不支持gdb一条一条的调试。
    分析system_call代码,系统调用的流程大致为:

    3.总结

    本文主要学习了Linux内核系统调用的过程,并通过gdb和代码分析了调用过程。一般情况下,在用户态调用time()函数时,实际上调用了系统函数sys_time(),而用户态中有一个系统调用库函数xyz(),里面通过中断向量0x80触发system_call中断服务程序入口这段汇编代码,由用户态切换到内核态。首先通过SAVE_ALL保护现场,然后通过system_call函数中调用分配表找到系统调用内核处理函数指针,调用函数后通过restore_all和INTERRUPT_RETURN(iret)恢复现场并返回系统调用到用户态结束。以上system_call调用为软中断,和其他所有中断类似,可以推广到一般的中断处理过程。

  • 相关阅读:
    C# 压缩组件介绍与入门
    《Effective C#》快速笔记(六)-
    原生JS实现简单富文本编辑器
    oracle 给表字段把VARCHAR2 换成 CLOB
    java.lang.NoClassDefFoundError: javax/servlet/ServletOutputStream
    Idea中Module is not specified解决办法
    JS用正则替换特殊字符
    对List<Map>里的map的某个属性重复的值进行处理的方法
    ……
    使用原生js 实现点击消失效果
  • 原文地址:https://www.cnblogs.com/louhao-20199310/p/11734977.html
Copyright © 2011-2022 走看看