操作系统运行环境与运行机制(系统调用篇)

系统调用:

用户在编程是可以调用的操作系统功能(使CPU可以从用户态陷入内核态)

 应用程序,C函数,API,和内核函数关系

系统调用机制的设计

①中断/异常机制

支持系统调用服务的实现:选择一条陷入指令(访管指令)即可

②选择一条特殊指令:陷入指令(亦称访管指令)

引发异常完成用户态到内核态的切换

③系统调用号和参数:

每个系统调用都实现给定一个编号(功能号)

④系统调用表:

存放系统调用服务例程入口地址

参数传递问题(怎样实现用户程序的参数(存在于用户栈)传递给内核(存在于内核栈)?):

①由陷入指令自带参数:陷入指令的长度有限,且还要携带系统调用功能号,只能自带有限的参数

②通过通用寄存器传递参数:这些寄存器是操作系统和用户程序都能访问的,但寄存器的个数会限制传递参数的数量

③在内存中开辟专用堆栈区来传递参数

现代参数传递使用第2种方法

系统调用例子:

1 #include <unistd.h>
2 int main(){
3 char string[5] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘!’, ‘\n’};
4 write(1, string, 7);
5 return 0;
6 }
7 输出结果:Hello!

这是用高级语言写的程序,编译后转成汇编指令为:

1..section .data
2.output:
3. .ascii “Hello!\n”
4.output_end:
5. .equ len, output_end - output
6..section .text
7..globl _start
8._start:                                                                                     ---
9. movl $4, %eax #eax寄存器存放系统调用号                                   |
10. movl $1, %ebx                                                 |这一段是write函数的简要的汇编指令代码
11. movl $output, %ecx                                                                           |
12. movl $len, %edx                                                                              |
13. int $0x80 #引发一次系统调用  0x80 = 128(d)即为Linux中断向量表中专门用于陷入指令的中断号,调用异常机制  |
14. end:                                                                                      ---
15. movl $1, %eax #1这个系统调用的作用?  -----    1是系统调用号,对应的是返回退出程序
16. movl $0, %ebx                   |   这一段属于return 0 简要的汇编代码
17. int $0x80                          -----

系统调用执行过程

