20135327郭皓--Linux内核分析第四周 扒开系统调用的三层皮(上)
Linux内核分析第四周 扒开系统调用的三层皮(上)
郭皓 原创作品转载请注明出处 《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000
一、用户态、内核态和中断
用户态:当进程在执行用户自己的代码时,则称其处于用户态,即此时处理器在特权级最低的(3级)用户代码中运行。
内核态:当一个进程执行系统调用而陷入内核代码中执行时,我们就称进程处于内核态,此时处理器处于特权级最高的(0级)内核代码中执行。
PS:CPU指令执行级别


中断:
用户态和内核态的转换:

中断处理的完整过程
进入中断程序,保存寄存器数据
SAVE_ALL
-..//内核代码,完成中断服务,发生进程调度
RESTORE_ALL//退出中断程序,恢复寄存器数据
iret(pop cs:eip/ss:esp/eflags from kernel stack)//对应着中断信号或int指令,与发生时CPU动作相反

二、系统调用概述
系统调用:
这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作。而系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现。
系统调用的意义:
- 把用户从底层的硬件编程中解放出来
- 极大的提高了系统的安全性
- 使用户程序具有可移植性
API和系统调用:
应用编程接口(application program interface,API)和系统调用是不同的
- API只是一个函数定义
- 系统调用通过软中断向内核发出一个明确求
Libc库定义的一些API引用了封装例程(wrapper routine,唯一目的就是发布系调用)
- 一般每个系统调用对应一个封装例程
- 库再用这些封装例程定义出给用户的API
不是每个API都对应一个特定的系统调用。
- API可能直接提供用户态的服务
- 如,一些数学函数
- 一个单独的API可能调用几个系统调用
- 不同的API可能调用了同一个系统调用
返回值:
- 大部分封装例程返回一个整数,其值的含义依赖于相应的系统调用
- -1在多数情况下表示内核不能满足进程的请求
- Libc中定义的errno变量包含特定的出错码
应用程序、封装例程、系统调用处理程序及系统调用服务例程之间的关系

xyz():API 其中封装了一个系统调用Intel 0x80触发一个中断
中断向量0x80对应内核代码系统调用起点system_call
中断服务程序(sys_xyz)
系统调用三层皮:
- API(xyz)
- 中断向量(system_call)
- 中断服务程序(sys_xyz)
当用户态进程调用一个系统调用时, CPU切换到内核态并开始执行一个内核函数。
- 在Linux中是通过执行int $0x80来执行系统调用的,这条汇编指令产生向量为128的编程异常
- Intel Pentium II中引入了sysenter指令(快速系统调用), 2.6已经支持(本课程不考虑这个)
传参:
内核实现了很多不同的系统调用,进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数
- 使用eax寄存器
系统调用也需要输入输出参数,例如
- 实际的值
- 用户态进程地址空间的变量的地址
- 甚至是包含指向用户态函数的指针的数据结构的地址
system_call是linux中所有系统调用的入口点,每个系统调用至少有一个参数,即由eax传递的系统调用号
- 一个应用程序调用fork()封装例程,那么在执行int $0x80之前就把eax寄存器的值置为2(即__NR_fork)。
- 这个寄存器的设置是libc库中的封装例程进行的,因此用户一般不关心系统调用号
- 进入sys_call之后,立即将eax的值压入内核堆栈
• 寄存器传递参数具有如下限制:
• 1)每个参数的长度不能超过寄存器的长度,即32位
• 2)在系统调用号( eax)之外,参数的个数不能超过6个( ebx,ecx, edx, esi, edi, ebp)
三、实验:使用库函数API和c代码中嵌入汇编代码触发同一系统调用
1.使用库函数API获取系统当前进程pid值
在这里我使用的是获取进程pid的库函数getpid()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
pid_t tt;
tt = getpid();
printf("%u\n", tt);
return ;
}
2.使用c代码中嵌入汇编代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
pid_t tt;
asm volatile(
"mov $0x14, %%eax\n\t"//系统调用号14放在eax中
"int $0x80\n\t" //系统调用中断
"mov %%eax, %0\n\t"//取出eax中返回的值
:"=m" (tt)
);
printf("%u\n", tt);
return ;
}

