Linux使用两级保护机制:0级供内核使用,3级供用户程序使用。从图中可以看出,每个进程有各自的私有用户空间(0~3G),这个空间对系统中的其他进程是不可见的。最高的1GB字节虚拟内核空间则为所有进程以及内核所共享。

http://developer.51cto.com/art/201110/299468.htm

http://blog.csdn.net/hjl243632044/article/details/7218283

http://www.cnblogs.com/Anker/p/3269106.html

针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,

而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。

每个进程可以通过系统调用进入内核,因此,Linux内核由系统内的所有进程共享。

有了用户空间和内核空间,整个linux内部结构可以分为三部分,从最底层到最上层依次是:硬件-->内核空间-->用户空间。如下图所示:

需要注意的细节问题:

(1) 内核空间中存放的是内核代码和数据,而进程的用户空间中存放的是用户程序的代码和数据。不管是内核空间还是用户空间,它们都处于虚拟空间中。

(2) Linux使用两级保护机制:0级供内核使用,3级供用户程序使用。

  内核态与用户态:

(1)当一个任务(进程)执行系统调用而陷入内核代码中执行时,称进程处于内核运行态(内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。

(2)当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而突然被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态。因为中断处理程序将使用当前进程的内核栈。

程序在执行过程中通常有用户态和内核态两种状态,CPU对处于内核态根据上下文环境进一步细分,因此有了下面三种状态:

(1)内核态,运行于进程上下文,内核代表进程运行于内核空间。

(2)内核态,运行于中断上下文,内核代表硬件运行于内核空间。

(3)用户态,运行于用户空间。

但是,切换到中断处理,比进程切换,代价要小。

所谓的“进程上下文”,可以看作是用户进程传递给内核的这些参数以及内核要保存的那一整套的变量和寄存器值和当时的环境等。

相对于进程而言,就是进程执行时的环境。具体来说就是各个变量和数据,包括所有的寄存器变量、进程打开的文件、内存信息等。一个进程的上下文可以分为三个部分:用户级上下文、寄存器上下文以及系统级上下文。

(1)用户级上下文: 正文、数据、用户堆栈以及共享存储区;

(2)寄存器上下文: 通用寄存器、程序寄存器(IP)、处理器状态寄存器(EFLAGS)、栈指针(ESP);

(3)系统级上下文: 进程控制块task_struct、内存管理信息(mm_struct、vm_area_struct、pgd、pte)、内核栈。

当发生进程调度时,进行进程切换就是上下文切换(context switch).操作系统必须对上面提到的全部信息进行切换,新调度的进程才能运行。

而系统调用进行的模式切换(mode switch)。模式切换与进程切换比较起来,容易很多,而且节省时间,因为模式切换最主要的任务只是切换进程寄存器上下文的切换。

硬件通过触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的 一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。所谓的“ 中断上下文”,其实也可以看作就是硬件传递过来的这些参数和内核需要保存的一些其他环境(主要是当前被打断执行的进程环境)。中断时,内核不代表任何进程运行,它一般只访问系统空间,而不会访问进程空间,内核在中断上下文中执行时一般不会阻塞。

LINUX完全注释中的一段话:

当一个进程在执行时,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容被称为该进程的上下文。当内核需要切换到另一个进程时,它需要保存当前进程的所有状态,即保存当前进程的上下文,以便在再次执行该进程时,能够必得到切换时的状态执行下去。在LINUX中,当前进程上下文均保存在进程的任务数据结构中。在发生中断时,内核就在被中断进程的上下文中,在内核态下执行中断服务例程。但同时会保留所有需要用到的资源,以便中继服务结束时能恢复被中断进程的执行。

内核空间,用户空间

http://blog.csdn.net/bingqingsuimeng/article/details/7924756

内核空间和用户空间之间如何进行通讯?

  内核空间和用户空间一般通过系统调用进行通信。

  如何判断一个驱动是用户模式驱动还是内核模式驱动? 判断的标准是什么?

一般的硬件体系机构都提供一种“门”机制。“门”的含义是指在发生了特定事件的时候低特权的应用程序可以通过这些“门”进入高特权的内核空间。对于IntelX86体系来说,Linux操作系统正是利用了“系统门”这个硬件界面(通过调用int $0x80机器指令),构造了形形色色的系统调用作为软件界面,为应用程序从用户态陷入到内核态提供了通道。(其实就是系统调用)

通过“系统调用”使用“系统门”并不需要特别的权限,但陷入到内核的具体位置却不是随意的,这个位置由“系统调用”来指定,有这样的限制才能保证内核安全无虞。

我们可以形象地描述这种机制:作为一个游客,你可以买票要求进入野生动物园,但你必须老老实实的坐在观光车上,按照规定的路线观光游览。当然,不准下车,因为那样太危险,不是让你丢掉小命,就是让你吓坏了野生动物。

由内核主动发起的信息交互

在内核发起的交互中,我们最关心和感兴趣的应该是内核如何向用户程序发消息,用户程序又是怎样接收这些消息的,具体问题通常集中在下面这几个方面:内核可否调用用户程序?是否可以通过向用户进程发信号来告知用户进程事件发生?

内核中启动用户程序还是要通过execve这个系统调用原形,只是此时的调用发生在内核空间,而一般的系统调用则在用户空间进行。如果系统调用带参数,那将会碰到一个问题:因为在系统调用的具体实现代码中要检查参数合法性,该检查要求所有的参数必须位于用户空间——地址处于0x0000000——0xC0000000之间,所以如果我们从内核传递参数(地址大于0xC0000000),那么检查就会拒绝我们的调用请求。为了解决这个问题,我们可以利用set_fs宏来修改检查策略,使得允许参数地址为内核地址。这样内核就可以直接使用该系统调用了。

(2) 利用brk系统调用来导出内核数据

内核和用户空间传递数据主要是用get_user(ptr)和put_user(datum,ptr)例程。所以在大部分需要传递数据的系统调用中都可以找到它们的身影。可是,如果我们不是通过用户程序发起的系统调用——也就是说,没有明确的提供用户空间内的缓冲区位置——的情况下,如何向用户空间传递内核数据呢?

Linux进程空间分布 & 上下文的更多相关文章

  1. Linux进程空间分布 & 进程控制块 PCB

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Verdana; color: #555555 } span.s1 { } Linux使用两级 ...

  2. Linux进程地址空间 && 进程内存布局[转]

    一 进程空间分布概述       对于一个进程,其空间分布如下图所示: 程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码. 初始化过的数据(Data):在程序运行初已经对变量进行初始 ...

  3. 浅析Linux进程空间布局

    一.进程空间分布概述 对于一个进程,其空间分布如下图所示: 1.参数说明 程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码. 初始化过的数据(Data):在程序运行初已经对变量进行初 ...

  4. linux进程用户内存空间和内核空间

    When a process running in user mode requests additional memory, pages are allocated from the list of ...

  5. Linux性能及调优指南(翻译)之Linux进程管理

    本文为IBM RedBook的Linux Performanceand Tuning Guidelines的1.1节的翻译原文地址:http://www.redbooks.ibm.com/redpap ...

  6. 《Linux 性能及调优指南》1.1 Linux进程管理

    https://blog.csdn.net/ljianhui/article/details/46718835 本文为IBM RedBook的Linux Performanceand Tuning G ...

  7. Linux进程控制(二)

    1. 进程的创建 Linux下有四类创建子进程的函数:system(),fork(),exec*(),popen() 1.1. system函数 原型: #include <stdlib.h&g ...

  8. Linux进程管理知识整理

    Linux进程管理知识整理 1.进程有哪些状态?什么是进程的可中断等待状态?进程退出后为什么要等待调度器删除其task_struct结构?进程的退出状态有哪些? TASK_RUNNING(可运行状态) ...

  9. linux内核空间与用户空间信息交互方法

    linux内核空间与用户空间信息交互方法     本文作者: 康华:计算机硕士,主要从事Linux操作系统内核.Linux技术标准.计算机安全.软件测试等领域的研究与开发工作,现就职于信息产业部软件与 ...

随机推荐

  1. SpringBoot-redis-session

    配置pom <parent> <groupId>org.springframework.boot</groupId> <artifactId>sprin ...

  2. sql server 行转列 要注意的问题 pivot

      select * from (  select mvqr.VoteQuestionId,mvqr.AnswerSolution from  JY_MemberVoteQuestionRef as  ...

  3. 2559. [NOIP2016]组合数问题

    [题目描述] [输入格式] 从文件中读入数据. 第一行有两个整数t, k,其中t代表该测试点总共有多少组测试数据,k的意义见[问题描述]. 接下来t行每行两个整数n, m,其中n, m的意义见[问题描 ...

  4. Web性能测试术语

    并发用户: 并发一般分为2种情况.一种是严格意义上的并发,即所有的用户在同一时刻做同一件事情或者操作,这种操作一般指做同一类型的业务.比如在信用卡审批业 务中,一定数目的用户在同一时刻对已经完成的审批 ...

  5. iOS中ARC和非ARC混用

    如果在使用第三方类库的时候,我们可能会遇到一些内存管理的问题   那么如何在一个工程中实现ARC和非ARC混用呢,例如你创建一个ARC的工程,但是你引用的第三方类库是非ARC管理内存的   首先点击工 ...

  6. 自学php【二】 PHP计算时间加一天

    最近几天在做一个项目,主要是将SQLserver数据到MySQL数据库,一个url跑一次 同步一次昨天的数据,由于很多数据需要同步,所以做了一个操作界面的,一个单纯跑url的 在其中涉及到了对于时间的 ...

  7. java继承问题

    代码: 父类: public class Father { public Father() { System.out.println("基类构造函数{"); show(); new ...

  8. 在eclipse里如何快速定位到某一行?

    使用快捷键ctrl+L讲每一行的行号显示出来:在eclipse的某一行的最左边,右键——show Line Numbers就可以将行数都显示出来.

  9. HDU_1561_The more, The Better_树型dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 The more, The Better Time Limit: 6000/2000 MS (J ...

  10. vue-cli的项目加入骨架屏

    在原生APP中我们经常可以看到,打开app时候,内容还没出来,app会被别的内容替代,这样很好的提升了用户体验.那么在webApp中,我们如何避免白屏的尴尬情况呢?可以通过 vue-skeleton- ...