linux进程的地址空间,核心栈,用户栈,内核线程

地址空间:

32位linux系统上,进程的地址空间为4G,包括1G的内核地址空间,和3G的用户地址空间。

内核栈:

进程控制块task_struct中保存了2个page大小的信息。

为什么每一个进程都是用各自的内核栈呢?

引用(http://hi.baidu.com/iruler/blog/item/0c3363f377ccc5c90a46e023.html)“

假设某个进程通过系统调用运行在内核态(使用这个全局内核堆栈),此时如果被抢占,发生一次切换,另一个进程开始运行,如果这个当前进程又通过系统调用陷入内核,那么这个进程也将使用这个全局内核堆栈,这样的话就把以前那个进程的内核空间堆栈给破坏了。
而如果进程使用独立的内核栈,就避免了这种情况的发生

内核线程:

拥有自己独立内核栈的调度单元,可以参与调度,在内核空间执行。

用户栈:

每一个线程有一个用户栈,由ss和esp指向。

===================================================

进程1                                进程2

内核代码区      kcode (0xc0001000)        
 kcode (0xc0001000)

内核栈区          kstack(0xc000F000)          kstack(0xc001F000)

内核栈区          kstack(0xc000D000)          kstack(0xc001D000)

...

内核数据区      kdata  (0xc0003000)          kdata  (0xc0003000)

---------------------------------------------------------------------------------------------

用户代码区      ucode  (0x70001000)        ucode (0x70001000)

用户栈区          ustack (0x7000F000)        ustack (0x7000F000)

用户栈区          ustack (0x7000D000)        ustack (0x7000D000)

...

用户数据区      udata   (0x70003000)        udata  (0x70003000)

===================================================

合理的解释:

内核1G空间的映射页表(256个entries*4M)只有一份,n个进程共享(都复制了一份在自己的进程页表内, 256个内核的entries+768个用户空间的entries, 总共1024个entries,假定使用4M页面,并且一开始就全都分配好)。

每个进程用户空间的这些entries各不相同,比如说,同样的0x70001000虚拟地址, 进程1指向物理内存0x2000, 而进程2指向0x1000。

每个线程对应的内核栈的虚拟地址不重叠。

thread1's kernel stack  = 0f000,

thread2's
kernel stack  = 0d000,

thread3's
kernel stack  = 1f000,

thread4's
kernel stack  = 1d000

...

思考1:

如果内核栈不是预先分配好的(分
配的意思是指"在内核空间中分出一段一段不重叠空间作为各个线程的栈", e.g. kmalloc调用),那么步入内核态的时候,
压栈,发生缺页异常,必须对内核栈占用的这个页进行换页,而换页历程的调用必然涉及参数的压栈出栈,而这个时候内核栈没有就绪,异常发生嵌套,系统出错!

思考2:

在内核里面做kmalloc是可以的,添加一个entries,关联一块物理内存,ok可以用了。

思考3:

如果希望进程共享某一个虚拟内存地址0x80001000的数据, 那么在需要共享的进程p1,p2的页表中添加1个entries(0x80001000->0x3000)。

另外内核是天然的共享对象,所以才在每一个进程中页表中设置内核空间页表的一份拷贝。

如果有个家伙特立独行,创建n个关于内核空间的页表,指向n个物理内存块,那么他就需要再在这n个物理内存中"铺设"n分内核代码和数据的副本(真是自找麻烦)。

思考4:

内核栈确实不适合共享(一个特殊的内存区域)。怎么办?像用户空间栈一样固定在某一个虚拟地址,安插页表项entries指向不同的物理内存?显然不行! 只有一个办法,在内核空间内分配n个不重叠的空间出来。

思考5:

内核步入的时候最初的“内核栈”并不是真正的内核栈,这个栈是全局的,每个cpu一个,是过渡到真正的内核栈使用的。(http://bbs.pediy.com/archive/index.php?t-87518.html)

思考6:

独立内核栈的场景, at first 我们分析一下如果共用一个内核栈会出现什么情况,假设有A、B三个进程,A调用系统调用read(1,...)读按键,此时正好又没有按键,
所以A被阻塞在内核,此时内核调度B执行,此时B也调用一个系统调用被阻塞了,而此时按键事件到来,进程A被唤醒,A继续执行。我们想想B进入内核
已经破坏了A进入内核的内核栈,那此时A能正常返回吗?所以从上面分析A、B肯定是拥有各自的内核栈。此内核栈好像是和task_struct以前分配的
一共分配了3个页面,除了task_struct占得内存外,其余的就是内核栈。而在x86上这个栈等指针保存在TSS断的SS0和Esp0中。(http://bbs.chinaunix.net/thread-1930753-1-1.html)

参考资料:

1, 内核栈的使用(http://tech.ddvip.com/2008-09/122095404362368.html)

linux进程的地址空间,核心栈,用户栈,内核线程的更多相关文章

  1. linux进程虚拟地址空间

    转载源 在多任务操作系统中,每个进程都运行在属于自己的内存沙盘中.这个沙盘就是虚拟地址空间(Virtual Address Space),在32位模式下它是一个4GB的内存地址块.在Linux系统中, ...

  2. Linux进程虚拟地址空间管理2

    2017-04-12 前篇文章对Linux进程地址空间的布局以及各个部分的功能做了简要介绍,本文主要对各个部分的具体使用做下简要分析,主要涉及三个方面:1.MMAP文件的映射过程 2.用户 内存的动态 ...

  3. LInux进程虚拟地址空间的管理

    2017-04-07 脱离物理内存的管理,今天咱们来聊聊进程虚拟内存的管理.因为进程直接分配和使用的都是虚拟内存,而物理内存则是有系统“按需”分配给进程,在进程看来,只知道虚拟内存的存在! 前言: 关 ...

  4. linux进程模型总结

    Linux进程通过一个task_struct结构体描述,在linux/sched.h中定义,通过理解该结构,可更清楚的理解linux进程模型.       包含进程所有信息的task_struct数据 ...

  5. Linux进程模型

    ----原文链接:http://www.cnblogs.com/biyeymyhjob/archive/2012/08/01/2617884.html------ Linux进程通过一个task_st ...

  6. Linux下的进程类别(内核线程、轻量级进程和用户进程)--Linux进程的管理与调度(四)

    本文中出现的,内核线程,轻量级进程,用户进程,用户线程等概念,如果不太熟悉, 可以参见 内核线程.轻量级进程.用户线程三种线程概念解惑(线程≠轻量级进程) Linux进程类别 虽然我们在区分Linux ...

  7. Linux内核线程kernel thread详解--Linux进程的管理与调度(十)

    内核线程 为什么需要内核线程 Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进程的种种合理以及不合理的请求). 内核需要多个执行流并行,为了防止可能的阻塞,支持多线程是必要的. 内核线程 ...

  8. Linux进程管理 (篇外)内核线程简要介绍

    关键词:kthread.irq.ksoftirqd.kworker.workqueues 在使用ps查看线程的时候,会有不少[...]名称的线程,这些有别于其它线程,都是内核线程. 其中多数内核线程从 ...

  9. linux内核线程,进程,线程

    http://blog.csdn.net/dyllove98/article/details/8917197 Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起.( ...

随机推荐

  1. php ftp文件上传函数--新手入门参考

    在 php编程中,用ftp上传文件比较多见,这里分享个简单入门型的ftp上传实例. <?php /** * ftp上传文件 * 学习ftp函数的用法 */ // 定义变量 $local_file ...

  2. linux 文件属性

    关于属性的结构 在linux下文件和文件夹都被认为是文件, 所以以下的这个属性对文件和文件夹通用 获取属性的函数有stat/fstat/lstat/fstat struct stat{ mode_t ...

  3. ActiveMQ之TemporaryQueue和TemporaryTopic

    TemporaryQueue和TemporaryTopic,从字面上就可以看出它们是“临时”的目的地.可以通过Session来创建,例如: TemporaryQueue replyQueue = se ...

  4. MySQL 多实例给root用户创建密码

    DB:5.5.14 OS:CentOS 6.3 安装多实例MySQL数据库,安装完成后默认无密码,一次性给所有实例的root账户创建密码: #!/bin/bash for i  in {3361..3 ...

  5. Javascript Array.prototype.some()

    当我们使用数组时,查找数组中包含某个特殊的项是非常常见的动作.下面例子是一个简单的实现: 01 planets = [ 02     "mercury", 03     " ...

  6. Express/Koa/Hapi

    Express/Koa/Hapi 本文翻译自: https://www.airpair.com/node.js/posts/nodejs-framework-comparison-express-ko ...

  7. 64bit Ubuntu, Android AAPT, R.java

    Ubuntu 13.10 aapt: error while loading shared libraries: libstdc++.so.6: cannot open shared object f ...

  8. MITK Tutorial(二)

    目标: 生成MITK 插件包括一个新用户交互的视图,并调用一些ITK filters. Step 1: How to create a new MITK Plugin 可以选择用Plugin Gene ...

  9. Careercup - Facebook面试题 - 4713484755402752

    2014-05-02 00:30 题目链接 原题: Given two arrays of sorted integers, merge them keeping in mind that there ...

  10. Java 集合类(一)

    今天我们先讲一下Collection: Collection和Collections的区别: java.util.Collection是一种java集合接口,它提供了对集合对象的基本操作通用接口方法, ...