20135103王海宁

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

这周的实验在上周实验四的基础上,进一步的操作:
1.将系统调用函数getpid命令加入menuos中
2.通过gdb跟踪sys_getpid系统调用执行的完整过程

步骤:给MenuOS增加getpid和getpid-asm命令
0)更新menu代码到最新版
1)在main函数中增加MenuConfig
2)增加对应的getpid函数和getpid-asm函数
3)make rootfs

进入实验楼环境后,敲入如下命令:

  1. <span style="font-size:14px;">cd LinuxKernel
  2. cd menu
  3. vi test.c</span>

进入test.c源程序后添加如下代码:

  1. <span style="font-size:14px;">//添加两个函数,别忘了加头文件#include <unistd.h>
  2. int main() {
  3. pid_t tt;
  4. asm volatile (
  5. "movl $0x20, %%eax\n\t"
  6. "int $0x80\n\t"
  7. "movl %%eax, %0\n\t"
  8. :"=m"(tt)
  9. );
  10. printf("%u\n", tt);
  11. return 0;
  12. }
  13. int main() {
  14. pid_t tt;
  15. tt = getpid();
  16. printf("%u\n", tt);
  17. return 0;
  18. }</span>
  1. <span style="font-size:14px;">//然后在main函数中添加
  2. MenuConfig("time","Show System Time",Time);
  3. MenuConfig("time-asm","Show System Time(asm)",TimeAsm);</span>

代码添加完成后make rootfs重新编译,此时系统会自动启动。如下图:

下面用gdb跟踪sys_getpid执行的过程:
1.执行以下命令开启内核的调试功能 qemu -kernel linux-3.18.6/arch/x86/boot/bz/Image -initrd rootfs.img -s -S,此时系统处于停止状态
2.再打开一个命令行窗口输入gdb,在gdb命令提示符下依次输入file linux-3.18.6/vmlinux, target remote:1234命令连接内核并跟踪调试
3.设置断点break sys_getpid, 接着continue开始运行,此时menuOS从stopped状态开始执行。在menu程序的提示符下输入who,程序执行到断点时暂停,此时gdb窗口显示程序断在sys_getpid处
4.接着使用gdb单步执行命令。next:不进入函数体的单步执行;step:进入函数体的单步执行;finish:进入函数体后退回调用函数

分析
中断相关的初始化代码是通过linux-3.18.6/init/main.c文件中的start_kernel函数里的trap_init()初始化的。执行int $0x80指令后内核开始执行system_call入口处开始的代码,位于entry_32.S汇编文件中。
下面分析system_call汇编代码:

1.SAVE ALL                                // 保存调用前寄存器相关的信息

2.call *sys_call_table(,%eax,4)   // 执行系统调用对应的处理函数,eax存放系统调用号

// 通过linux-3.18.6/arch/x86/syscalls/syscall_32.tbl找到系统调用号对应处理函数

3.movl %eax,PT_EAX(%esp)     // 保存系统调用处理函数返回值到exa

4. testl $_TIF_ALLWORK_MASK, %ecx    # current->work
    jne syscall_exit_work  
                                                   // 这两句检查调用退出前是否有其他工作要处理,如有则跳到syscall_exit_work处继续处理,以下是syscall_exit_work相关代码:
syscall_exit_work:
    testl $_TIF_WORK_SYSCALL_EXIT, %ecx    // 测试是否退出前还有工作要处理,如有则跳到work_pending
    jz work_pending           
    TRACE_IRQS_ON
    ENABLE_INTERRUPTS(CLBR_ANY)    # could let syscall_trace_leave() call
                    # schedule() instead
    movl %esp, %eax
    call syscall_trace_leave
    jmp resume_userspace
END(syscall_exit_work)

5.下面是work_pending的相关代码,在注释中解释相关内容
work_pending:
    testb $_TIF_NEED_RESCHED, %cl       // 是否有要继续调度的相关信号
    jz work_notifysig      #跳转到处理信号相关的代码处
work_resched:
    call schedule                                         // 时间调度,进程调度的时机在这里处理
    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
    andl $_TIF_WORK_MASK, %ecx    # is there any work to be done other  // 是否有其他工作要处理
                                                          # than syscall tracing?
    jz restore_all                // 如果没有则恢复中断上下文,即恢复进入之前保存的寄存器内容
    testb $_TIF_NEED_RESCHED, %cl
    jnz work_resched

work_notifysig:                # deal with pending signals and    // 处理相关信号代码
                                      # notify-resume requests
#ifdef CONFIG_VM86
    testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
    movl %esp, %eax
    jne work_notifysig_v86        # returning to kernel-space or
                                              # vm86-space
1:
#else
    movl %esp, %eax
#endif
    TRACE_IRQS_ON
    ENABLE_INTERRUPTS(CLBR_NONE)
    movb PT_CS(%esp), %bl
    andb $SEGMENT_RPL_MASK, %bl
    cmpb $USER_RPL, %bl
    jb resume_kernel
    xorl %edx, %edx
    call do_notify_resume
    jmp resume_userspace

#ifdef CONFIG_VM86
    ALIGN
work_notifysig_v86:
    pushl_cfi %ecx               # save ti_flags for do_notify_resume
    call save_v86_state        # %eax contains pt_regs pointer
    popl_cfi %ecx
    movl %eax, %esp
    jmp 1b
#endif
END(work_pending)

6. restore_all:
       RESTORE_INT_REGS     // 中断返回之前恢复相关寄存器的内容