当CPU执行到特殊的陷入指令时:
1.中断/异常机制:软中断发出中断信号,硬件保护现场;通过查中断向量表把控制权转给系统调用总入口程序  (之前查到的都是包含中断处理程序入口地址的中断向量,现在是系统调用总入口程序地址
2.系统调用总入口程序:保存现场;将参数保存在内核堆栈里(参数传递);根据eax寄存器中的系统调用号,通过查系统调用表把控制权转给相应的系统调用处理例程或内核函数
3.执行系统调用例程
4.恢复现场,返回用户程序

Linux系统调用:

陷入指令中断号选择128号
int $0x80
门描述符
  ①系统初始化时:对IDT表中的128号门初始化
  ②门描述符(中断描述符表)的2、3两个字节设置为内核代码段选择符
      0、1、6、7四个字节:偏移量(段选择符从GDT中选择段描述符,然后段描述符有段基地址,从而最终指向system_call(),由sched_init()中set_system_gate(0x80, &system_call)设置)
  ③门类型:15,陷阱门,没有禁止中断
  ④DPL:3,与用户级别相同,因为只有当前执行程序的特权级大于等于门的DPL,特权级才能发生由用户态变成内核态(数值越小特权级越高)

Linux内核中Include/ASM-1386/UNISTD.h文件:

#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6

存了大量的系统调用号

系统执行INT 0x80具体过程:

1.由于特权级的改变,要切换栈

用户栈 → 内核栈

2.CPU从任务状态段TSS中装入新的栈指针(SS︰ESP),指向内核栈                  PS.任务状态段(Task State Segment, TSS)是x86架构电脑上是一个保存任务信息的数据结构,保存了内层堆栈指针

3.用户栈的信息(SS︰ESP)、EFLAGS、用户态CS 、EIP 寄存器的内容压栈(返回用)
4.将EFLAGS压栈后,复位TF,IF位保持不变                                                         PS.TF(bit 8) [Trap flag] 将该位设置为1以允许单步调试模式,清零则禁用该模式。

5.用128在IDT中找到该门描述符,从中找出段选择符装入代码段寄存器CS
6.段描述符中的基地址 + 陷阱门描述符中的偏移量 → 定位 system_call()的入口地址

Linux执行流程

对应的SAVE_ALL执行内容

底层工作总结:

1. 硬件压栈:程序计数器等
2. 硬件从中断向量装入新的程序计数器等
3. 汇编语言过程保存寄存器值
4. 汇编语言过程设置新的堆栈
5. C语言中断服务程序运行(例:读并缓冲输入)
6. 进程调度程序决定下一个将运行的进程
7. C语言过程返回至汇编代码
8. 汇编语言过程开始运行新的当前进程

      作者水平有限,文章肯定有错还请各位指点!!!感谢!!!

参考链接:

http://blog.csdn.net/jn1158359135/article/details/7761011

时间: 2024-10-05 23:56:30

操作系统运行环境与运行机制(系统调用篇)的相关文章

【转】如何配置EditPlus中Java运行环境,运行Java程序

如何配置EditPlus中Java运行环境,运行Java程序 http://jingyan.baidu.com/article/86112f13725e2e2736978711.html 分步阅读 EdltPlus是一款不错的Java代码编辑器,使用EditPlus对于语言代码格式自动生成,省去了我们很多不必要的时间,且其具有小巧,省内存的优势,对于我们平时编写一些简单的Java程序很有帮助,下面小编就为大家介绍下如何配置EditPlusJava环境编辑,使其可以直接运行Java程序(怎么样在e

java运行环境和运行机制

先来介绍三个概念: JVM----JAVA virtual machine      java虚拟机:对字节码提供相同的接口,对操作系统提供不同的接口,以适应各个OS JRE----JAVA runtime environment java运行时环境 JDK----java SE Development kit java 标准版开发包 这是学习java最基础的三个概念,他们的关系如下     JDK(开发必备) -|-----JAVA 类库        |-----JAVA编译器      

NodeJs&gt;-------&gt;&gt;第二章:Node.js中交互式运行环境--------REL

第二章:Node.js中交互式运行环境--------REL 一:REPL运行环境概述 1 C:\Users\junliu>node 2 > foo = 'bar' ; 3 'bar' 4 > 二:在REPL运行环境中操作变量 1 C:\Users\junliu>node 2 > foo='bar' 3 'bar' 4 > var foo='bar' 5 undefined 6 > 1 console.log("foo='bar'"); //控

进程篇(1: 进程运行环境)--请参照本博客“操作系统”专栏

2014年5月30日  下午1:40:59 1. Unix 进程执行环境: 1.1 终止处理程序: ISO C 规定,一个程序可以登记多达32个函数,这些函数将由exit自动调用.我们称这些函数为终止处理程序(exit handler),并调用atexit函数来登记这些函数.该函数的原型如下: 1 #include <stdlib.h>2 3 int atexit(void (*function)(void)); exit调用这些终止程序的顺序与他们登记时的顺序相反(先登记后调用).同一个函数

[WebServer] Windows操作系统下 Tomcat 服务器运行 PHP 的环境配置

前言: 由于本人在开发和学习过程中需要同时部署 JavaWeb 和 PHP 项目,并偶然发现 Tomcat 服务器可以运行 PHP,所以只需要运行一个 Tomcat 服务器即可完成两种Web程序的部署.于是整理了网上的一些相关资料,并结合自己的实际操作,记录于此,以供参考. 一.环境(64bit): 1.操作系统.Tomcat 和 JDK 环境: Server version: Apache Tomcat/9.0.0.M4 Server built: Mar 12 2016 11:39:59 U

漫游Kafka实战篇之搭建Kafka运行环境

接下来一步一步搭建Kafka运行环境. Step 1: 下载Kafka 点击下载最新的版本并解压. > tar -xzf kafka_2.9.2-0.8.1.1.tgz > cd kafka_2.9.2-0.8.1.1 Step 2: 启动服务 Kafka用到了Zookeeper,所有首先启动Zookper,下面简单的启用一个单实例的Zookkeeper服务.可以在命令的结尾加个&符号,这样就可以启动后离开控制台. > bin/zookeeper-server-start.sh

Ecstore安装篇-1.运行环境初始化

Ecstore单机运行环境初始化 Ecstore运行环境要求 应用软件版本信息 Nginx 5.3.29 PHP 5.3.29

Win2012 R2 IIS8.5+PHP(FastCGI)+MySQL运行环境搭建教程

这篇文章主要介绍了Win2012 R2 IIS8.5+PHP(FastCGI)+MySQL运行环境搭建教程,需要的朋友可以参考下 准备篇 一.环境说明: 操作系统:Windows Server 2012 R2 PHP版本:php 5.5.8 MySQL版本:MySQL5.6.15 二.相关软件下载: 1.PHP下载地址: http://windows.php.net/downloads/releases/php-5.5.8-nts-Win32-VC11-x86.zip 2.MySQL下载地址:

[转]Docker学习笔记之一,搭建一个JAVA Tomcat运行环境

本文转自:http://www.blogjava.net/yongboy/archive/2013/12/12/407498.html 前言 Docker旨在提供一种应用程序的自动化部署解决方案,在 Linux 系统上迅速创建一个容器(轻量级虚拟机)并部署和运行应用程序,并通过配置文件可以轻松实现应用程序的自动化安装.部署和升级,非常方便.因为使用了容器,所以可以很方便的把生产环境和开发环境分开,互不影响,这是 docker 最普遍的一个玩法.更多的玩法还有大规模 web 应用.数据库部署.持续