扒开系统调用的三层皮(上)

于佳心 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

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

我选择了02系统调用,fork

库函数API

#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t f;
f = fork();
printf("f = %d \n",f);
return ;
}

嵌入汇编

#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t f;
f = fork();
asm volatile(
"mov $0x02,%%eax\n\t" /*将系统调用号保存到eax里*/
"int $0x80\n\t" /*中断向量号,执行系统调用*/
"mov %%eax,%0\n\t" /*将返回值保存到f中*/
:"=m"(f)
);
printf("f = %d \n",f);
return ;
}

总结:

这节课我们主要学了系统调用,要学会系统调用。我们首先要知道用户态和内核态的区别。

一般现代CPU都有几种不同的指令执行级别,在高执行级别下,代码可以执行特权指令,访问任意的物理地址,这种CPU执行级别就是对应着内核态。

而在相应的低级别执行状态下,代码的掌握范围会受到限制,只能在对应级别允许的范围内活动

权限级别划分是一个让操作系统稳定的机制

intel x86 CPU有四种不同的级别划分:0,1,2,3

Linux只使用了0和3

0表示内核态,3表示用户态

内核态和用户态的显著区分方法是cs:eip

cs寄存器的最低两位表示当前代码的特权级

CPU每条指令的读取都是通过cs:eip这两个寄存器:

其中cs是代码段选择寄存器,eip是偏移量寄存器

上述判断由硬件完成

一般来说在LInux中,地址空间是一个显著的标志:内核态可以访问全部地址,但0xc0000000以上的地址只能在内核态下访问,0x00000000-0xbfffffff的地址两种状态下都可以访问(这里所说的地址空间是逻辑地址,不是物理地址)

寄存器上下文从用户态切换到内核态时必须保存用户态的寄存器上下文

内核态的值放进CPU

中断/int指令会在堆栈上保存一些寄存器的值,如:用户态栈顶地址、当时的状态字、当时的cs:eip的值

中断发生后得第一件事是保存现场,将其他寄存器的值push到内核 中断中去,结束后再把寄存器pop出来

iret指令与中断信号发生的cpu做的动作相反

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

系统调用的意义:

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

把用户从底层的硬件编程中解放出来

极大的提高了系统的安全性

使用户程序具有可移植性

系统调用的一种特殊的中断

应用编程接口(API)和系统调用是不同的

API只是函数的一个定义

系统调用通过软中断向内核发出一个明确的请求

Libc库定义的一些API引起了封装例程(唯一目的就是发布系统调用)

一般每个系统调用对应一个封装例程

库再用这些封装例程定义出给用户的API

不是每个API都对应一个特定的系统调用

API可能直接提供用户态的服务

一个单独的API可能调用几个系统调用

不同的API可能调用了同一个系统调用

大部分封装例程返回一个整数,其值的含义依赖于相应的系统调用

-1在多数情况下表示内核不能满足进程的请求

Libc中定义的errno变量包含特定的出错码

当用户态进程调用一个系统调用时,CPU切换到内核态并执行一个内核函数

在Linux中是通过执行int $0x80来执行系统调用的,这条汇编指令产生向量为128的编程异常

传参:内核实现了很多不同的系统调用,进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数

学的知识越来越难了,有点担心以后学不会。

Linux内核分析作业 NO.4的更多相关文章

  1. linux内核分析作业8:理解进程调度时机跟踪分析进程调度与进程切换的过程

    1. 实验目的 选择一个系统调用(13号系统调用time除外),系统调用列表,使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 分析汇编代码调用系统调用的工作过程,特别是参数的传递的方 ...

  2. Linux内核分析作业7:Linux内核如何装载和启动一个可执行程序

            1.可执行文件的格式 在 Linux 平台下主要有以下三种可执行文件格式: 1.a.out(assembler and link editor output 汇编器和链接编辑器的输出) ...

  3. linux内核分析作业6:分析Linux内核创建一个新进程的过程

    task_struct结构: struct task_struct {   volatile long state;进程状态  void *stack; 堆栈  pid_t pid; 进程标识符  u ...

  4. linux内核分析作业5:分析system_call中断处理过程

    1.增加 Menu 内核命令行 调试系统调用. 步骤:删除menu git clone        (tab) make rootfs 这就是我们将 fork 函数写入 Menu 系统内核后的效果, ...

  5. linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作

    一.实验 使用gcc –S –o main.s main.c -m32 命令编译成汇编代码,如下代码中的数字请自行修改以防与他人雷同 int g(int x) { return x + 3; } in ...

  6. linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核代码

    计算机如何工作 三个法宝:存储程序计算机.函数调用堆栈.中断机制. 堆栈 函数调用框架 传递参数 保存返回地址 提供局部变量空间 堆栈相关的寄存器 Esp 堆栈指针  (stack pointer) ...

  7. linux内核分析作业3:跟踪分析Linux内核的启动过程

    内核源码目录 1. arch:录下x86重点关注 2. init:目录下main.c中的start_kernel是启动内核的起点 3. ipc:进程间通信的目录 实验 使用实验楼的虚拟机打开shell ...

  8. linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    系统调用:库函数封装了系统调用,通过库函数和系统调用打交道 用户态:低级别执行状态,代码的掌控范围会受到限制. 内核态:高执行级别,代码可移植性特权指令,访问任意物理地址 为什么划分级别:如果全部特权 ...

  9. Linux内核分析作业 NO.8 完结撒花~~~

    进程的切换和系统的一般执行过程 于佳心  原创作品转载请注明出处  <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10000 ...

  10. Linux内核分析作业 NO.7

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

随机推荐

  1. 028、HTML 标签3表单标签插入组件

    内容:表单标签插入组件(经常使用)############################################################## form表单标签和input组件 < ...

  2. 细数垃圾邮箱客户端 Live Mail 的BUG

    以前用XP系统,里面自带的有outlook,使用中还行,不过bug也不少,常见的如 1.查找,邮件多了后,常常查找不到: 2.有时收件箱什么的突然空白,或部分邮件不见了(2G大小限制,超过了就不能做移 ...

  3. JQUERY方法给TABLE动态增加行

    比如设置table的id为tabvar trHTML = "<tr><td>...</td></tr>"$("#tab&q ...

  4. PHP foreach 循环使用"&$val" 地址符“&”

    在熟悉项目代码的时候 看到这样的foreach 循环: foreach($data as &$val){ .... } 第一次看到循环里面使用了地址符“&”,我印象中的这个符号 是直接 ...

  5. leetcode 460. LFU Cache

    hash:存储的key.value.freq freq:存储的freq.key,也就是说出现1次的所有key在一起,用list连接 class LFUCache { public: LFUCache( ...

  6. python+selenium+chrome driver 64位环境配置

    新换了电脑,重新配置下环境,备忘下 1.python2安装 https://www.python.org/downloads/release/python-2714/ 下载64位Windows x86 ...

  7. PAT A1009 Product of Polynomials (25 分)——浮点,结构体数组

    This time, you are supposed to find A×B where A and B are two polynomials. Input Specification: Each ...

  8. SQL Server聚合函数与聚合开窗函数

    以下面这个表的数据作为示例. 什么是聚合函数? 聚合函数:聚合函数就是对一组值进行计算后返回单个值(即分组).聚合函数在计算时都会忽略空值(null). 所有的聚合函数均为确定性函数.即任何时候使用一 ...

  9. R链接hive/oracle/mysql

    Linux:R连接hive用的Rhive 1,重要 1,sudo R CMD javareconf 2,sudo R 3, 1+1 是否为2 3.1,>install.packages(&quo ...

  10. 预定义的类型“System.Object”未定义或未导入

    打开一个以前的程序 ,发现报这个错误.检查了程序,发现程序的引用 System 不见了 ,尝试 引用失败.. 查了有人说重新建立 Sln文件有用.. 一头雾水,随后 尝试操作 ,程序有用了 具体步骤: ...