Linux内核之进程地址空间

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情
1.进程地址空间概念:

进程使用的是虚拟内存中的地址,也叫线性地址,由操作系统协助相关硬件(如MMU),映射到物理地址。线性地址是通过页表(Page Table)映射到物理内存,页表由操作系统维护并被处理器引用。内核空间在页表中拥有较高特权级,因此用户态程序试图访问这些页时会导致一个页错误。在Linux中,内核空间是持续存在的,并且在所有进程中都映射到同样的物理内存。内核代码和数据总是可寻址,随时准备处理中断和系统调用。与此相反,用户模式地址空间的映射随进程切换的发生而不断变化。在32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G-4G是内核空间。其实,这个4G的地址空间是不存在的,也就是我们所说的虚拟内存空间。

2.进程地址空间、内存描述符、线性区链表关系:

进程地址空间由允许进程使用的全部线性地址组成,与进程地址空间有关的全部信息都包含在一个叫做内存描述符的数据结构中,这个结构的类型为mm_struct。Linux通过类型为vm_area_struct的对象实现线性区,每个线性区描述符表示一个线性地址空间,进程所拥有的线性区从不重叠,并且内核尽力把新分配的线性区与紧邻的现有线性区进行合并。如果两个相邻区的访问权限匹配,就能把他们合并在一起。下图描述了进程地址空间、内存描述符、线性区链表之间的关系:

进程地址空间、内存描述符、线性区链表之间的关系

内核频繁执行的一个操作就是查找包含指定线性地址空间的线性区,为了提高效率Linux2.6把内存描述符存放在叫做红黑树(read-black-tree)的数据结构中。为了存放进程的线性区,linux既使用了链表,又使用了红黑树,一般的,红黑树用来确定含有指定地址的线性区,而链表通常在扫描整个线性区集合时使用。线性区的大小是4KB的倍数(必须包含完整的页),而栈的大小却是任意的。c语言中的每个段空间就是通过vm_area_struct表示,他们关系如下 :

程序中段到物理地址的映射
当一个程序被执行时,该程序的内容必须被放到进程的虚拟地址空间(注意,是虚拟地址空间),对于可执行程序的共享库也是如此。可执行程序并非真正读到物理内存中,而只是链接到进程的虚拟内存中(此时都是在进程的虚拟地址空间)。当一个可执行程序映射到进程虚拟地址空间时,一组vm_area_struct数据结构将被产生。每个vm_area_struct数据结构表示可执行印象的一部分;是可执行代码,或是初始化的数据,以及未初始化的数据等。

3.请求调页和缺页异常:

请求调页是 一种动态内存分配技术,它把页框的分配推迟到不能再推迟为止。这种技术的动机是:进程开始运行的时候并不访问地址空间中的全部内容。事实上,有一部分地址 也许永远也不会被进程所使用。程序的局部性原理也保证了在程序执行的每个阶段,真正使用的进程页只有一小部分,对于临时用不到的页,其所在的页框可以由其 它进程使用。因此,请求分页技术增加了系统中的空闲页框的平均数,使内存得到了很好的利用。从另外一个角度来看,在不改变内存大小的情况下,请求分页能够 提高系统的吞吐量。当进程要访问的页不在内存中的时候,就通过缺页异常处理将所需页调入内存中。

CPU通过地址总线可以访问连接在地址总线上的所有外设,包括物理内存、IO设备等等,但从CPU发出的访问地址并非是这些外设在地址总线上的物理地址,而是一个虚拟地址,由MMU将虚拟地址转换成物理地址再从地址总线上发出,MMU上的这种虚拟地址和物理地址的转换关系是需要创建的,并且MMU还可以设置这个物理页是否可以进行写操作,当没有创建一个虚拟地址到物理地址的映射,或者创建了这样的映射,但那个物理页不可写的时候,MMU将会通知CPU产生了一个缺页异常。
下面总结下缺页异常的几种情况:

  • 当MMU中确实没有创建虚拟页物理页映射关系,并且在该虚拟地址之后再没有当前进程的线性区vma的时候,可以肯定这是一个编码错误,这将杀掉该进程;
  • 当MMU中确实没有创建虚拟页物理页映射关系,并且在该虚拟地址之后存在当前进程的线性区vma的时候,这很可能是缺页异常,并且可能是栈溢出导致的缺页异常;
  • 当使用malloc/mmap等希望访问物理空间的库函数/系统调用后,由于linux并未真正给新创建的vma映射物理页,此时若先进行写操作,将如上面的2的情况产生缺页异常,若先进行读操作虽也会产生缺页异常,将被映射给默认的零页(zero_pfn),等再进行写操作时,仍会产生缺页异常,这次必须分配物理页了,进入写时复制的流程;
  • 当使用fork等系统调用创建子进程时,子进程不论有无自己的vma,“它的”vma都有对于物理页的映射,但它们共同映射的这些物理页属性为只读,即linux并未给子进程真正分配物理页,当父子进程任何一方要写相应物理页时,导致缺页异常的写时复制;

