姬梦馨

原创作品

http://mooc.study.163.com/course/USTC-1000029000

一、用户态、内核态和中断处理过程

用户通过库函数与系统调用联系起来:库函数帮我们把系统调用封装起来。

1.内核态

高级别执行,可以使用特权指令,访问任意的物理地址。

在高执行级别下,代码可以执行特权指令,访问任意的物理地址。

 

2.用户态:

用户态:低级别执行,代码范围受到限制。 对应x86 3级(x86CPU有0-3四个级别)intel x86 CPU有四个权限分级,0-3。 Linux 有两种,0是内核态,3是用户态区分权限级别使得系统更加稳定。

 

如何区分用户态与内核态?
cs:eip。[代码段选择寄存器:偏移量寄存器]
通过cs寄存器的最低两位,表示当前代码的特权级:
【针对逻辑地址】
0xc0000000以上的空间只能在内核态下访问
0x00000000-0xbfffffff两种状态下都可以访问

3.中断

中断处理是从用户态进入内核态的主要方式。

寄存器上下文从用户态切换到内核态时,必须保存用户态的寄存器上下文到内核堆栈中,同时会把当前内核态的一些信息加载,例如cs:eip指向中断处理程序入口。

中断发生后的第一件事就是保存现场 - SAVE_ALL
中断处理结束前最后一件事是恢复现场 - RESTORE_ALL

二、系统调用概述

1. 系统调用的意义:

操作系统为用户态进程与硬件设备进行交互提供了一组接口,就是系统调用。

  • 提高系统安全性
  • 用户程序可移植
  • 远离底层硬件编程

2. API - 应用编程接口

与系统调用区别:
API只是一个函数定义
系统调用是通过软中断向内核发出一个明确的请求。

一般每个系统调用对应一个封装例程,库再用这些封装例程定义出用户的API,方便用户使用。
也就是说,API与系统调用不是一一对应的

API:
  • 直接提供用户态服务
  • 单独的API可能调用几个系统调用
  • 不同的API可能调用了同一个系统调用

返回值: 大部分封装例程返回一个整数
            1表示失败,不能满足请求 
             errno 特定出错码

3.所谓“扒开系统调用的三层皮”

  • API(xyz)
  • 中断向量(system_call)
  • 中断服务程序(sys_xyz)
  • 用户态进程调用系统调用时,CPU切换到内核态执行内核函数

4.系统调用的参数传递

进程指明需要哪个系统调用,传递系统调用号,使用eax传递

  • 系统调用号将xyz与sys_xyz关联起来
  • system_call是linux中所有系统调用的入口点,每个系统调用至少有一个参数,即系统调用号。

用户态到内核态:  寄存器传递。
每个参数长度不能超过32位,个数不能超过6个。
若超过,使某个寄存器中存储指针,指向内存,内存中存储参数。

实验:

使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

1.使用库函数API获取系统当前时间

使用time(),结果如下:

2.使用C代码中嵌入汇编代码触发系统调用获取系统当前时间

结果如下:

3:选择mkdir这个系统调用,其系统调用号为39,即0x27。

mkdir.c的运行结果如下:

运行完mkdir可执行文件,产生了新的文件夹test,改编成汇编代码调用:

执行结果如图:

总结:

系统调用是用户通过库函数方式:库函数帮我们把系统调用封装起来。还是很抽象的,需要结合实验和实践理解。