总结:
通过本周的学习,更加熟悉了系统调用的本质,以及系统调用和中断的关联。系统调用是用户态和内核态的桥梁,而具体的措施就是中断。
20135327郭皓--Linux内核分析第四周 扒开系统调用的三层皮(上)的更多相关文章
- LINUX内核分析第四周——扒开系统调用的三层皮
LINUX内核分析第四周--扒开系统调用的三层皮 李雪琦 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...
- linux内核分析 第四周 扒开系统调用的三层皮(上)
一.用户态.内核态和中断处理过程 系统调用是用户通过库函数方式:库函数帮我们把系统调用封装起来. 内核态:高级别执行,可以使用特权指令,访问任意的物理地址. 用户态:低级别执行,代码范围受到限制. C ...
- Linux内核分析 笔记五 扒开系统调用的三层皮(下) ——by王玥
(一)给MenuOs增加time和time-asm命令 更新menu代码到最新版 在main函数中增加MenuConfig 增加对应的Ttime和TimeAsm函数 make rootfs (二)使用 ...
- 20135327郭皓--Linux内核分析第五周 扒开系统调用的三层皮(下)
Linux内核分析第五周 扒开系统调用的三层皮(下) 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/U ...
- 20135327郭皓--Linux内核分析第九周 期中总结
Linux内核分析第九周 期中总结 一.知识概要 1. 计算机是如何工作的 存储程序计算机工作模型:冯诺依曼体系结构 X86汇编基础 会变一个简单的C程序分析其汇编指令执行过程 2. 操作系统是如何工 ...
- linux 内核 第四周 扒开系统调用的三层皮 上
姬梦馨 原创作品 http://mooc.study.163.com/course/USTC-1000029000 一.用户态.内核态和中断处理过程 用户通过库函数与系统调用联系起来:库函数帮我们把系 ...
- 20135327郭皓--Linux内核分析第七周 可执行程序的装载
第七周 可执行程序的装载 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 ...
- 20135327郭皓——Linux内核分析第二周 操作系统是如何工作的
操作系统是如何工作的 上章重点回顾: 计算机是如何工作的?(总结)——三个法宝 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的 ...
- 20135327郭皓--Linux内核分析第三周 构造一个简单的Linux系统MenuOS
Linux内核分析第三周 构造一个简单的Linux系统MenuOS 前提回顾 1.计算机是如何工作的三个法宝 1.存储程序计算机 2.函数调用堆栈 3.中断 2.操作系统的两把宝剑 中断上下文的切换 ...
随机推荐
- mpvue 使用echarts动态绘制图表(数据改变重新渲染图表)
最近在公司开发一款微信小程序,按照客户需求用饼状图显示当前设备状态(开机.故障.关机),于是就在网上寻找各种资料,找了很多mpvue使用关于echarts绘制图表,最终功夫不负有心人,找到一篇关于mp ...
- mpvue 应用 Vant Weapp框架开发微信小程序
今天在使用mpvue开发微信小程序的过程中需要实现一个底部上拉选择列表的功能,因为之前做过H5微信公众号的开发,使用的就是有赞的Vant-ui,所以第一时间就想到了有赞的Vant Weapp UI框架 ...
- Scala学习之路 (八)Scala的隐式转换和隐式参数
一.概念 Scala 2.10引入了一种叫做隐式类的新特性.隐式类指的是用implicit关键字修饰的类.在对应的作用域内,带有这个关键字的类的主构造函数可用于隐式转换. 隐式转换和隐式参数是Scal ...
- android java.lang.ExceptionInInitializerError
11-08 13:36:05.108: E/AndroidRuntime(5318): java.lang.ExceptionInInitializerError 11-08 13:36:05.108 ...
- Android-ProgressDialog点击对话框外部是不让其消失
1)ProgressDialog.setCanceledOnTouchOutside(false); 调用这个方法时,按对话框以外的地方不起作用.按返回键还起作用 2)ProgressDialog.s ...
- 例子:照片的OCR识别
来自ng的ml-003中 18_XVIII._Application_Example-_Photo_OCR 这是ng2013年在coursera上最后的一课了.这一系列的几个视频还是相比前面有些难懂, ...
- array_reduce()使用
这个函数的作用是,把数组中的值循环放到回调函数里处理,结果返回一个单一的值.(applies iteratively the callback function to the elements of ...
- 生成本地测试用https证书,支持通配符和多域名,初学OpenSSL
18-01-26在v2ex上看到一妹纸发的<身为一个 21 岁的年轻程序员,我已经腰突了(躺>,哈哈,感同身受,想到这几天我左腿麻木持续了好几天,前几天屁股疼的只要坐下就站不起来,不过站着 ...
- 1、Docker概述与安装
1.Docker概述 原文地址:https://docs.docker-cn.com/engine/docker-overview/#docker-engine Docker是一个开发,集装,运行应用 ...
- REST-framework快速构建API--权限
我们在访问资源时,有些资源保密程度较高,需要特殊的人员才能访问.比如,获取公司的每日收入流水的API接口,只能CEO才能查看. 这时,我们就需要将资源设定权限了. REST-framework实现如下 ...