《Linux内核分析》第五周 扒开系统调用的三层皮(下)
【刘蔚然 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000】
WEEK FIVE(3.21——3.27)扒开系统调用的“三层皮”(下)
SECTION 1 给MenusOS增加time和time-asm命令
1.操作步骤
进入实验楼
- 首先,强制(即 -rf命令)删除当前的menu
克隆一个新的menu(其中已经含有time了)。但是通过实践以及查询,实验楼中对连入外网进行了限制,所以在实验楼中输入下列语句会报错(也就是无法解析https://github.com的网址)
git clone https://github.com/mengning/menu.git
进入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));
- 此外,添加time函数和timeasm函数
- 进入test.c之后,查看main函数。与之相关的只有两条语句:
- 附:关于网址解析解决过程(无法修改resolv.conf文件)后在实验楼的“问答”中查到实验环境限制连入外网
- ()
- ()
- 附:虚拟机中的实验过程(与20135211共同完成)
- 按照第三周《构建一个简单的内核MenuOS》中的配置步骤,对kali虚拟机进行配置;然后更新内核版本到最新版
- 启动init进程(由makefile中内容可以看出,init可执行文件是linktable.c,menu.c,test.c多个文件编译得到的);并且,此时的MenuOS内核已经添加了time以及time_asm系统调用
再进行内核调试的时候,由于kali是64位环境,与实验楼中的调试方法略有不同
启动内核到调试状态
root@KaliYL:/usr/src/linux-source-4.4/arch/x86_64/boot# qemu-system-x86_64 -kernel bzImage -initrd /home/YL/rootfs.img -S -s//这里要加上-system-x86_64
进行调试
gdb /usr/src/linux-source-4.4/vmlinux
(gbd) set arch i386:x86-64
(gdb)target remote:1234
(gdb)b rest_init //(不能break 到 start_kernel,会报错)
2.小结
由此可见,给MenuOS增加time和time-asm命令需要:
- 更新menu代码
- 在main函数中增加menuconfig
- 增加对应的time和timeasm函数
- make rootfs
SECTION 2 使用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处停下来的(因为这里是一处系统调用函数而不是正常函数)
系统调用在内核代码中的工作机制和初始化
1.int 0x80指令与systemcall是通过中断向量联系起来的,而API和对应的sys[函数]是通过系统调用号联系起来的
- ()
- 这也印证了上周的学习内容:软中断触发系统调用,系统调用处理函数负责指派API对应的系统调用函数
2.系统调用机制的初始化
- trapgate函数中,涉及到了系统调用的中断向量和systemcall的汇编代码入口;一旦执行int 0x80,CPU直接跳转到system_call
- ()
3.简化后便于理解的system_call伪代码
- systemcall的位置就在ENTRY(systemcall)处;(其他中断的处理过程与此类似)
- 501行的syscalltable是系统调用表(比如,对于time函数而言,在此处调用的就应该是systime)
- 503行after_call之后,保存返回值
- 505行要exit的时候,会有一个syscallexitwork,否则直接返回用户态
- 进入syscallexitwork之后,简化为下图所示的伪代码
- 19行,判断当前的任务是否需要处理syscallexitwork;一般来说,系统调用都需要处理一些系统调度,也就是需要“work”
- 从第30行开始,跳转到workpending。有worknotifying也就是处理信号;work_reschedle也就是重新调度(调度完之后再restore all)
4.简单浏览system_call到iret之间的主要代码
- SAVE_ALL:保存现场
- syscall_call:调用了系统调用处理函数
- restore all:恢复现场(因为系统调用处理函数也算是一种特殊的“中断”)
- syscallexitwork:如3.中所述
- INTERRUPT RETURN:也就是iret,系统调用到此结束
思考总结
1.理解makefile
1 #
2 # Makefile for Menu Program
3 #
4
//1.以下类似于变量声明,就是将右侧的变量在代码中用左侧替代
5 CC_PTHREAD_FLAGS = -lpthread
6 CC_FLAGS = -c
7 CC_OUTPUT_FLAGS = -o
8 CC = gcc //2.CC 是一个全局变量,它指定你的Makefile所用的编译器,一般默认是gcc
9 RM = rm
10 RM_FLAGS = -f
11
12 TARGET = test
13 OBJS= linktable.o menu.o test.o //3.Define a macro for the object files;.o文件是unix下的中间代码目标文件
14
15 all: $(OBJS)
16 $(CC) $(CC_OUTPUT_FLAGS) $(TARGET) $(OBJS) //4.即 gcc -o XXX
17 rootfs: //5.挂载根文件系统(root files system),见下方解释
18 gcc -o init linktable.c menu.c test.c -m32 -static -lpthread //该句以下是编译顺序
19 gcc -o hello hello.c -m32 -static
20 find init hello | cpio -o -Hnewc |gzip -9 > ../rootfs.img
21 qemu -kernel ../linux-3.18.6/arch/x86/boot/bzImage -initrd ../rootfs.img
22 .c.o:
23 $(CC) $(CC_FLAGS) $<
24
25 clean:
26 $(RM) $(RM_FLAGS) $(OBJS) $(TARGET) *.bak
参考:
- http://itlab.idcquan.com/linux/kernel/816044_2.html
- http://baike.baidu.com/link?url=vZkbUcmSVZOORBE9KpcDQugz53MEwesBgryZRyWUnt0d3kMBqZqpeBJQP8eg-uQgTNFcKLr-E6WHh81YByO3FK
- http://www.crifan.com/whatisroot_filesystem/
分析:
makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
此外,在不同的系统中启动内核的起点有着不同的定义。在实际操作的kali虚拟机中,第21行即可更改为:
qemu-system-x86-64 -kernel 4.3.0-kali-amd64 -initrd ../rootfs.img//kali是64位虚拟机
2.画出从systemcall到iret的流程图(参考entry32.S)
解释:entry.S即中断总控程序的汇编语言定义
参考http://blog.csdn.net/jk198310/article/details/11615703以及http://www.euryugasaki.com/archives/1105
尝试自己画了流程图,对前半部分的梳理还是比较流畅的
这是从同样学习此门课程的本周作业上看到的流程图,仔细研究了一遍,感觉还是很清晰的。不过,关于(图中圈出的)schedule,我个人认为应该是need_resched
《Linux内核分析》第五周 扒开系统调用的三层皮(下)的更多相关文章
- 20135327郭皓--Linux内核分析第五周 扒开系统调用的三层皮(下)
Linux内核分析第五周 扒开系统调用的三层皮(下) 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/U ...
- Linux内核分析第五周——扒开系统调用的“三层皮”(下)
Linux内核分析第五周--扒开系统调用的"三层皮"(下) 李雪琦+原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.1 ...
- Linux内核分析第五周 扒开系统调用的三层皮(下) (20135304 刘世鹏)
作者:刘世鹏20135304 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.给MenuOS增加t ...
- linux内核分析 第五周 扒开系统调用的三层皮(下)
rm menu -rf 强制删除原menu文件 git clone http://github.com/mengning/menu.git 从github中克隆 cd menu 在test.c中增加上 ...
- LINUX内核设计第五周——扒开系统调用的三层皮(下)
- 《Linux内核分析》第四周 扒开系统调用的“三层皮”
[刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK FOUR( ...
- Linux内核及分析 第五周 扒开系统调用的三层皮(下)
实验内容: 1.执行rm menu -rf命令,强制删除原有的menu 2.使用git命令 git clone https://github.com/mengning/menu.git 克隆新的men ...
- Linux内核设计第五周——扒开系统调用三层皮(下)
Linux内核设计第五周 ——扒开系统调用三层皮(下) 一.知识点总结 1.给MenuOS增加新的命令的步骤 更新menu代码到最新版 test.c中main函数里,增加MenuConfig() 增加 ...
- Linux内核分析——第五周学习笔记
第五周 扒开系统调用的“三层皮”(下) 一.知识点总结 (一)给MenuOS增加time和time-asm命令 在实验楼中,首先 强制删除menu (rm menu -rf) 重新克隆一个新版本的me ...
随机推荐
- BZOJ 1059 & 二分图匹配
题意: 判断一个黑白染色的棋盘能否通过交换行或列使对角线上都是黑色. SOL: 真是有点醉...这种问题要么很神要么很水...第一眼感觉很水但就是不造怎么做...想了10分钟怎么感觉就是判断个数够不够 ...
- Android MultiDex
出现的原因: 当Android系统安装一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt.DexOpt的执行过程是在第一次加载Dex文件的时候执行的.这个过程会生 ...
- iframe高度自适应内容
JS自适应高度,其实就是设置iframe的高度,使其等于内嵌网页的高度,从而看不出来滚动条和嵌套痕迹.对于用户体验和网站美观起着重要作用. 如果内容是固定的,那么我们可以通过CSS来给它直接定义一个高 ...
- HDU 4454 Stealing a Cake(枚举角度)
题目链接 去年杭州现场赛的神题..枚举角度..精度也不用注意.. #include <iostream> #include <cstdio> #include <cstr ...
- 四、卫星定位《苹果iOS实例编程入门教程》
该app为应用的功能为用iPhone 显示你现在的位置 现版本 SDK 8.4 Xcode 运行Xcode 选择 Create a new Xcode project ->Single View ...
- Nodejs正则表达式函数之match、test、exec、search、split、replace使用详解
1. Match函数 使用指定的正则表达式函数对字符串惊醒查找,并以数组形式返回符合要求的字符串 原型:stringObj.match(regExp) 参数: stringObj 必选项,需要去进行匹 ...
- SpringMVC——接收请求参数和页面传参
Spring接收请求参数: 1.使用HttpServletRequest获取 @RequestMapping("/login.do") public String login(Ht ...
- JavaScript笔记——this的取值
有关ECMAScript定义如何获取this请移步ECMAScript中关于如何获取this的定义 绝大多数情况下,函数的调用方式决定了this的取值 全局上下文 console.log(this = ...
- 全选,不选,反选js
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...
- Daily Scrum 11.4
昨天会议结束后熬夜较晚,没有及时添加会议记录到博客上,今天补上. Member Today’task Tomorrow’task 张恿 挖掘程序潜力 根据今天的总结对程序进行改进 吴文会 明日返校.. ...