linux 内核 第四周 扒开系统调用的三层皮 上的更多相关文章

  1. 《Linux内核分析》--扒开系统调用的三层皮 20135311傅冬菁

    扒开系统调用的三层皮           20135311傅冬菁 一.内容分析 寄存器上下文(从用户态切换到内核态) 中断/int指令会在堆栈上保存一些寄存器的值(用户态栈顶地址..当时的状态字.当下 ...

  2. Linux内核分析之扒开系统调用的三层皮(上)

    一.原理总结 本周老师讲的内容主要包括三个方面,用户态.内核态和中断,系统调用概述,以及使用库函数API获取系统当前时间.系统调用是操作系统为用户态进程与硬件设备进行交互提供的一组接口,也是一种特殊的 ...

  3. Linux内核分析之扒开系统调用的三层皮(下)

    一.实验内容 1. 通过内核的方式使用系统调用 需要使用的命令 rm menu -rf //强制删除当前menugit clone http://github.com/mengning/menu.gi ...

  4. 《Linux内核分析》-- 扒开系统调用的三层皮(下)之system_call中断处理过程 20135311傅冬菁

    20135311傅冬菁  原创作品 <Linux内核分析>MOOC课程 分析system_call中断处理过程 内容分析与总结: 系统调用在内核代码中的工作机制和初始化 系统调用在用户态中 ...

  5. 20135327郭皓--Linux内核分析第四周 扒开系统调用的三层皮(上)

    Linux内核分析第四周 扒开系统调用的三层皮(上) 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/U ...

  6. LINUX内核分析第四周——扒开系统调用的三层皮

    LINUX内核分析第四周--扒开系统调用的三层皮 李雪琦 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...

  7. 《Linux内核分析》第四周 扒开系统调用的“三层皮”

    [刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK FOUR( ...

  8. Linux内核及分析 第四周 扒开系统调用的三层皮(上)

    实验过程 选择20号系统调用getpid(取得进程识别码) 在网上查询getpid函数的C语言代码以及其嵌入式汇编语句 C语言代码: #include <stdio.h> #include ...

  9. linux内核分析 第四周 扒开系统调用的三层皮(上)

    一.用户态.内核态和中断处理过程 系统调用是用户通过库函数方式:库函数帮我们把系统调用封装起来. 内核态:高级别执行,可以使用特权指令,访问任意的物理地址. 用户态:低级别执行,代码范围受到限制. C ...

随机推荐

  1. 在 CentOS/Fedora 下安装 JAVA 环境

    介绍 本文介绍如何在 CentOS 7(6/6.5). Fedora.RHEL 上安装 Java.Java是一个流行的软件平台,允许您运行Java应用程序. 本文涵盖了以下Java版本的安装: Ope ...

  2. $Gauss$消元

    $Gauss$消元 今天金牌爷来问我一个高消的题目,我才想起来忘了学高消... 高斯消元用于解线性方程组,也就是形如: $\left\{\begin{matrix}a_{11}x_1+a_{12}x_ ...

  3. 【洛谷】【最小生成树】P1195 口袋的天空

    [题目背景:] 小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空. 有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖. [题目描述:] 给你云朵的个数N,再给你M个关系,表示哪些 ...

  4. cenos6.5 python2.6.6升级至python2.7.3

    踩坑无数... 一.参照以下两篇博文把python升级至python2.7.3 https://www.cnblogs.com/senzhe/p/6322214.html http://www.jb5 ...

  5. Dig命令解析结果

    dig -t RT NAME @NS -t RT 指定要查询的资源记录类型 NAME 需要解析的域(域名) @NS 指定那个域名服务器负责解析 [root@xss ~]# dig www.ihoney ...

  6. mysql数据库创建和权限分配

    查询安装路径: whereis mysql连接mysql: mysql -u root -p第一步:创建用户CREATE USER 'claim_prod'@'%' IDENTIFIED BY 'Pa ...

  7. Android 调用手机上第三方百度地图并传值给地图

    //移动APP调起Android百度地图方式举例 Intent intent = null; try { // intent = Intent.getIntent("intent://map ...

  8. ansible 变量定义和引用

    cat /etc/ansible/hosts [nodes]10.2.1.232 key=23210.2.1.43 key=43 cat debug.yaml ---- name: test how ...

  9. jqgrid 编辑行、新增行、删除行、保存行

    编辑行:$("#jqGrid").jqGrid('editRow', rowKey); 删除行:$("#jqGrid").delGridRow(rowKey); ...

  10. map的综合例子

    #include<iostream> #include<string> #include<map> #include<fstream> #include ...