目前来看,应该就是这四种情况,还是比较清晰的,可发现一个重要规律就是,linux是直到实在不行的时候才会分配物理页。从用户空间的缺页异常分为两种情况:

  • 触发异常的线性地址处于用户空间的vma中,但还未分配物理页,如果访问权限没问题的话内核就给进程分配相应的物理页了;
  • 触发异常的线性地址不处于用户空间的vma中,这种情况得判断是不是因为用户进程的栈空间消耗完而触发的缺页异常,如果是的话则在用户空间对栈区域进行扩展,并且分配相应的物理页,如果不是则作为一次非法地址访问来处理,内核将终结进程。

缺页处理函数为arch/arm/mm/fault.c文件中的do_page_fault函数。

linux内核--进程地址空间(三) 引言:上篇博文中,我们简单的介绍了Linux虚拟存储器的概念及组成情况,下面来分析分析进程的创建和终结及跟进程地址空间的联系。 这里首先介绍一个比较重要的概念:存储器映射 在Linux系统中,通过将一个虚拟存储器区域与一个磁盘上的对象关联起来,以初始化这个虚拟存储器区域的内容,这个过程称为存储器映射。存储器映射为共享数据、创建新的进程以及加载程序提供了一种高效的机制。 虚拟存储器区域可以映射 阅读详情

相关推荐

保姆级教程:从Salmon输出到DESeq2,搞定RNA-seq表达矩阵标准化与下游分析准备

本文提供从Salmon输出到DESeq2标准化的RNA-seq数据分析全流程指南,详细解析表达矩阵构建、标准化方法选择及下游分析准备。重点介绍如何将Salmon定量结果转换为DESeq2兼容格式,包括TPM与原始计数的处理技巧,以及常见问题排查方法,帮助研究人员高效完成RNA-seq数据分析。

weixin_42699679的博客 271

进程地址空间

进程需要访问内存时,操作系统会通过PCB中的内存管理信息来查找对应的物理内存地址,并检查访问权限等信息,以确保内存访问的安全性和正确性。2、将内存申请与内存使用的概念在时间上划分清楚,通过虚拟地址空间来屏蔽底层申请内存的过程,达到进程读写内存和操作系统管理操作进行软件层面上的分离目的,让应用和内存管理解耦。1.父子进程有着各自的mm_struct,其成员起始值是一致的,对于同一个变量,如果并未进行改写,那么俩者的的虚拟地址将会通过页表+MMU转换后指向同一块物理空间。

2301_79991997的博客 804

华为OD机试真题新系统-空间占用计算(Py/Java/C/C++/Js/Go)

华为OD机试新系统机试真题 【空间占用计算】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【空间占用计算】。

qq_45776114的博客 3240

linux 进程的页表,内核页表和进程页表

2015 May 28 pagetable,kernel,userspace内核页表和进程页表内核页表和进程页表最近在看vmalloc()分配代码,我们知道当通过alloc_page()分配出来page后,需要将这些分散的物理页框page映射到vmalloc区,这里我们就要修改内核页表,以前我学页表是把内核空间与用户空间割裂学习的,导致二者无法很好地衔接,这里我会把两个概念重新解释清楚。下面代码映...

weixin_33520805的博客 1295

Linux进程地址空间

总结:• 变量内容不一样,所以父子进程输出的变量绝对不是同一个变量• 但地址值是⼀样的,说明该地址绝对不是物理地址• 在Linux地址下,这种地址叫做虚拟地址• 我们在⽤C/C++语⾔所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由操作系统统一进行管理注意:操作系统必须负责将虚拟地址转化成物理地址。

2501_91740090的博客 156

进程页表与内核页表:页表的初始化

