(一)给MenuOs增加time和time-asm命令

  • 更新menu代码到最新版
  • 在main函数中增加MenuConfig
  • 增加对应的Ttime和TimeAsm函数
  • make rootfs

(二)使用gdb跟踪系统调用内核函数sys_time

1.sys_time返回后进入汇编代码处理gdb无法继续跟踪

2.执行0x80之后执行system_call对应的代码

3.entry32.s中system_call 不是一个函数,只是一段汇编代码的起点,gdb不能跟踪它。

(三)系统调用在内核代码中的处理过程

1.系统调用在内核代码中的工作机制和初始化

  • 系统调用的工作机制:

通知内核的机制是靠软中断实现的:在x86系统上预定义的软中断是中断号128,通过int$0x80指令触发该中断,这条指令会触发一个异常导致系统切换到内核态并执行128号异常处理程序,即system_call().

  • 系统调用机制的初始化:

2.简化后便于理解的system_call伪代码

1.系统调用其实就是一个特殊的中断

2.伪代码如下:

3.代码分析:

  1. # system call handler stub
  2. ENTRY(system_call) #系统调用处理入口(内核态)
  3. RING0_INT_FRAME # can't unwind into user space anyway
  4. ASM_CLAC
  5. pushl_cfi %eax # save orig_eax #保存eax,也就是调用号
  6. SAVE_ALL # 保存寄存器
  7. GET_THREAD_INFO(%ebp) # 获取thread_info结构中ebp的值
  8. # system call tracing in operation / emulation
  9. testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) # 检测是否由系统跟踪
  10. jnz syscall_trace_entry # 有系统跟踪则先去执行
  11. cmpl $(NR_syscalls), %eax # 比较输入的系统调用号 是否大于 最大的系统调用号
  12. jae syscall_badsys # 大于 则无效,退出
  13. syscall_call:
  14. call *sys_call_table(,%eax,4) # 在系统调用表中的调用相应的服务例程,eax为调用号,4字节对齐
  15. syscall_after_call:
  16. movl %eax,PT_EAX(%esp) # store the return value # 保存返回值
  17. syscall_exit:
  18. LOCKDEP_SYS_EXIT # 用于调试,只有开启调试后才会检测系统调用深度
  19. DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
  20. # setting need_resched or sigpending
  21. # between sampling and the iret
  22. TRACE_IRQS_OFF # 关闭中断跟踪
  23. movl TI_flags(%ebp), %ecx # 检测是否还有其他任务
  24. testl $_TIF_ALLWORK_MASK, %ecx # current->work
  25. jne syscall_exit_work
  26. syscall_exit_work:
  27. testl $_TIF_WORK_SYSCALL_EXIT, %ecx
  28. jz work_pending # 测试是否退出前还有工作要处理,如果有的话跳转到work_pending
  29. TRACE_IRQS_ON # 开启系统中断跟踪
  30. ENABLE_INTERRUPTS(CLBR_ANY) # could let syscall_trace_leave() call
  31. # 允许中断 # schedule() instead
  32. movl %esp, %eax
  33. call syscall_trace_leave
  34. jmp resume_userspace # 恢复用户空间
  35. END(syscall_exit_work)
  36. work_pending:
  37. testb $_TIF_NEED_RESCHED, %cl # 是否有需要继续调度的相关信号
  38. jz work_notifysig # 跳转到处理信号相关的代码处
  39. work_resched:
  40. call schedule # 时间调度, 进程调度的时机在这里处理
  41. LOCKDEP_SYS_EXIT
  42. DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
  43. # setting need_resched or sigpending
  44. # between sampling and the iret
  45. TRACE_IRQS_OFF
  46. movl TI_flags(%ebp), %ecx
  47. andl $_TIF_WORK_MASK, %ecx # is there any work to be done other 是否还有其他工作要处理
  48. # than syscall tracing?
  49. jz restore_all #如果没有的话就恢复中断上下文,也就是恢复进入之前保存的寄存器相关内容
  50. testb $_TIF_NEED_RESCHED, %cl
  51. jnz work_resched
  52. work_notifysig: # deal with pending signals and
  53. # notify-resume requests
  54. #ifdef CONFIG_VM86
  55. testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
  56. movl %esp, %eax
  57. jne work_notifysig_v86 # returning to kernel-space or
  58. # vm86-space
  59. restore_all:
  60. TRACE_IRQS_IRET # 恢复中断跟踪
  61. restore_all_notrace:
  62. #ifdef CONFIG_X86_ESPFIX32
  63. movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
  64. # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
  65. # are returning to the kernel.
  66. # See comments in process.c:copy_thread() for details.
  67. movb PT_OLDSS(%esp), %ah
  68. movb PT_CS(%esp), %al
  69. andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
  70. cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
  71. CFI_REMEMBER_STATE
  72. je ldt_ss # returning to user-space with LDT SS
  73. #endif
  74. restore_nocheck:
  75. RESTORE_REGS 4 # skip orig_eax/error_code
  76. irq_return:
  77. INTERRUPT_RETURN
    4.流程图:

  • 在系统调用返回之前,可能发生进程调度,进程调度里就会出现进程上下文的切换
  • 进程间通信可能有信号需要处理

