先说明两个概念:中断和系统调用

一 系统调用: 是应用程序(运行库也是应用程序的一部分)与操作系统内核之间的接口,它决定了应用程序是如何和内核打交道的。

1,  Linux系统调用:2.6.19版内核提供了319个系统调用。比如 exit fork read open close ……

2,  对Windows来说,操作系统提供给应用程序的接口不是系统调用,而是API。比如:ReadFile。我们暂时把API和系统调用等同起来

3,  Linux中,每个系统调用对应一个系统调用号,内核维护了一个系统调用表,通过这张表可以找到对应的系统调用函数。

二 中断

1,  现代的CPU常常可以在多种截然不同的特权级别下执行指令,所以有两种特权级别,分别为用户模式(User Mode)和内核模式(Kernel Mode)

2,  系统调用运行在内核态,应用程序基本都是运行在用户态。用户态要切换到内核态,操作系统一般是通过中断来完成

3,  Linux使用0x80中断作为系统调用的入口,Windows采用0x2E号中断作为系统调用入口

4,  中断是一个硬件或软件发出的请求,要求CPU暂停当前工作转手去处理更加重要的事。

5,  中断一般有两个属性,中断号和中断处理程序。不同的中断有不同的中断号,也对应不同的中断处理程序。

6,  在内核中有一个数组称为中断向量表,这个数组的第n项包含了指向第n号中断的中断处理程序的指针。

三 基于int的Linux的经典系统调用实现(进入正题)

1,  以fork为例

void main(void)
{
fork();
}

2,  大概流程就是这样:用户调用fork  ->  eax=2(保存系统调用号到寄存器中) -> int 0x80 (触发中断,切换到内核态)

           ->  在中断向量表中查找(0x80号) -> 执行0x80对应的中断服务程序(system_call)

            ->  在系统调用表中找到系统调用号为2的那一项(通过之前保存的eax=2) -> 执行系统调用(sys_fork)

3,  执行流程图如下

4,  用户调用某个系统调用,执行到int $0x80时,会保存现场以便恢复,接着将特权状态切换到内核态,然后CPU便会查找中断向量表中的第0x80号元素。

5,  切换堆栈:

(1)       在执行中断处理函数之前,CPU首先还要进行栈的切换。

(2)       在Linux中,用户态和内核态使用的是不同的栈,两者各自负责各自的函数调用。

(3)       调用0x80中断时,程序执行流程从用户态切换到内核态,当前栈也必须相应的从用户栈切换到内核栈。从中断处理程序中返回时,再切换回用户栈

(4)       “当前栈”指的是ESP的值所在的栈空间,若ESP的值位于用户栈的范围内,那个当前栈就是用户栈,反之就是内核栈。此外,寄存器SS的值还要指向当前栈所在的页

(5)       用户栈 -> 内核栈的实际行为就是:

        保存当前的ESP,SS的值   ->   将ESP SS的值设置为内核栈的相应值

      内核栈 -> 用户栈的实际行为就是:

        恢复原来的ESP SS的值

(6)       用户态的ESP 和 SS保存在内核栈中,这一行为由i386的中断指令自动地由硬件完成。

(7)       中断发生时,CPU切入内核态,还会接着做下面几件事

        找到当前进程的内核栈(每个进程都有独立的内核栈) ->   在内核栈中一次压入用户态的寄存器SS、ESP、EFLAGS、CS、EIP。

(8)       系统从系统调用中返回时,需要用iret指令回到用户态,iret会从内核态中弹出寄存器SS、ESP、EFLAGS、CS、EIP的值,使得栈恢复到用户态的状态

6,中断处理程序:切换栈了以后,程序的流程就切换到了中断向量表中记录0x80号中断处理程序,Linux内部的i386中断服务流程如图

执行完sys_fork后再沿原路返回

参考: 《程序员的自我修养》