摘要:linux刚刚加电启动时,如何从实模式进入保护模式?启动分页机制的前提是什么?如何保证分页机制之前和之后通过实地址和虚拟地址都能访问到同一个物理地址呢?内核页表是如何进行初始化的?用户进程不能访问内核的数据是在初始化的哪个阶段决定的?这些内容,都牵扯到linu的进程页表和内核页表,以及内核页表的初始化。本文也主要为你解答这些疑问. 本文来源:进程页表和内核页表:页表的初始化 1....

473687880 1297

基于内核栈切换的进程切换(李治军操作系统课实验5)

分析: TSS作用 找到当前内核栈:进程内核栈在线性地址空间中的地址是由该任务的TSS段中的ss0和esp0两个字段指定的,依靠TR寄存器就可以找到当前进程的TSS。也就是说,当从用户态进入内核态时,CPU会自动依靠TR寄存器找到当前进程的TSS,然后根据里面ss0和esp0的值找到内核栈的位置,完成用户栈到内核栈的切换。TSS是沟通用户栈和内核栈的关键桥梁,这一点在改写成基于内核栈切换的进程切...

weixin_41761478的博客 3355

Linux内核-进程地址空间

进程地址空间进程可寻址的虚拟内存组成,最为重要的是内核允许进程使用这种虚拟内存中的地址。

affrewg的博客 743

Linux内核进程地址空间

文章目录概述内存描述符虚拟内存区域用户空间常用的操作页表 概述 1.所谓进程地址空间,就是从进程的视角看到的地址空间 2.在Linux中,每个进程都有自己独立的虚拟地址空间,在32位模式下它是4GB的内存块 3.Linux内核进程和用户进程所占虚拟内存比例是1:3 4.用户空间的进程只能访问整个虚拟地址空间0-3GB的部分,不能访问3GB-4GB的部分 5.当进程地址空间被共享的时候,就是多线程了 内存描述符 1.mm_struct表示了进程地址空间的全部信息,叫做内存描述符,其中两个最重要的属性: mm

屎蛋的铲屎官 433

Linux内核——进程地址空间

一.概述 当内核函数请求内存时,内核不会对该请求进行推迟,会立刻得到。而对于用户态进程内核会认位其请求不是十分紧迫的(因为进程开始运行时并不会立刻访问其地址空间中的全部内存),且内核不信任用户代码,需要捕获并处理用户态进程引起的寻址错误,因而当用户进程请求动态内存时,并未获得请求的页框,而仅仅获得对一个新的线性地址区间的使用权,即这一线性地址成为进程地址空间的一部分,真正分配页框会推...

qq_34228327的博客 562

Linux进程概念——下】验证进程地址空间的基本排布 | 理解进程地址空间 | 进程地址空间如何映射至物理内存(页表的引出) | 为什么要存在进程地址空间 | Linux2.6内核进程调度队列

文章目录【写在前面】一、程序地址空间二、进程地址空间三、 【写在前面】 一、程序地址空间 这个概念比较重要,之前我们也涉及过 —— 我们在语言上定义的各种变量等在内存中的分布情况,如果没有听说过,那么你的 C/C++ 是不可能学好的。 其实对于这块,我们一直是有误区的。 二、进程地址空间 三、 ...

DanceBit的博客 1635

linux内核分析之进程地址空间

本文主要介绍linux内核进程地址空间的数据结构描述,包括mm_struct/vm_area_struct。进程线性地址区间的分配流程,并对相应的源代码做了注释。  内核中的函数以相当直接了当的方式获得动态内存。当给用户态进程分配内存时,情况完全不同了。进程对动态内存的请求被认为是不紧迫的,一般来说,内核总是尽量推迟给用户态进程分配内存。由于用户进程时不可信任的,因此,内核必须能随时准备捕获用

bullbat的专栏 3437

Linux内核原理之进程地址空间

文章目录进程地址空间简介进程虚拟地址空间进程地址空间的布局内存映射的原理数据结构树和链表虚拟内存区域的表示优先查找树对区域的操作address_space内存映射创建映射删除映射反向映射数据结构建立逆向映射 进程地址空间 用户层进程的虚拟地址空间Linux的一个重要抽象:它向每个运行进程提供了同样的系统视图,使得多个进程可以同时运行,而不会干扰其他进程内存中的内容 简介 本章主要关注用户管理虚拟地址空间的方法 每个应用程序都有自身的地址空间,与所有其他应用程序分隔开 在巨大的线性结构地址空间中,只有很少

Making-It 755

