Linux内核分析 笔记四 系统调用的三个层次 ——by王玥
一、知识点总结
(一)用户态、内核态和中断


1.内核态:在高的执行级别下,代码可以执行特权指令,访问任意的物理地址,这时的CPU就对应内核态
2.用户态:在低级别的指令状态下,代码 只能在级别允许的特定范围内活动。在日常操作下,执行系统调用的方式是通过库函数,库函数封装系统调用,为用户提供接口以便直接使用。
3.在Linux下0级表示内核态,3级表示用户态。
4.内核态cs:eip的值是任意的,即可以访问所有的地址空间。用户态只能访问其中的一部分内存地址。
5.中断处理是从用户态进入内核态的主要方式,系统调用是一种特殊的中断。中断/int指令会在堆栈上保存用户态的寄存器上下文,其中包括用户态栈顶地址、当时的状态字、cs:eip的值,以及内核态的栈顶地址、当时的状态字、中断处理程序入口。中断处理结束前的最后一件事就是恢复现场,退出中断程序,恢复保存寄存器的数据。
例:
interrupt(ex:int 0X80)//发生系统调用 save
cs:eip/ss:esp/eflags(current)to kernel stack //保存cs:eip的值,保存当前堆栈段寄存器当前栈顶和标志位寄存器 load cs:eip(entry of a specific ISR)and ss:eip(point to kenerl stack) //把当前的中断信号或系统调用相关中断服务例程入口加载到cs:eip中,把当前的堆栈段和esp加载到CPU
SAVE_ALL//保存现场 ...//内核代码,完成中断服务,发生进程调度
RESTORE_ALL//恢复现场
iret - pop cs:eip/ss:esp/eflags from kernel stack//iret对应相反的中断指令
(二)系统调用概述
1.系统调用的意义
操作系统为用户态进程与硬件设备进行交互提供的一组接口——系统调用
- 把用户从底层的硬件编程中解放出来 
- 极大的提高了系统的安全性 
- 使用户程序具有可移植性 
2.API(应用程序编程接口)与系统调用的关系
- API是一个系统调用封装成的一个函数定义 
- 系统调用通过软中断向内核发出一个明确的请求 
- Libc库定义的一些API引用了封装例程,目的是发布系统调用,让程序员写代码的时候可以通过函数调用而非汇编指令触发一个系统调用 
- 一般每个系统调用对应一个封装例程,库再用这些封装例程定义出给用户的API 

3.返回值
- 大部分封装例程返回一个整数,其值的含义依赖于相应的系统调用 
- -1在多数情况下表示内核不能满足进程的请求 
- Libc中定义的errno变量包含特定的出错码 
- 应用程序、封装例程、系统调用处理程序及系统调用服务例程之间的关系:

- 系统调用的三层皮:xyz(API)、system_call(中断向量)、sys_xyz(中断服务程序)

4.传参
- 内核实现了很多不同的系统调用。 
- 进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数 
- 使用eax寄存器传递系统调用号。 

