进程的地址空间

目录

一.前言

二.虚拟地址空间

1.定义:

2.划分:

3.与物理地址进行映射

三.对虚拟地址空间的管理

1.总体上描述------mm_struct

2.各个区域数据的管理------vm_area_struct(VMA)

四.虚拟地址与物理地址进行动态映射

1.什么是页表

2.虚拟地址与物理地址进行动态映射过程举例

五.设计意义

1.合理规划内存:

2.规避使用风险,保护物理内存

3.降低系统的复杂程度


一.前言

我们已经知道操作系统将各种程序描述成进程形式,再进行组织起来运行,那么进程里的数据是被如何管理的呢?

我们本篇来讨论操作系统怎么对进程数据进行管理的。当然管理仍然是先组织,再描述。

我们在学习编程语言时,学习过数据在内存中存储的形式:

实际中物理地址没有这样的区域划分,物理地址仅仅是连续的,并且交给操作系统统一管理的,区域划分是为进程设计的虚拟地址空间。

二.虚拟地址空间

1.定义:

每个程序运行时,都会拥有一套独有的、隔离的虚拟内存地址,进程只能操作这套虚拟地址,不能直接访问物理内存。

2.划分:

用户地址空间(3G):进程自身拥有,运行用户态代码,权限受限(无法访问硬件或内核资源)。

内核地址空间(1G):全局唯一,所有进程共享同一份内核虚拟地址,仅内核态可访问,存放操作系统核心数据(可访问硬件资源,执行敏感操作)。

3.与物理地址进行映射

虚拟地址空间通过页表和内存管理单元MMU机制与物理地址空间进行动态映射。

三.对虚拟地址空间的管理

内核通过一套数据结构 + 系统调用 + 硬件分页机制统一对虚拟地址进行管理,分为三层:描述整个地址空间、划分内存区域、页表虚实映射。

1.总体上描述------mm_struct

定义:每个进程 task_struct 里有成员 struct mm_struct *mm,代表完整虚拟地址空间。

内容:

计数:mm_users /mm_count(生命周期)

VMA 管理:链表 + 红黑树 + mmap_sem(管理所有虚拟分区)

分段地址:代码 / 数据 / 堆 / 栈边界

页表根 pgd:虚实映射硬件支撑

内存统计:rss、total_vm、swap_vm

全局链表节点 mmlist:内核统一管理全部进程 mm

现在我们主要认识的就是mm_struct记载虚拟地址空间内的各个数据地址起始和终止值,方便进程快速访问。

多个进程mm_struct管理:所有有效 mm_struct 通过全局双向链表统一串联管理;

2.各个区域数据的管理------vm_area_struct(VMA)

因为各个区域的数据的功能不同,所以使用多个VMA来分别描述。

结构:

复制代码
struct vm_area_struct {
    /* 1. 虚拟地址区间:左闭右开 [vm_start, vm_end) */
    unsigned long vm_start;
    unsigned long vm_end;

    /* 2. 归属该VMA的地址空间 mm_struct */
    struct mm_struct *vm_mm;

    /* 3. 双索引:双向链表 + 红黑树,用于mm快速管理所有VMA */
    struct vm_area_struct *vm_next, *vm_prev;  // 双向链表,按地址升序
    struct rb_node vm_rb;                     // 红黑树节点,用于地址快速查找

    /* 4. VMA权限/属性标志位(核心) */
    unsigned long vm_flags;

    /* 5. 文件映射相关:文件对象 + 文件内页偏移 */
    struct file *vm_file;
    loff_t vm_pgoff;  // 单位:页,文件映射起始偏移

    /* 6. 匿名内存COW核心链表,fork写时复制依赖 */
    struct anon_vma_chain *anon_vma_chain;

    /* 7. VMA操作回调函数集:缺页、关闭、修改权限等 */
    const struct vm_operations_struct *vm_ops;

    /* 8. 私有数据,设备驱动自定义使用 */
    unsigned long vm_private_data;
};

多个VAM管理形式:

  1. 当虚拟区间较少时采取单链表,由mmap指针指向这个链表;

  2. 当虚拟区间多时采取红黑树进行管理,由mm_rb指向这棵树;

四.虚拟地址与物理地址进行动态映射

1.什么是页表

页表就是内核维护的一张映射表:记录"虚拟页 → 物理页框"的对应关系,配合硬件 MMU 完成地址翻译。

特点:每个用户进程拥有一套页表,互不干扰

2.虚拟地址与物理地址进行动态映射过程举例

我们创建一个变量val,如何fork一个子进程,改变val的原来值,观察其地址变化

结果:

val值改变了,但是地址值没有变化!!!

我们使用映射过程来解释:

1.创建子进程时,系统会将父进程的所有数据拷贝一份给子进程,包括虚拟地址以及对应关系------页表,所以子进程会拥有相同的虚拟地址,页表的对应关系也没有改变。

2.子进程改变变量值,系统会重新申请一块空间给子进程的该变量,这时子进程的虚拟地址值不变,但是页表上对应的物理地址改变。

五.设计意义

1.合理规划内存:

1.按区域存放数据,防止进程使用混乱

2.可以清晰管理数据,提高效率

2.规避使用风险,保护物理内存

1.进程使用数据需要经过映射过程,这个期间,内核就可以对使用权限进行审查。

2.实现各个进程的物理内存隔离,防止进程访问不属于自己的物理空间。

3.降低系统的复杂程度

进程只与虚拟地址进行交互,对物理内存的操作由内核完成,互不干扰,各司其职,实现管理分层,降低了系统的复杂程度。

相关推荐
吴声子夜歌41 分钟前
Shell编程实例——编写安全的shell脚本(二)
linux·运维·shell
xiaoye-duck2 小时前
《Linux 网络编程》深入理解 IP 协议(二):网段划分、私有 IP 与 NAT 地址转换
linux·网络·ip
zx_741484813 小时前
【Linux入门】Shell 函数、正则表达式与文本处理:cut 与 awk
linux·运维·正则表达式
Zenova EdgeOS3 小时前
Linux dmesg 工业边缘实战:内核日志过滤、持久化与故障定位
linux·运维·边缘计算·工业边缘·dmesg·内核日志
金士顿4 小时前
System.Text.Json Source Generator 深度解析:为什么 Native AOT 不喜欢反射
linux·asp.net core·arm64·net·native aot
做运维的阿瑞5 小时前
Python 标准库汇总:分类速览与常用模块清单
linux·运维·python
百万蹄蹄向前冲5 小时前
密码都对Node.js却连不上Linux数据库
linux·mysql
彧azz5 小时前
Linux 网络编程学习总结
linux·网络·笔记·学习·面试
susplus6 小时前
【ARM 裸机开发 (IMX6ULL-mini)】GNU工具、Makefile 工程构建、链接脚本详解|C 语言点灯 + 蜂鸣器驱动
linux·arm·makefile·imx6ull
Shadow(⊙o⊙)6 小时前
Linux进阶知识1.0
linux·运维·服务器