实验五:扒开系统调用的三层皮(下)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实验五:扒开系统调用的三层皮(下)相关的知识,希望对你有一定的参考价值。
实验五:扒开系统调用的三层皮(下)
王朝宪20135114
原创作品转载请注明出处 《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)
- 进程调度中会发生中断上下文切换和进程上下文的切换,这是个连贯的过程
- 内核可以抽象成多种不同中断处理过程的集合
四、总结
从system_call开始到iret结束的过程:
int 0x80
ENTRY(System.call)
SAVE_ALL//保护现场
call *System_call_table//找到系统调用表
Syscall_after_call //推出前保存返回值
Syscall_exit(分情况讨论)
1. 当没有Syscall_exit_work时 | 2. 当有Syscall_exit_work时
restore_all //恢复现场 | work_pending
restore_all_notrace //返回到用户态 | work_resched //重新调度 work_notifysing //处理信号
iret //结束 | call schedule
| restore_all //返回系统调用
| iret //结束
以上是关于实验五:扒开系统调用的三层皮(下)的主要内容,如果未能解决你的问题,请参考以下文章