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内核分析第四周 扒开系统调用的三层皮(上)的更多相关文章

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

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

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

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

  3. Linux内核分析 笔记五 扒开系统调用的三层皮(下) ——by王玥

    (一)给MenuOs增加time和time-asm命令 更新menu代码到最新版 在main函数中增加MenuConfig 增加对应的Ttime和TimeAsm函数 make rootfs (二)使用 ...

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

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

  5. 20135327郭皓--Linux内核分析第九周 期中总结

    Linux内核分析第九周 期中总结 一.知识概要 1. 计算机是如何工作的 存储程序计算机工作模型:冯诺依曼体系结构 X86汇编基础 会变一个简单的C程序分析其汇编指令执行过程 2. 操作系统是如何工 ...

  6. linux 内核 第四周 扒开系统调用的三层皮 上

    姬梦馨 原创作品 http://mooc.study.163.com/course/USTC-1000029000 一.用户态.内核态和中断处理过程 用户通过库函数与系统调用联系起来:库函数帮我们把系 ...

  7. 20135327郭皓--Linux内核分析第七周 可执行程序的装载

    第七周 可执行程序的装载 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 ...

  8. 20135327郭皓——Linux内核分析第二周 操作系统是如何工作的

    操作系统是如何工作的 上章重点回顾: 计算机是如何工作的?(总结)——三个法宝 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的 ...

  9. 20135327郭皓--Linux内核分析第三周 构造一个简单的Linux系统MenuOS

    Linux内核分析第三周  构造一个简单的Linux系统MenuOS 前提回顾 1.计算机是如何工作的三个法宝 1.存储程序计算机 2.函数调用堆栈 3.中断 2.操作系统的两把宝剑 中断上下文的切换 ...

随机推荐

  1. p,np,npc,np难问题,确定图灵机与非确定图灵机

    本文转自豆瓣_燃烧的影子 图灵机与可计算性 图灵(1912~1954)出生于英国伦敦,19岁进入剑桥皇家学院研究量子力学和数理逻辑.1935年,图灵写出了"论高斯误差函数"的论文, ...

  2. jquery1.9 下检测浏览器类型和版本的方法

    Jquery1.9版本中$.browser已被剔除: 判断浏览器类型: 复制代码 代码如下: $.browser.mozilla = /firefox/.test(navigator.userAgen ...

  3. 3532: [Sdoi2014]Lis

    Description 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若干项,使得4的最长上升子序列长度减少至少1,且付出的代价之和最小,并输出方案. 如果有多种方案,请输出将删去 ...

  4. 把php session 会话保存到redis

    php的session会话默认时以文件形式保存在php.ini配置文件设置的会话缓存目录,文件保存会话的效率很低,每当每个用户登录一次就会在服务器上生成一个唯一的session_id文件,当用户登录量 ...

  5. anaconda使用以及创建python3.7+pytorch1.0虚拟环境以及Jupyter notebook初级使用

    查看所有已安装的软件包$ conda list# packages in environment at S:\Users\jiangshan\Anaconda3:## Name Version Bui ...

  6. char a='1'和char a=1区别

    char a='1'表示:把字符为1,ASSIC码为49的值赋值给a: char a= 1表示:把ASSIC码为1的值赋值给a

  7. 理解JavaScript中的作用域链

    理解了作用域链,闭包就不难理解了,所以本文主要谈一谈我对作用域链的理解.   关于JavaScript中变量的作用域,全局变量在程序中始终都有定义.局部变量在声明它的函数体内以及其内部所嵌套的函数内始 ...

  8. HDU 3342 Legal or Not(有向图判环 拓扑排序)

    Legal or Not Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  9. linux 文件夹和文件操作

    1.统计目录有多少个文件数 find ./company -type f | wc -l 2.删除文件夹中的文件 rm -f * #最经典的方法,删除当前目录下的所有类型的文件 rsync --del ...

  10. jquery jqzoom插件练习

    <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...