扒开系统调用的三层皮(下)

Posted on 2016-03-24 14:43  20135131张潇月  阅读(244)  评论(0编辑  收藏  举报

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

上周是从用户态来看系统调用,这周是从内核方面来看这个问题。

给MenuOS增加新的系统调用

首先删除当前前的menu,重新克隆一个新版本的menu

Makefile其实就是一个脚本,用make rootfs可以自动编译生成根文件系统,还可以自动启动起来MenuOS

可已很容易的看到我们的MenuOS里增加了我们上节课用的time和time-asm

使用gdb跟踪系统调用

首先回到LinuxKernel

cd..  #返回上一级

用大小S来调试

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

水平分割一下,启动gdb。把3.18的内核带的符号表加载进来。我们连接到我们需要调试的MenuOS里。在start_kernel设置断点,按c会发现,运行在start_kernel那里停止

list可以查看start_kernel这段代码

在time设立设置断点。b sys_time

如果我们执行time命令的话,会停在sys_time这个位置

输入list可以查看内部代码,如果这里一直按s开单步执行,后面一直按n会进入schedule函数。

sys_time返回后进入汇编代码处理gdb无法继续追踪。

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

tips:进程调度的时机对于我们理解系统的运行十分关键

系统调用的初始化:

trap_init()里边有个set_system_trap_gate和system_call,系统调用的中断向量和system_call汇编代码的入口

这之后一旦执行int 0x80 CPU就直接跳转到system_call的位置来执行,就是kernel、entry_32.s

ENTRY(system_call)这个指令就是执行int 0x80后的下一条指令。这一段代码就是系统调用的执行过程,也是中断的过程,也存在保护现场和恢复现场。

sys_call_table就是系统调用定义的系统调用表,eax寄存器用来传递系统调用号;

syscall_after_call需要先保存返回值,在退出之前,如果没有syscall_exit_work,就restore_all就返回用户态;如果有就执行work_pending,其中包含work_notifysig,是处理信号的;work_resched,是处理重新调度的,如果需要就call schedule,jump跳出返回系统调用。

流程图

Copyright © 2024 20135131张潇月
Powered by .NET 8.0 on Kubernetes