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

标签(空格分隔): 20135321余佳源


余佳源 原创作品转载请注明出处 《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000


一、给MenuOS增加time和time-asm命令

1.克隆并自动编译MenuOS

    rm menu -rf //强制删除原menu文件
git clone https://github.com/mengning/menu.git //从github中克隆
cd menu
make rootfs //运行自动编译脚本,生成根文件系统,启动MenuOS

PS:实验楼环境太恶劣而且有时候会git失败,所以我选择用自己的虚拟机来实现。make rootfs的最后一步会出错,因为qemu指令不被支持,正确使用的使用qemu-system-x86_64

2.给MenuOS增加time和time-asm命令

  • 更新menu代码到最新版
  • test.c中main函数里,增加MenuConfig
  • 增加对应的两个函数:Time和TimeAsm
  • make rootfs


二、调试内核

  1. 使用gdb跟踪调试内核

    --

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

                 ------------另开一个终端------------

    gdb

    (gdb)file linux-3.18.6/vmlinux //加载符号表

    (gdb)target remote:1234 //连接

  • b sys_time:在系统调用time的位置设置断点
  • c:让MENUOS运行
  • 在MENUOS输入time就可以看到断点位置


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

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

    --
  • main.c中start_kernel函数:trap_init()
  • set_system_trap_gate(SYSCALL_VECTOR,&system_call)
    • SYSCALL_VECTOR:系统调用的中断向量
    • &system_call:汇编代码入口
  • 一执行int 0x80,系统直接跳转到system_call。

int 0x80指令与systemcall是通过中断向量联系起来的,而API和对应的sys[函数]是通过系统调用号联系起来的

trapgate函数中,涉及到了系统调用的中断向量和systemcall的汇编代码入口;一旦执行int 0x80,CPU直接跳转到system_call

  1. 系统调用——一个特殊的中断

    --
ENTRY(system_call)-->执行 0x80后的下一条指令
RING0_INT_FRAME # can't unwind into user space anyway
ASM_CLAC
pushl_cfi %eax # save orig_eax
SAVE_ALL------------------>保护现场包括系统寄存器信息
GET_THREAD_INFO(%ebp)------------->获取thread_info结构的信息
# system call tracing in operation / emulation
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)---->测试是否有系统跟踪
jnz syscall_trace_entry---->如果有系统跟踪,先执行,然后再回来
cmpl $(NR_syscalls), %eax------>比较eax中的系统调用号和最大syscall,超过则无效
jae syscall_badsys------>无效的系统调用 直接返回
syscall_call:
call *sys_call_table(,%eax,4)-------->eax传递系统调用号查找系统调用表sys_call_table中定义好的相应的系统调用
syscall_after_call:----------↓
movl %eax,PT_EAX(%esp)----->保存返回值 # store the return value
syscall_exit:
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
testl $_TIF_ALLWORK_MASK, %ecx------>判断当前的任务是否需要进程调度
jne syscall_exit_work------->未完成,则去执行这些任务
restore_all:---------->回复现场,回归用户态
TRACE_IRQS_IRET---->iret 从系统调用返回
  • 若有sys_exit_work,则进入sys_exit_work:会有一个进程调度时机。

    • work_pending -> work_notifysig,用来处理信号

      • 可能call_schedule:进程调度代码
      • 可能跳转到restore_all,恢复现场。
  • 若无sys_exit_work,就执行restore_all恢复,返回用户态。
  • INTERRUPT_RETURN <=> iret,结束。

在系统调用返回之前,可能发生进程调度,进程调度里就会出现进程上下文的切换。

进程间通信可能有信号需要处理。

可以将内核视为一系列中断指令的集合。


四、实验部分

  1. 使用gdb跟踪分析第20号系统调用内核函数:getpid

    --

先执行rm menu -rf,强制删除原有的menu文件夹,使用git命令更新menu代码至最新版。

在test.c中增加我编写的两个函数:Getpid()和asm_Getpid()

在main函数中增加两个函数的MenuConfig命令项:

make rootfs编译成功,qemu失败:改成 qemu-system-x86_64

编译运行,在MenuOS中输入help,可以查看当前所有的系统调用,分别执行Getpid asm_Getpid进行系统调用:

  1. 从system_call到iret

    --
  • system_call到iret之间的主要代码

  • 流程图


五、总结

系统调用就是特殊的一种中断

  • 保存现场

    • 在系统调用时,我们需要SAVE_ALL,用于保存系统调用时的上下文。
    • 同样,中断处理的第一步应该也要保存中断程序现场。
    • 目的:在中断处理完之后,可以返回到原来被中断的地方,在原有的运行环境下继续正确的执行下去。
  • 确定中断信息

    • 在系统调用时,我们需要将系统调用号通过eax传入,通过sys_call_table查询到调用的系统调用,然后跳转到相应的程序进行处理。
    • 同样,中断处理时系统也需要有一个中断号,通过检索中断向量表,了解中断的类型和设备。
  • 处理中断

    • 跳转到相应的中断处理程序后,对中断进行处理。
  • 返回

    • 系统调用时最后要restore_all恢复系统调用时的现场,并用iret返回用户态。
    • 同样,执行完中断处理程序,内核也要执行特定指令序列,恢复中断时现场,并使得进程回到用户态。

LINUX内核分析第五周学习总结——扒开系统调用的“三层皮”(下)的更多相关文章

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

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

  2. Linux第五周学习总结——扒开系统调用的三层皮(下

    Linux第五周学习总结--扒开系统调用的三层皮(下) 作者:刘浩晨 [原创作品转载请注明出处] <Linux内核分析>MOOC课程http://mooc.study.163.com/co ...

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

    扒开系统调用的三层皮(下) 郝智宇 无转载 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.给Men ...

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

    朱荟潼 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课http://mooc.study.163.com/course/USTC 1000029000 一.学习内容 (一 ...

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

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

  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内核分析第五周学习总结

    扒开系统调用的三层皮(下) 20135237朱国庆+ 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/UST ...

  9. 《Linux内核分析》第四周学习总结 扒开系统调用的三成皮(上)

    第四周 扒开系统调用的三层皮(上) 郝智宇 无转载 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一. ...

随机推荐

  1. Linux 小知识翻译 - 「Linux」和病毒

    据说,「Linux」系统上的病毒要远远少于Windows系统上病毒.从2种系统的普及度来看,这是很显然的, 「Linux」的使用人群很少,所以「Linux」上的病毒的扩散时,受害的范围也不大. 但是, ...

  2. Beta冲刺(2/5)(麻瓜制造者)

    今日完成任务 邓弘立:继续完成了昨天未完成的登录接口的重编码与测试. 李佳铭|:进一步完善了收藏UI 江郑: 对使用前端框架页面元素的进一步优化,基本功能进行中 刘双玉:部分图书馆租借接口修改 肖小强 ...

  3. HTML5 canvas getImageData() 方法

    下面的代码通过 getImageData() 复制画布上指定矩形的像素数据,然后通过 putImageData() 将图像数据放回画布: var c=document.getElementById(& ...

  4. Qt 编程指南 2 Hello Designer

    2 Hello Designer  ①编辑窗口部件:为窗口拖拽控件(即部件),编辑控件布局等. ②编辑信号/槽:用户在图形界面的一些动作会触发窗口或控件的信号,信号对应的处理函数就是槽函数,这种模式实 ...

  5. Java中static、final、static final的区别【转】

    说明:不一定准确,但是最快理解. final: final可以修饰:属性,方法,类,局部变量(方法中的变量) final修饰的属性的初始化可以在编译期,也可以在运行期,初始化后不能被改变. final ...

  6. 可长点心吧-sort

    sort #<algorithm> 用的时候一定是 从 第一个(你想要排序的范围内的) 到 最后一个+1 真的错了不止一次了 真的长点心吧

  7. PAT A1126 Eulerian Path (25 分)——连通图,入度

    In graph theory, an Eulerian path is a path in a graph which visits every edge exactly once. Similar ...

  8. PAT A1142 Maximal Clique (25 分)——图

    A clique is a subset of vertices of an undirected graph such that every two distinct vertices in the ...

  9. rbac组件

    创建新项目 新建一个项目untitled,注意django 版本为1.11 修改models.py,增加2个表 from django.db import models class Classes(m ...

  10. java StringBuilder和StringBuffer 用法

    可变的字符串,兄弟关系StringBuilder:效率高,安全性低StringBuffer:效率低,安全性高 StringBuilder 的常用方法的使用,StringBuffer用法一样. publ ...