超过6个的情况下,使用某一个寄存器作为指针,进入内核态之后可以访问所有的地址空间,通过某一片区域传递参数。
(三)使用库函数API和C代码中嵌入汇编代码触发同一个系统调用
1.使用库函数API来获取系统当前时间
2.C代码中嵌入汇编代码的写法
__asm__(
汇编语句模板:
输入部分:
输出部分:
破坏描述部分:);
汇编代码分析:
#include <stdio.h>
#include <time.h>
int main()
{
    time_t tt;//int型数值
    struct tm *t;
    asm volatile(
        "mov $0,%%ebx\n\t"//将ebx寄存器清零,系统调用传递第一个参数使用ebx,这里是null
        "mov $0xd,%%eax\n\t"//将0xd放入eax中,0xd为13,传递系统调用号13
        "int $0x80\n\t"
        "mov %%eax,$0\n\t"//通过eax这个寄存器返回系统调用值
        :"=m"(tt)
    );
    t = localtime(&tt);
    printf("time:%d:%d:%d:%d:%d:%d\n",t->tm_year+1900,t->tm_mon,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
    return 0;
}限定符对照表:

3.用汇编方式触发系统调用获取系统当前时间


(四)实验
1.选择20号系统调用,getpid来获取当前进程的pid
2.实验内容:
- 使用库函数API方式:


- 使用C代码中嵌入汇编代码方式:


王玥【原创作品转载请注明出处】 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
Linux内核分析 笔记四 系统调用的三个层次 ——by王玥的更多相关文章
- Linux内核分析 笔记二 操作系统是如何工作的  ——by王玥
		一.知识要点 1.计算机是如何工作的?(总结)——三个法宝 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算 ... 
- Linux内核分析第四章 读书笔记
		Linux内核分析第四章 读书笔记 第一部分--进程调度 进程调度:操作系统规定下的进程选取模式 面临问题:多任务选择问题 多任务操作系统就是能同时并发地交互执行多个进程的操作系统,在单处理器机器上这 ... 
- Linux内核分析(四)----进程管理|网络子系统|虚拟文件系统|驱动简介
		原文:Linux内核分析(四)----进程管理|网络子系统|虚拟文件系统|驱动简介 Linux内核分析(四) 两天没有更新了,上次博文我们分析了linux的内存管理子系统,本来我不想对接下来的进程管理 ... 
- Linux内核分析 笔记三 构造一个简单的Linux系统MenuOS ——by王玥
		一.知识点总结 (一)Linux源代码简介 arch/x86目录下的代码是我们重点关注的 内核启动相关代码都在init目录下 start_kernel函数相当于普通C程序的main函数 linux的核 ... 
- Linux内核分析之扒开系统调用的三层皮(上)
		一.原理总结 本周老师讲的内容主要包括三个方面,用户态.内核态和中断,系统调用概述,以及使用库函数API获取系统当前时间.系统调用是操作系统为用户态进程与硬件设备进行交互提供的一组接口,也是一种特殊的 ... 
- Linux内核分析 笔记七 可执行程序的装载 ——by王玥
		一.预处理.编译.链接和目标文件的格式 (一)可执行程序是怎么得来的? 1. 2.可执行文件的创建——预处理.编译和链接 shiyanlou:~/ $ cd Code ... 
- 【MOOC EXP】Linux内核分析实验四报告
		程涵 原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 [使用库函数API和C代码中嵌入汇编代 ... 
- Linux内核分析之扒开系统调用的三层皮(下)
		一.实验内容 1. 通过内核的方式使用系统调用 需要使用的命令 rm menu -rf //强制删除当前menugit clone http://github.com/mengning/menu.gi ... 
- 《Linux内核分析》-- 扒开系统调用的三层皮(下)之system_call中断处理过程  20135311傅冬菁
		20135311傅冬菁 原创作品 <Linux内核分析>MOOC课程 分析system_call中断处理过程 内容分析与总结: 系统调用在内核代码中的工作机制和初始化 系统调用在用户态中 ... 
随机推荐
- SDN 第四次上机作业
			1.建立以下拓扑,并连接上ODL控制器. 2.利用ODL下发流表,使得h3在10s内ping不通h1,10s后恢复. 3.借助Postman通过ODL的北向接口下发流表,再利用ODL北向接口查看已下发 ... 
- 【干货】一文理解Druid原理架构(时序数据库,不是ali的数据库连接池)
			Druid.io(以下简称Druid)是2013年底开源出来的, 主要解决的是对实时数据以及较近时间的历史数据的多维查询提供高并发(多用户),低延时,高可靠性的问题. Druid简介: Druid是一 ... 
- 【Ansible 文档】【译文】Windows 支持
			see also:List of Windows Modules Windows Support Windows 支持 Windows: How Does It Work Windows:如何工作 正 ... 
- 抓取js动态生成的数据分析案例
			需求:爬取https://www.xuexi.cn/f997e76a890b0e5a053c57b19f468436/018d244441062d8916dd472a4c6a0a0b.html页面中的 ... 
- 小米3系统计算器自己定义开关控件-MySwitchView
			1.前言 在android4.0以后,有switch控件.相似于iPhone上面滑块的效果.可是仅仅能用在4.0以后的系统中.之前的平台.就无法使用这种控件. 近段时间.看到了 ... 
- 【转】网段,子网掩码,网络标识,IP划分
			网段指一个计算机网络中使用同一物理层设备(传输介质,中继器,集线器等)直接通讯的那一部分.就是从一个IP到另一个IP 好比 从192.168.0.1到192.168.255.255这之间就是一个网段 ... 
- 青岛大学开源OJ平台搭建
			源码地址为:https://github.com/QingdaoU/OnlineJudge 可参考的文档为:https://github.com/QingdaoU/OnlineJudgeDeploy/ ... 
- 垃圾回收相关(深入理解Java虚拟机中的内容)
			程序计数器.虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收.垃圾回收主要是针对 Java 堆和方法区进行. 判断一个对 ... 
- Mac下用户名、计算机名、个人目录名修改
			1.修改mac用户名 [系统偏好设置]->[用户与群组]->点开左下方的小锁->解锁后再用户头像右击,进入到高级选项->进行设置即可 2.修改mac计算机名 [系统偏好设置]- ... 
- JAVA框架  Spring  事务
			一.我们之前在hibernate的时候,需要直接写事务,需要绑定当前线程保证获取同一个连接,虽然hibernate的帮我们封装绑定当前现成的操作,但是需要我们手动的去开启和关闭事务. 而spring帮 ... 
