Linux内核分析——第五周学习笔记
第五周 扒开系统调用的“三层皮”(下)
一、知识点总结
(一)给MenuOS增加time和time-asm命令
在实验楼中,首先
- 强制删除menu (rm menu -rf)
- 重新克隆一个新版本的menu(git clone https://github.com/mengning/menu.git
- 进入menu之后,输入make rootfs,就可以自动编译,自动生成根文件系统
- 输入help,可以发现系统支持更多的命令:help version quit time(显示系统时间) time-asm(汇编方式实现)

- 如何实现time和time-asm?
更新menu代码到最新版test.c中main函数里,增加MenuConfig()增加对应的两个函数,Time和TimeAsm函数make rootfs自动编译脚本
下图为在虚拟机中的设置


(二)使用gdb调试跟踪系统调用内核函数sys_time
该过程在第三周已经详细讲解过,这里不做赘述,过程如下:



- 为处理time函数的系统调用systime设置断点之后,在menuOS中执行time。发现系统停在systime处。继续按n单步执行,会进入schedule函数。
- sys_time返回之后进入汇编代码处理,gdb无法继续跟踪。
- 如果在syscall设置断点(entry32.S),然后输入c之后,发现是不会在sys_call处停下来的(因为这里是一处系统调用函数而不是正常函数)。
(三)系统调用在内核代码中的处理过程
1.系统调用在内核代码中的工作机制和初始化
整个系统调用过程中,时间很重要。
以system_call为例,int 0x80指令与systemcall是通过中断向量联系起来的,而API和对应的sys是通过系统调用号联系起来的

用户态时,系统调用xyz()使用int 0x80,它对应调用system_call
右边的处理过程(汇编代码)非常重要,通过系统调用号匹配起来
2.系统调用机制的初始化
trap_init函数里面有一个set_system_trap_gate函数,其中涉及到了系统调用的中断向量SYSCALL_VECTOR和汇编代码入口system_call,一旦执行int 0x80,CPU直接跳转到system_call来执行。

3.简化后便于理解的system_call伪代码
- systemcall的位置就在ENTRY(systemcall)处,其他中断的处理过程与此类似。

SAVE_ALL:保存现场
- call *sys_call_table(,%eax,4)调用了系统调度处理函数,eax存的是系统调用号,是实际的系统调度程序。
- sys_call_table:系统调用分派表
syscall_after_all:保存返回值
- 若有sys_exit_work,则进入sys_exit_work:会有一个进程调度时机。
- work_pending -> work_notifysig,用来处理信号
- 可能call schedule:进程调度代码
- 可能跳转到restore_all,恢复现场。
- work_pending -> work_notifysig,用来处理信号
若无sys_exit_work,就执行restore_all恢复,返回用户态。
INTERRUPT_RETURN <=> iret,结束。
这段代码有几百行,老师用伪代码简化了下

SAVE_ALL与sys_call_table系统调用分派表,对应的处理函数分别是:
sys_call_table(,%eax,4)
JMP(EAX*4 + system_xxx)
.在系统调用返回之前,可能发生进程调度,进程调度里就会出现进程上下文的切换
.进程间通信可能有信号需要处理
4.简单浏览system_call到iret之间的主要代码
- SAVE_ALL:保存现场
- syscall_call:调用了系统调用处理函数
- restore all:恢复现场(因为系统调用处理函数也算是一种特殊的“中断”)
- syscallexitwork:如3.中所述
- INTERRUPT RETURN:也就是iret,系统调用到此结束
二、实验:分析system_call中断处理过程
(一)使用gdb跟踪分析一个系统调用内核函数(上周选择的系统调用)——getuid
1.先执行rm menu -rf,强制删除原有的menu文件夹,使用git命令更新menu代码至最新版。

2.在test.c中添加C函数、汇编函数


3.make rootfs,输入help,可以看到qemu中增加了我们先前添加的命令:

4.可以看到,getuid和getud_asm已经加进去了,分别执行这两个系统调用:

(二)使用gdb跟踪分析一个系统调用内核函数
1.进入gdb调试

2.给start_kernel处设置断点

3.结果如下

4.查看所选用的系统调用函数,可知断点要设置在这里


5.执行命令getuid时没有停下

6.c运行之后,在MenuOs里使用getuid_asm,可以看到它在执行时停下了

7.结束若干次单步执行,然后继续往下单步执行,发现出现了进程调度函数,返回进程调度中的一个当前进程任务的值

8.list可以查看内部的函数,直到system_call返回后进入汇编代码处理,gdb无法继续进行追踪
(三)system_call到iret过程流程图

三、总结
(一)从系统调用处理过程到一般的中断处理过程
1. 保存现场
- 在系统调用时,用SAVE_ALL来保存系统调用时的上下文。
- 中断处理的第一步也是要保存中断程序现场。
- 中断处理完之后,可以返回到原来被中断的地方,在原有的运行环境下继续正确的执行下去。
2. 确定中断信息
- 在系统调用中,需要将系统调用号通过eax传入,通过
sys_call_table查询到调用的系统调用,然后跳转到相应的程序进行处理。 - 中断处理时系统也需要有一个中断号,通过检索中断向量表,了解中断的类型和设备。
3. 处理中断
- 跳转到相应的中断处理程序后,对中断进行处理。
4. 返回
- 系统调用时最后要restore_all恢复系统调用时的现场,并用iret返回用户态。
- 同样,执行完中断处理程序,内核也要执行特定指令序列,恢复中断时现场,并使得进程回到用户态。
(二)给menuOS增加命令的方法:
- 强制删除menu (rm menu -rf)
- 更新menu代码至最新版本(git clone https://github.com/mengning/menu.git)
- 在test.c中main函数中增加MenuConfig,以及增加上周自己选择Getegid,GetegidAsm的代码
- Make roofts自动编译,生成,和启动根文件系统
(三)使用gdb跟踪调试内核的方法:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
gdb
(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表
(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
(gdb)break start_kernel # 断点的设置,注意寻找对应的系统调用函数名字,例如time命令对应sys_time
Vivi.Lu 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
Linux内核分析——第五周学习笔记的更多相关文章
- linux内核分析第五周学习笔记
linux内核分析第五周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- LINUX内核分析第五周学习总结——扒开应用系统的三层皮(下)
LINUX内核分析第五周学习总结——扒开应用系统的三层皮(下) 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cou ...
- LINUX内核分析第五周学习总结——扒开系统调用的“三层皮”(下)
LINUX内核分析第五周学习总结--扒开系统调用的"三层皮"(下) 标签(空格分隔): 20135321余佳源 余佳源 原创作品转载请注明出处 <Linux内核分析>M ...
- 《Linux内核分析》第一周学习笔记
<Linux内核分析>第一周学习笔记 计算机是如何工作的 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/c ...
- 《Linux内核分析》第二周学习笔记
<Linux内核分析>第二周学习笔记 操作系统是如何工作的 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/ ...
- Linux内核分析第三周学习笔记
linux内核分析第三周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- Linux内核分析第五周学习总结——分析system_call中断处理过程
Linux内核分析第五周学习总结--分析system_call中断处理过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...
- Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程
Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...
- Linux内核分析第七周学习笔记——Linux内核如何装载和启动一个可执行程序
Linux内核分析第七周学习笔记--Linux内核如何装载和启动一个可执行程序 zl + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study. ...
随机推荐
- 菜鸟对APP界面设计的一些心得小结
1. 前言 当我看着我以前做的一些app界面,我意识到我应该把我的界面设计能力水平再提升一个,因为实在是丑啊!贴一些以前的设计: 现在看来,是不能看的了.我主要是做需求设计,后面也有一些美工的工作,我 ...
- 团队作业——Beta冲刺3
团队作业--Beta冲刺 冲刺任务安排 杨光海天 今日任务:浏览详情界面的开发 明日任务:浏览详情界面的开发 吴松青 今日任务:与队长一同进行图片详情的开发,接触了一些自己没接触过的知识点并向队友学习 ...
- React阻止事件冒泡的正确打开方式
需求:点击导航list按钮出现侧弹框,点击空白处弹框消失 问题:绑定空白处的点击事件到document上,但是非空白处的点击也会触发这个点击事件,在react中如何阻止事件冒泡? 解决方法:e.sto ...
- java字节码的工具(含IDEA插件)
转:https://blog.csdn.net/qq_34039315/article/details/78561493 javap方式 最基础的方式,此处不做介绍 windows下的工具jclass ...
- CSS3页面布局方案
CSS3页面布局方案 Web页面中的布局,在css3之前,主要使用float属性或者position属性进行页面中的简单布局,但是使用它们也存在一些缺点,比如两栏或者多栏中如果元素的内容高度不一致,则 ...
- oninput和onpropertychange实时监听输入框值的变化
oninput和onpropertychange实时监听输入框值的变化 传统监听输入框的做法就是使用keyup.keydown.keypress,或者change事件来实现,但keyup.keydow ...
- Android 网络请求超时处理方案
以用户登录为例介绍用户访问网络时的请求超时处理的两种方法: 1)使用android提供的工具类AsyncTask类,此类提供了一个AsyncTask.execute().get(timeout, un ...
- ASP.NET Core中,UseDeveloperExceptionPage扩展方法会吃掉异常
在ASP.NET Core中Startup类的Configure方法中,有一个扩展方法叫UseDeveloperExceptionPage,如下所示: // This method gets call ...
- vlc播放rtsp之怪事
播放源:rtsp;//admin:12345@11.11.3.24:554/Streaming/channels/201 源是一台海康的nvr,在一台win2003的服务器用vlc2.2可以播放,但在 ...
- 20155223 实验5 MSF基础应用
20155223 实验5 MSF基础应用 基础问题回答 用自己的话解释什么是exploit,payload,encode? exploit:漏洞攻击.一个exploit程序肯定会触发系统的一个或多个漏 ...