linux进程地址空间内核,Linux进程内核地址空间

一、 Linux采用了虚拟内存管理技术,使得每个进程都有独立的进程地址空间,该空间是大小为3G,用户看到和接触到的都是虚拟地址。利用这虚拟地址,不但能保护操作系itongde作用,更重要的是用户程序可使用比实际物理地址内存更大的地址空间。二、inux将4G的虚拟地址空间划分为2部分---用户空间与内核空间用户空间从0到0xbfffffff,内核空间从3G到4G,用户进程通常情况下只能访问用户空间的...

weixin_39592315的博客 156

可重入内核进程地址空间--深入理解linux内核

可重入内核,是指多个进程可以同时处于内核态下,也就是说可以多个进程可以并发的执行内核代码。对于但处理器来说某一时刻只能有一个进程被CPU处理,其他处于内核态的进程处于阻塞或者挂起等待状态。 对于linux来说,可重入内核代码包含可重入函数和非可重入函数。可重入函数是指运行时只改变局部数据结构,不改变全局数据结构;不可重入函数是指运行该函数时也需要改变全局数据结构。 所以,如果有多个进程进入不可重

j123kaishichufa的专栏 2175

Linux】——进程地址空间 && Linux2.6内核进程调度队列

世上有两种耀眼的光芒,一种是正在升起的太阳,一种是正在努力学习编程的你!一个爱学编程的人。各位看官,我衷心的希望这篇博客能对你们有所帮助,同时也希望各位看官能对我的文章给与点评,希望我们能够携手共同促进进步,在编程的道路上越走越远!提示:以下是本篇文章正文内容,下面案例可供参考联想你上学期间与同桌的三八线。用计算机语言来进行描述:要管理地址空间,要先对地址空间进行描述。地址空间本质是内核的一个struct结构体!内部很多的属性都是表示start,end的范围。

2301_79585944的博客 1222

linux进程地址空间内核,Linux内核辨析 之 进程地址空间(一)

Linux内核剖析 之 进程地址空间(一)绪论内核获取内存方式——直接了当:1.从分区页框分配器获取内存(__get_free_pages()或alloc_pages());2.使用slab分配器为专用或通用对象分配内存(kmem_cache_alloc()或kmalloc());3.使用vmalloc或vmalloc_32获取一块非连续内存区。如果申请的内存得以满足,这些函数返回一个页描述...

weixin_34593388的博客 318

Linux进程地址空间内核空间

本文介绍了操作系统中的内核空间和时钟中断机制。内核空间是操作系统内核在虚拟内存中的专属区域,所有进程共享同一内核空间但用户程序无法直接访问。用户程序通过系统调用与内核交互,触发CPU从用户态切换到内核态。内核空间具有高特权级,运行在Ring0级别,能直接访问硬件资源。时钟中断是操作系统的核心机制,它周期性地触发中断处理程序,实现进程调度、时间维护和资源统计。每次中断都会强制CPU执行内核代码,检查时间片并可能切换进程。这两个机制共同保障了系统的安全性、多任务处理能力和资源管理效率。

wefg1的博客 774

进程地址空间Linux内核源码分析)

背景之前写过关于内存管理源码分析的博客。大体介绍了什么是页、区、slab缓存,以及内核获取、释放页的接口,分配、释放slab缓存的接口。进程地址空间简单的说就是用户空间中进程的内存,我们叫这内存为进程地址空间。本篇博客借助linux源码大体分析进程地址空间的相关知识。进程控制块既然我们要聊一聊进程地址空间,那么不可避免的就要先聊一下进程控制块,进程控制块的概念想必大家不会陌生。一个进程是由一个进程

hty46565的博客 2954

linux内核进程虚拟地址空间管理

内核线程没有运行时,active_mm为空,当内核线程运行时,借用上一个进程的内存描述符,在被借用进程的用户虚拟地址空间的上方运行,进程描述符的成员active_mm指向借用的内存描述符,假设被借用的内存描述符所属的进程不属于线程组,那么内存描述符的成员mm_users不变,仍然是1,成员mm_count加1变成2。如果两个进程属于同一个线程组,每个进程进程描述符的成员mm和active_mm都指向同一个内存描述符,内存描述符的成员mm_users是2、成员mm_count是1。

wwwlyj123321的博客 1981
上一篇: Linux内核之进程
下一篇: Linux内核之进程调度
武林麦客
博客等级 码龄16年 3粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值