您的位置:首页 > 运维架构 > Linux

20135201李辰希 《Linux内核分析》第五周 扒开系统调用的“三层皮”(下)

2016-03-26 16:18 274 查看
李辰希 原创作品转载请注明出处 《Linux内核分析》

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_call

3.简化后便于理解的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指令将结果信息反馈给了用户。这样,用户就完美的在请求系统调用帮助后,轻松的解决了问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: