Linux内核分析第五周 扒开系统调用的三层皮(下) (20135304 刘世鹏)
2016-03-27 21:20
351 查看
作者:刘世鹏20135304 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
一、给MenuOS增加time和time-asm命令
1. 通过内核的方式(跟踪调试系统调用)来理解并使用系统调用。rm menu -rf //强制删除当前menu git clone http://github.com/mengning/menu.git //重新克隆新版本的menu cd menu ls make rootfs //rootfs是事先写好的一个脚本,自动编译自动生成根文件系统,同时自动启动MenuOS
2. 将上周选择的系统调用添加到MenuOS中
vi test.c //进入test.c文件 添加新功能 make rootfs //编译
3. 给MenuOS增加time和time_asm命令的步骤:
更新menu代码到最新版
test.c中main函数里,增加MenuConfig()
增加对应的Time函数和TimeAsm函数
make rootfs
二、使用gdb跟踪系统调用内核函数sys_time
qemu -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 //连接到需要调试的MenuOS (gdb)b start_kernel //设置断点 (gdb)c //执行,可见程序在start_kernel处停下 list //可查看start_kernel的代码 (gdb)b sys_time //sys_time是13号系统调用对应的内核处理函数,在该函数处设置断点 (gdb)c //如果这里一直按n单步执行,会进入schedule函数。sys_time返回后进入汇编代码处理,gdb无法继续进行追踪
执行int 0x80后执行system call对应的代码(system call不是函数,是一段特殊的汇编代码,gdb还不能进行跟踪)。
三、系统调用在内核代码中的处理过程
1. 系统调用在内核代码中的工作机制和初始化
int 0x80——>system call:通过中断向量匹配system call——>sys_xyz():通过系统调用号匹配
1.1 系统调用机制的初始化
一旦执行int 0x80后立刻跳转到system_call执行
2. 理解的system_call伪代码(总结上有流程)
int 0x80后的下一条指令从此处的ENTRY(system_call)开始系统调用返回之前可能会发生进程调度(call schedule)
当前进程可能有信号需要处理(work_notifysig)
进程调度中会发生中断上下文切换和进程上下文的切换,这是个连贯的过程
内核可以抽象成多种不同中断处理过程的集合
实验
在main函数中增加MenuConfig和详细函数![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/02/d1836f6a02dba955e424e86f2eeb1559.png)
Make rootfs
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/02/9ce4bc5e7171d8161a467be7881ed220.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/02/da5bfe6b861761b20c5095cc56b90f69.png)
设置断点
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/02/0c73cc651ed354f9aa23f021c6f6e2d0.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/02/dd2c20d0dd5ab4e310942aa46fadf838.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/02/25975133be5840bdd299dafb0ae782d5.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/02/1e448ac318f8c7c7497ff42e575f3050.png)
进行单步调试
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/02/ba74a41aac324987ba3305a948776a15.png)
系统调用在内核代码中的处理过程
main.c中start_kernel函数:trap_init()trap_gate函数中,涉及到了系统调用的中断向量和system_call的汇编代码入口
SYSCALL_VECTOR:系统调用的中断向量
&system_call:汇编代码入口
执行int 0x80,系统直接跳转到system_call
system_call到iret之间的主要代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
SAVE_ALL //保存现场 call *sys_call_table(,%eax,4) //调用了系统调度处理函数,eax存的是系统调用号,是实际的系统调度程序。 sys_call_table //系统调用分派表 syscall_after_all//保存返回值 sys_exit_work //详见解释 restore all //恢复现场(因为系统调用也是一种特殊的“中断”) INTERRUPT RETURN //也就是iret,系统调用到此结束
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
对sys_exit_work的解释:
若有sys_exit_work,则进入sys_exit_work:会有一个进程调度时机。
work_pending -> work_notifysig,用来处理信号
可能call schedule:进程调度代码
可能跳转到restore_all,恢复现场。
若无sys_exit_work,就执行restore_all恢复,返回用户态。
相关文章推荐
- linux内核设计与实现 进程管理 访问子进程的方法详解
- Linux内核分析实验五
- 《Linux内核设计与实现》——第18章(调试)
- Linux学习笔记_常用命令2
- linux内核分析第五周学习笔记
- Linux启动流程概述
- Linux内核协议栈(8)IO复用select函数
- linux权限之su和sudo的区别
- Linux内核协议栈(7)listen函数分析
- Linux磁盘及文件系统管理
- Linux磁盘及文件系统管理
- Linux下DHCP服务器配置与应用
- Linux进程管理工具top/htop/glances/dstat的使用
- Linux文件系统管理之一(文件权限管理)
- CentOS6 编译安装python 3.5
- Linux学习笔记——切换并取代用户身份命令——su
- 《Linux内核设计与实现》——第5章(系统调用)
- 《Linux内核分析》 第五节 扒开系统调用的三层皮(下)
- Linux内核分析——系统调用(下)
- Linux开发环境搭建 一 (Ubuntu安装的方式,如何选择?)