7.     irq_return:
      INTERRUPT_RETURN     // 这两行代码主要是返回到用户态

总结
1.执行int 0x80指令后系统从用户态进入内核态,跳到system_call()函数处执行相应服务进程。在此过程中内核先保存中断环境,然后执行系统调用函数。
2.system_call()函数通过系统调用号查找系统调用表sys_cal_table来查找具体系统调用服务进程。
3.执行完系统调用后,iret之前,内核会检查是否有新的中断产生、是否需要进程切换、是否学要处理其它进程发送过来的信号等。 
4.内核是处理各种系统调用的中断集合,通过中断机制实现进程上下文的切换,通过系统调用管理整个计算机软硬件资源。
5.如没有新的中断,restore保存的中断环境并返回用户态完成一个系统调用过程。

《Linux内核分析》第五周的更多相关文章

  1. LINUX内核分析第五周学习总结——扒开系统调用的“三层皮”(下)

    LINUX内核分析第五周学习总结--扒开系统调用的"三层皮"(下) 标签(空格分隔): 20135321余佳源 余佳源 原创作品转载请注明出处 <Linux内核分析>M ...

  2. LINUX内核分析第五周学习总结——扒开应用系统的三层皮(下)

    LINUX内核分析第五周学习总结——扒开应用系统的三层皮(下) 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cou ...

  3. 20135327郭皓--Linux内核分析第五周 扒开系统调用的三层皮(下)

    Linux内核分析第五周 扒开系统调用的三层皮(下) 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/U ...

  4. linux内核分析第五周学习笔记

    linux内核分析第五周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...

  5. Linux内核分析第五周——扒开系统调用的“三层皮”(下)

    Linux内核分析第五周--扒开系统调用的"三层皮"(下) 李雪琦+原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.1 ...

  6. Linux内核分析第五周学习总结——分析system_call中断处理过程

    Linux内核分析第五周学习总结--分析system_call中断处理过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  7. Linux内核分析——第五周学习笔记

    第五周 扒开系统调用的“三层皮”(下) 一.知识点总结 (一)给MenuOS增加time和time-asm命令 在实验楼中,首先 强制删除menu (rm menu -rf) 重新克隆一个新版本的me ...

  8. Linux内核分析第五周学习总结:扒开系统调用的三层皮(下)

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.给MenuO ...

  9. linux内核分析 第五周

    一.实验相关 1.下载老师最新的menu文件,并在其中添加上周所编写的代码,并运行 下载 添加 运行 2.gdb调试跟踪 gdb设置跟踪文件(先进入linux-3.18.6所在的文件) gdb设置断点 ...

  10. “Linux内核分析”第五周报告

    张文俊+ 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 学习总结 1.给M ...

随机推荐

  1. 【Nginx】开启 gzip和缓存

    Nginx 开启 gzip和缓存 时间:2016-09-23 16:42:37 nginx 是一个高性能的 Web 服务器,之前也写过一些关于 nginx 的文章.为了提高博客的响应速度,可以从设置 ...

  2. [luogu2172] 部落战争

    题面 ​ 我们可以将'.'抽象为一个可以通过的点, 将'x'抽象为一个不可通过的点. ​ 那么题意便可以转化为: 一条路径可以看做从任意一个没有到达过的可通过的点出发到任意一个其他的可以通过却没有被到 ...

  3. JAVA框架:hibernate(四)

    一.绑定本地session 原理:之前connection实现事务一个道理,2种方法:1.变量下传.2.因为servlet是单线程,和本地当前线程绑定. 配置: 1)配置核心配置文件hibernate ...

  4. css 常用单位

    em: 相对于应用在当前元素的字体尺寸,1em 等于当前的字体尺寸,2em 等于当前字体尺寸的两倍,一般浏览器字体大小默认为16px,则2em == 32px: W3原文:font size of t ...

  5. A - Zebras

    Oleg writes down the history of the days he lived. For each day he decides if it was good or bad. Ol ...

  6. 使用Highcharts生成折线图_at last

    //数据库数据的读取,读取数据后数据格式的转换,还有highchart数据源的配置,伤透了脑筋. anyway,最终开张了.哈哈! 数据库连接:conn_orcale.php <?php $db ...

  7. BZOJ2427: [HAOI2010]软件安装 tarjan+树形背包

    分析: 一开始我以为是裸的树形背包...之后被告知这东西...可能有环...什么!有环! 有环就搞掉就就可以了...tarjan缩点...建图记得建立从i到d[i]之后跑tarjan,因为这样才能判断 ...

  8. 【LeeCode23】Merge k Sorted Lists★★★

    1.题目描述: 2.解题思路: 题意:将K个已经排序的链表合并成一个排序的链表,分析并描述所用算法的复杂度. 方法一:基于“二分”思想的归并排序.本文用非递归和递归两种方法实现. (1)非递归:归并排 ...

  9. SEO优化上首页之搜索引擎排名规则

    搜索引擎建立索引的网页数以万亿计,用户搜索的关键词也是海量,如果每个用户提交搜索请求后,搜索引擎都去数以万亿的索引中重新排名网页,效率将非常低下.根据2-8法则,80%是查询是集中在相同的20%内容上 ...

  10. Exp5:MSF基础应用

    Exp5:MSF基础应用 一.基础问题回答 (1)用自己的话解释什么是 exploit , payload , encode. exploit: 设相当于利用漏洞偷偷打开的管道,将做好的木马病毒等顺利 ...