Linux内核分析 笔记五 扒开系统调用的三层皮(下) ——by王玥的更多相关文章

  1. LINUX内核分析第四周——扒开系统调用的三层皮

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

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

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

  3. linux内核分析 第四周 扒开系统调用的三层皮(上)

    一.用户态.内核态和中断处理过程 系统调用是用户通过库函数方式:库函数帮我们把系统调用封装起来. 内核态:高级别执行,可以使用特权指令,访问任意的物理地址. 用户态:低级别执行,代码范围受到限制. C ...

  4. #Linux第四周学习总结——扒开系统调用的三层皮(上)

    Linux第四周学习总结--扒开系统调用的三层皮(上) 一.用户态.内核态和中断 系统调用通过库函数. 1.用户态和内核态 区分(不同的指令执行级别): 用户态:在相应的低执行状态下,代码的掌控范围受 ...

  5. Linux内核及分析 第四周 扒开系统调用的三层皮(上)

    实验过程 选择20号系统调用getpid(取得进程识别码) 在网上查询getpid函数的C语言代码以及其嵌入式汇编语句 C语言代码: #include <stdio.h> #include ...

  6. 20135337朱荟潼 Linux第四周学习总结——扒开系统调用的三层皮(上)

    朱荟潼 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课http://mooc.study.163.com/course/USTC 1000029000 知识点梳理 一.用 ...

  7. Linux内核分析——第五章 系统调用

    第五章 系统调用 5.1 与内核通信 1.系统调用在用户空间进程和硬件设备之间添加了一个中间层,该层主要作用有三个: (1)为用户空间提供了一种硬件的抽象接口 (2)系统调用保证了系统的稳定和安全 ( ...

  8. 《Linux内核分析》第五周笔记 扒开系统调用的三层皮(下)

    扒开系统调用的三层皮(下) 一.给menuOS增加time和time-asm 通过内核调试系统调用.将上次做的实验加入到menusOS,变成menusOS里面的两个命令. 1 int Getpid(i ...

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

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

随机推荐

  1. 团队项目管理:Github项目误删恢复记录

    参考: 准备更换git托管,如何迁移原git仓库 Github项目误删恢复记录 今天正常上线打卡,发现组织的线上Github仓库被误删了..本来是一场悲剧,所幸在本地的垃圾箱中翻出了还没有删除的本地仓 ...

  2. CF848C:Goodbye Souvenir(CDQ分治)

    Description 给定长度为$n$的数组, 定义数字$X$在$[l,r]$内的值为数字$X$在$[l,r]$内最后一次出现位置的下标减去第一次出现位置的下标给定$m$次询问, 每次询问有三个整数 ...

  3. oracle Lob对象空间回收测试

    备注:转自网络 SQL> create table t(time date,text clob);SQL> begin for i in 1 .. 10000 loop insert in ...

  4. Qt 编程指南 9 软件打包

    Qt 官方开发环境使用的动态链接库方式,在发布生成的exe程序时,需要复制一大堆 dll,如果自己去复制dll,很可能丢三落四,导致exe在别的电脑 里无法正常运行.因此 Qt 官方开发环境里自带了一 ...

  5. PAT A1013 Battle Over Cities (25 分)——图遍历,联通块个数

    It is vitally important to have all the cities connected by highways in a war. If a city is occupied ...

  6. kubernetes中infra容器的理解

    1. infra容器和用户容器的关系 1.1 pause 是k8s的基础设施的一部分,pod中其他容器通过pause容器跟其他pod进行通信. 1.2 pod中其他容器跟pause容器共享命名空间1. ...

  7. tiled卷积神经网络(tiled CNN)

    这个结构是10年Quoc V.Le等人提出的,这里的tiled,按照 Lecun的解释是Locally-connect non shared.即是局部连接,而且不是共享的,这是针对于权重来说的.本文翻 ...

  8. java使用POI读取excel报表

    留此作为记录 package com.demo; import java.io.FileInputStream; import java.util.Iterator; import org.apach ...

  9. FileShare枚举的使用(文件读写锁) - (转载)

    开发过程中,我们往往需要大量与文件交互,但往往会出现很多令人措手不及的意外,所以对普通的C#文件操作做了一次总结,问题大部分如下: 写入一些内容到某个文件中,在另一个进程/线程/后续操作中要读取文件内 ...

  10. Django框架知识点整理

    1.安装django, pip install django 或者是通过 “==”符号指定版本号. 2.创建一个Django项目: django-admin createproject project ...