基于int的Linux的经典系统调用实现的更多相关文章

  1. 浅析基于ARM的Linux下的系统调用的实现

    在Linux下系统调用是用软中断实现的,下面以一个简单的open例子简要分析一下应用层的open是如何调用到内核中的sys_open的. t8.c 1: #include <stdio.h> ...

  2. Linux下的系统调用

    张雨梅   原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10000 1.linux的的用户态与内核 ...

  3. 基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(一)之miscdevice和ioctl

    基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(一)之miscdevice和ioctl 0. 导语 在嵌入式的道路上寻寻觅觅很久,进入嵌入式这个行业也有几年的时间了,从2011年后 ...

  4. 基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(二)之cdev与read、write

    基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(二)之cdev与read.write 0. 导语 在上一篇博客里面,基于OMAPL138的字符驱动_GPIO驱动AD9833(一)之 ...

  5. 《Linux设备驱动开发具体解释(第3版)》(即《Linux设备驱动开发具体解释:基于最新的Linux 4.0内核》)网购链接

    <Linux设备驱动开发具体解释:基于最新的Linux 4.0内核> china-pub   spm=a1z10.3-b.w4011-10017777404.30.kvceXB&i ...

  6. 基于335X平台Linux交换芯片驱动开发

    基于335X平台Linux交换芯片驱动开发   一.软硬件平台资料 1.开发板:创龙AM3359核心板,网口采用RMII形式. 2.Kernel版本:4.4.12,采用FDT 3.交换芯片MARVEL ...

  7. 用 set follow-fork-mode child即可。这是一个 gdb 命令,其目的是告诉 gdb 在目标应用调用fork之后接着调试子进程而不是父进程,因为在 Linux 中fork系统调用成功会返回两次,一次在父进程,一次在子进程

    GDB的那些奇淫技巧 evilpan 收录于 Security  2020-09-13  约 5433 字   预计阅读 11 分钟  709 次阅读  gdb也用了好几年了,虽然称不上骨灰级玩家,但 ...

  8. 基于pygtk的linux有道词典

    基于pygtk的linux有道词典 一.桌面词典设计 想把Linux用作桌面系统,其中一部分障碍就是Linux上没有像有道一样简单易用的词典.其实我们完全可以自己开发一款桌面词典, 而且开发一款桌面词 ...

  9. 基于s5pv210嵌入式linux系统sqlite3数据库移植

    基于s5pv210嵌入式linux系统sqlite3数据库移植 1.下载源码 http://www.sqlite.org/download.html 最新源码为3080100 2.解压 tar xvf ...

随机推荐

  1. 如何正大光明的使用 google 进行搜索

    对于程序猿来说,不能使用google,是一大痛所在,今天在使用 百度网盘 搜索时,突然发现 ,他能同时使用 baidu和 google进行搜索,于是想到了这个正大光明的使用google 的方法,不需要 ...

  2. hdu 4635 Strongly connected 强连通缩点

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给你一个n个点m条边的图,问在图不是强连通图的情况下,最多可以向图中添多少条边,若图为原来 ...

  3. pageX和pageY

    pageX() 属性是鼠标指针的位置,相对于文档的左边缘. pageY() 属性是鼠标指针的位置,相对于文档的上边缘. 例1 $(document).mousemove(function(e){ $( ...

  4. Keepalived高可用集群搭建(转载linuxIDC)

    1.Keepalived简介 Keepalived是一个基于VRRP协议来实现的WEB服务高可用方案,可以利用其来避免单点故障.使用多台节点安装keepalived.其 他的节点用来提供真实的服务,同 ...

  5. Android反编译

    反编译(未混淆情况) 1.获取资源文件: 命令行界面apktool.bat d -f  test.apk  fileName  (然而修改后缀名为.zip即可获得): apktool2.0以上版本:a ...

  6. Mysql在windows下和linux下对表名大小写默认要求的一个细节

    今天在虚拟机里搭建项目环境,偷了下懒,直接把本机数据库中的表用sqlyog复制给虚拟机中的数据库,然后开始部署项目,项目一启动提示: Table 'sdmqrt.QRTZ_LOCKS' doesn't ...

  7. [转]PhoneGap使用PushPlugin插件实现消息推送

    本文转自:http://my.oschina.net/u/1270482/blog/217661 http://devgirl.org/2013/07/17/tutorial-implement-pu ...

  8. 写一个iOS VoIP应用需要知道什么?

    IOS编程--VoIP解密 一般来说, IOS很少给App后台运行的权限. 仅有的方式就是 VoIP. IOS少有的为VoIP应用提供了后台socket连接,定期唤醒并且随开机启动的权限.而这些就是I ...

  9. 八皇后,回溯与递归(Python实现)

    八皇后问题是十九世纪著名的数学家高斯1850年提出 .以下为python语句的八皇后代码,摘自<Python基础教程>,代码相对于其他语言,来得短小且一次性可以打印出92种结果.同时可以扩 ...

  10. HOJ 1640 Mobile Phone

    题意:有一个n*n的矩阵,op==1时,在(x,y)增加值z,op==2时,求以(x1,y1)和(x2,y2)构成的矩阵的和. 思路:二维线段树. 代码: #include<stdio.h> ...