20135201李辰希 《Linux内核分析》第五周 扒开系统调用的“三层皮”(下)
2016-03-26 16:18
274 查看
李辰希 原创作品转载请注明出处 《Linux内核分析》
MOOC课程http://mooc.study.163.com/course/USTC-100002900
首先,强制删除当前的menu
克隆一个新的menu
进入menu之后,输入make rootfs,就可以自动编译
输入help,可以发现系统支持更多的命令:
help
version
quit
time
time-asm
那么,time和time-asm是如何实现的呢?
进入test.c之后,查看main函数。与之相关的只有两条语句:
menuconfig("time","Show system Time",Time);
menuconfig("time-asm","Show system Time",Time(asm));
6.给MenuOS增加time和time_asm命令的步骤:
更新menu代码到最新版
test.c中main函数里,增加MenuConfig()
增加对应的Time函数和TimeAsm函数
make rootfs
启动gdb
)
加载debug版本内核并连接到target地址
)
为处理time函数的系统调用systime设置断点之后,在menuOS中执行time。发现系统停在systime处。继续按n单步执行,会进入schedule函数。
sys_time返回之后进入汇编代码处理,gdb无法继续跟踪
如果在syscall设置断点(entry32.S),然后输入c之后,发现是不会在sys_call处停下来的(因为这里是一处系统调用函数而不是正常函数)
代码如下:
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 //连接
b sys_time:在系统调用time的位置设置断点
c:继续执行,停在断点处
n/s:单步运行,s进入函数,n不进入
理解system_call到iret之间的主要代码
系统调用返回前可能进行进程调用,里面会发生进程上下文的切换。
[/code]
系统调用返回之前可能会发生进程调度(call schedule)
当前进程可能有信号需要处理(work_notifysig)
进程调度中会发生中断上下文切换和进程上下文的切换,这是个连贯的过程
内核可以抽象成多种不同中断处理过程的集合
syscall_call:调用了系统调用处理函数
restore all:恢复现场(因为系统调用处理函数也算是一种特殊的“中断”)
syscallexitwork:如3.中所述
INTERRUPT RETURN:也就是iret,系统调用到此结束
MOOC课程http://mooc.study.163.com/course/USTC-100002900
一.给MenusOS增加time和time-asm命令
1.操作步骤
进入实验楼首先,强制删除当前的menu
克隆一个新的menu
进入menu之后,输入make rootfs,就可以自动编译
输入help,可以发现系统支持更多的命令:
help
version
quit
time
time-asm
那么,time和time-asm是如何实现的呢?
进入test.c之后,查看main函数。与之相关的只有两条语句:
menuconfig("time","Show system Time",Time);
menuconfig("time-asm","Show system Time",Time(asm));
6.给MenuOS增加time和time_asm命令的步骤:
更新menu代码到最新版
test.c中main函数里,增加MenuConfig()
增加对应的Time函数和TimeAsm函数
make rootfs
二.使用gdb跟踪系统调用内核函数sys_time
1.操作步骤
进入内核,冻结启动qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
启动gdb
)
加载debug版本内核并连接到target地址
)
为处理time函数的系统调用systime设置断点之后,在menuOS中执行time。发现系统停在systime处。继续按n单步执行,会进入schedule函数。
sys_time返回之后进入汇编代码处理,gdb无法继续跟踪
如果在syscall设置断点(entry32.S),然后输入c之后,发现是不会在sys_call处停下来的(因为这里是一处系统调用函数而不是正常函数)
代码如下:
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 //连接
b sys_time:在系统调用time的位置设置断点
c:继续执行,停在断点处
n/s:单步运行,s进入函数,n不进入
理解system_call到iret之间的主要代码
系统调用返回前可能进行进程调用,里面会发生进程上下文的切换。
从系统调用入口开始:ENTRY(system_call) SAVE_ALL //保存现场 system_call: call *system_call_table(,%eax,4) //调用了系统调用处理函数,有系统调用号eax中,是实际的系统调用处理程序。 当前任务syscall_exit_work里面有work_pending里面有 work_notifysig //处理pending信号,不用管 重要的是work_resched:call schedule //决定了进程调度的代码,调用完会跳转到restore_all restore_all //恢复现场 INTERRUPT_RETURN //irp_return宏,中断处理过程在这结束
[/code]
三、系统调用在内核代码中的处理过程
1.int 0x80指令与systemcall是通过中断向量联系起来的,而API和对应的sys[函数]是通过系统调用号联系起来的
2.系统调用机制的初始化
trapgate函数中,涉及到了系统调用的中断向量和systemcall的汇编代码入口;一旦执行int 0x80,CPU直接跳转到system_call3.简化后便于理解的system_call伪代码
int 0x80后的下一条指令从此处的ENTRY(system_call)开始系统调用返回之前可能会发生进程调度(call schedule)
当前进程可能有信号需要处理(work_notifysig)
进程调度中会发生中断上下文切换和进程上下文的切换,这是个连贯的过程
内核可以抽象成多种不同中断处理过程的集合
4.简单浏览system_call到iret之间的主要代码
SAVE_ALL:保存现场syscall_call:调用了系统调用处理函数
restore all:恢复现场(因为系统调用处理函数也算是一种特殊的“中断”)
syscallexitwork:如3.中所述
INTERRUPT RETURN:也就是iret,系统调用到此结束
四、总结
阐明自己对“系统调用处理过程”的理解。
系统调用是一种特殊的中断。它是写一个函数,它需要用到内核中的代码,但这部分代码我没有办法直接访问,所以,我通过系统调用,它说它帮我去让内核执行我想执行的代码,把最后的结果告诉我。这时,我作为用户就是什么都不知道了,等着系统调用来告诉我结果。系统调用,它先通过sys_ call这个函数和内核沟通,说我想用一下你的sys_ xxx功能,请你把这个功能执行的结果告诉我。内核很快就去自己的内部,执行sys_ xxx的功能,执行完了之后,内核告诉了系统调用,这个函数的执行结果。最后系统调用就通过iret指令将结果信息反馈给了用户。这样,用户就完美的在请求系统调用帮助后,轻松的解决了问题。相关文章推荐
- linux命令: touch, mkdir, cp, mv, rm
- VirtualBox network / study environment setup for RHEL
- Linux asm系统调用:32位和64位的区别
- 用pyenv解决在centos7下多版本python共存问题
- Kali linux 2 使用 Burpsuite 1.6.38
- Linux 版本查询
- Linux上find命令详解
- Linux下Samba的配置
- Linux USB 驱动开发(三)—— 编写USB 驱动程序
- Win7下CentOS7安装指南
- Linux各发行版配置总结
- linux kernel的中断子系统之(八):softirq
- linux内核启动以及文件系统的加载过程
- linux C内存泄露检测实现及内存泄露检测的一般方法
- linux文件系统简介
- Linux常用命令个人总结(持续修改)
- linux第五章笔记
- Linux 虚拟机根分区磁盘扩充空间记录
- linux内核分析第五周-分析system_call中断处理过程
- Linux 常用操作