《深入Linux内核架构》第4章 进程虚拟内存(2)

目录

4.3 内存映射原理

4.4 数据结构

4.4.1 树和链表

4.4.2 虚拟内存区域VMA的表示

4.4.3 相关数据结构


本专栏文章将有70篇左右,欢迎+关注,查看后续文章。

本节讲VMA结构体struct vm_area_struct和struct address_space。

4.3 内存映射原理

所有进程的虚拟空间总和比物理内存大得多,因此只有最常用的虚拟空间才映射到物理内存。

当访问一个未映射物理内存的虚拟内存时,进行按需调页。

按需调页步骤:

        进程访问用户空间虚拟地址,但无法通过页表找到对应物理地址。

        CPU触发缺页异常。

        通过虚拟地址对应address_space结构体,找到磁盘数据。

        分配物理内存页,读取磁盘数据到内存。

        建立正确页表,进程恢复执行。

后续详解。

4.4 数据结构

struct mm_struct:提供了进程在内存布局的所有必要信息。

struct mm_struct {

        ...

        struct vm_area_struct         *mmap;         链表,用于遍历该进程所有vma

        struct rb_root                       mm_rb;         红黑树,用于查找和插入该进程vma

        struct vma_area_struct        *mmap_cache;         缓存上一次find_vma结果

        ...

}

4.4.1 树和链表

每个区域(VMA)都用一个vm_area_struct表示,如代码段,数据段,堆,栈。

一个进程的所有VMA同时有两种排序方式:

        1. 单链表:mm_struct->mmap

                VMA根据起始地址以递增顺序放入mm_struct->mmap链表。

                作用:链表使用于遍历VMA。

        2. 红黑树:根节点为mm_struct->mm_rb

                VMA太多时,查找/插入操作等用红黑树更快。

4.4.2 虚拟内存区域VMA的表示

虚拟内存区域:即VMA。如:

        一个进程空间的代码段,数据段,堆,栈,mmap映射区域等。

每个VMA用struct vm_area_struct实例表示。

应用层哪些操作时会生成一个VMA:

        mmap函数。

        运行可执行文件或共享库。

        堆栈增长。

        shmat创建共享内存。

        malloc函数大内存。

两种映射:

        1. 匿名映射:没有对应映射的文件,如:

                堆,栈,mmap的MAP_ANONYMOUS类型映射。

                创建映射方法:

                        void *addr = mmap(NULL, size, PROT_READ|PROT_WRITE,                                 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); //fd为-1

        2. 文件映射:有对应映射源文件,如:

                数据段,代码段(对应可执行文件的.data和.text section)。

                创建映射方法:

                        void *addr = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);

struct vm_area_struct {

        struct mm_struct         *vm_mm;         

                所属mm_struct

       

         unsigned long              vm_start,vm_end;         

                该vma起始与结束地址

        

        struct vm_area_struct         *vm_next, *vm_prev;

                mm_struct中vma链表中前/后一个VMA(如上图)

      

          pgprot_t                 vm_page_prot;

        unsigned long         vm_flags;

        struct rb_node         vm_rb;

        union {

                struct {

                        struct rb_node rb;

                        unsigned long rb_subtree_last;

                } linear;

                struct list_head nonlinear;

        } shared;

        struct list_head           anon_vma_chain;

        struct anon_vma         *anon_vma;

        struct vm_operations_struct         *vm_ops;

        

        unsigned long         vm_pgoff;

                映射的文件位置的偏移量。

                若映射整个文件则为0。

        struct file         *vm_file;

                表示被映射的文件。

               若匿名映射,则为NULL。

}

成员解释:

1. pgprot_t vm_page_prot:

        该vma对应物理页的权限。值有:

                PROT_READ:允许读取页面。

                PROT_WRITE:允许写入页面。

                PROT_EXEC:允许执行页的代码。

                PROT_NONE:不允许任何访问。

        用法:entry = mk_pte(page, vma->vm_page_prot); //生成对应权限的页表项。

2. vm_flags:

        该VMA访问权限。值有:

                VM_READ,VM_WRITE,VM_EXEC:可读,可写,可执行

                VM_SHARD:该VMA由多进程共享。

                VM_PRIVATE:该VMA是私有的

                VM_MAYREAD:可设置为可读。

                VM_GROWSUP:该VMA向上扩展,如栈。

                VM_DONTCOPY:fork函数时不复制该VMA。

        根据VMA的访问权限(vm_flags)获取对应页面的保护权限(vm_page_prot)

                vma->vm_page_prot = vm_get_page_prot(vma->vm_flags) ;

3. struct vm_area_struct *vm_next, *vm_prev;

        mm_struct中struct vm_area_struct * mmap:是一个链表头。

                链表作用:连接了该进程的所有vma,便于遍历VMA。

        vm_prev:前一个VMA

        vm_next:后一个VMA

        注意:VMA地址递增排序。

4. struct rb_node vm_rb;

        mm_struct中struct rb_root mm_rb:一个红黑树根节点。

                mm_rb作用:

                        包含该进程的所有VMA到红黑树中,便于高效查询VMA。

        vm_rb:树节点,用于插入到红黑根节点中。

5. union {

        struct {

                struct rb_node rb;                 线性映射

                unsigned long rb_subtree_last;

        } linear;

        struct list_head nonlinear;         非线性映射

} shared;

用于文件映射的VMA:

1. VMA是线性映射

        struct rb_node rb作用:

                将该VMA插入到以address_space->i_mmap为根结点的红黑树。

2. VMA是非线性映射(即该VMA映射到多个非连续的物理内存区域。)

        struct list_head nonlinear作用:

                将该VMA连接到address_space->i_mmap_nonlinear链表中。

address_space作用:

        同一文件被映射到不同进程,有多个VMA。

        address_space通过红黑树或链表管理所有VMA。

        所以通过address_space,可知道一个文件被映射到哪些VMA。

线性映射:

        将虚拟地址简单偏移得到物理地址。如文件和共享库的映射。

非线性映射:

        被映射到多个非连续物理内存。如大文件映射。

6. struct list_head anon_vma_chain

        struct anon_vma *anon_vma

        (后续章节详解)

        刚创建子进程后,父子进程会共享相同地址空间,包括匿名页。

        管理共享同一匿名页的所有VMA。

匿名页时,stuct page->struct address_space *mapping不是指向struct address_space,而是struct anon_vma。

struct address_space管理文件映射的VMA,而struct anon_vma管理匿名映射的VMA。

如何找到映射该匿名页的所有VMA:

page -> struct anon_vma -> struct anon_vma_chain -> VMA

7. struct vm_operations_struct vm_ops:

        该VMA的操作函数。

        struct vm_operations_struct {

                void (*open)(struct vm_area_struct * area);

                void (*close)(struct vm_area_struct * area);

                        创建/删除vma,不常用,设为NULL。

                int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);

        };

fault函数使用场景:

        缺页异常:

                某虚拟地址没有分配对应物理页,触发缺页异常。

                执行fault函数,分配页,并读取数据到页中。

        写时复制COW:

                向只读映射写数据时,触发写时复制。

                执行fault函数,分配页作为副本并写入数据,不影响其他进程共享页面。

        共享页面拷贝:

                进程尝试写共享页时,fault将创建分配页,作为私有副本,并写入数据。

多进程共享同一物理页可节约内存。使用场景:

        执行相同程序:可共享代码段的页。

        动态库:共享库的代码段和数据段。基于写时复制,同一变量在不同进程的值不同。

        文件映射:映射同一文件到多进程,如映射数据库系统。

        共享内存IPC:多进程映射同一内存,进行进程间通信。

4.4.3 相关数据结构

struct file:内核中表示一个打开的文件。

struct file {

        struct inode                         *f_inode;             对应磁盘文件

        struct address_space         *f_mapping;         该文件映射信息

}

struct address_space {

        struct inode                         *host;         缓存的磁盘文件

        struct radix_tree_root         page_tree;

                该树连接了缓存了文件host的所有页page。

        作用:

                1. 通过该树,可查找到缓存文件指定偏移index的页。

                2. 可知某文件指定偏移处是否被缓存。若缓存,直接操作页,不用从磁盘读取。

                        //radix_tree_insert(&mapping->page_tree, index, page);

        struct rb_root                    i_mmap;

                红黑树,连接该文件的线性映射的所有VMA。

        struct list_head                 i_mmap_nonlinear;

                链表,连接该文件的非线性映射的所有VMA。

        struct address_space_operations         *a_ops;

}

address_space作用:

        1. 关联了文件和映射该文件的页(页缓存)。

                即关联struct inode *host和struct radix_tree_root page_tree。

        2. 保存映射该文件所有VMA。

                即struct rb_root i_mmap树和struct list_head i_mmap_nonlinear链表。

struct inode {         inode对应一个磁盘文件

        struct address_space         *i_mapping;

}

struct file {                 file对应一个已打开的文件

        struct inode                         *f_inode;

        struct address_space         *f_mapping;

}

打开文件时:

        file->f_mapping = inode->i_mapping;

一个进程多次打开同一个文件,内核为每次打开创建一个struct file实例。

而struct inode只有一个。

struct inode和struct file都包含struct address_space。

通过address_space的host成员可找到文件inode。

再通过inode中主/次设备号找到块设备文件。

如何将文件1.c的从头偏移100到1000区域映射到内存中?

        fd = open("/tmp/1.c", O_RDONLY);

        mmap(NULL, 900, PROT_READ, MAP_PRIVATE, fd, 100);

除了映射文件,mmap还可直接映射raw设备。
        作用:绕过文件系统接口和文件缓冲区。
        fd = open("/dev/mtdlbock1", O_RDONLY);
        mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, offset);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/607337.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

k8s概述及核心组件

一、k8s概述 1.1 引言 docker compose 单机编排工具 有企业在用 docker swarm 能够在多台主机中构建一个docker集群 基本淘汰集群化管理处理工具 容器 微服务封装 dockerfile 编写成镜像 然后进行发布 dockerfile 可以写成shell脚本(函数做调…

【Linux网络编程】HTTPS协议

【Linux网络编程】HTTPS协议 目录 【Linux网络编程】HTTPS协议HTTPS介绍加密常见的加密方式HTTPS的工作过程探究(重点)常见问题完整流程总结 作者:爱写代码的刚子 时间:2024.5.9 前言:本篇博客将会介绍HTTPS协议 HTTPS…

【记录】常见的前端设计系统(Design System)

解释一下设计系统的定义,以及在国内,都有那些优秀的设计系统可以学习,希望可以帮到大家。 什么是设计系统(Design System)? 设计系统(Design System)是一套综合性的指导原则、组件和规则&…

VBA技术资料MF152:列出工作表中所有单元格的注释

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…

Linux进程——Linux环境变量

前言:在结束完上一篇的命令行参数时,我们简单的了解了一下Linux中的环境变量PATH,而环境变量不只有PATH,关于更多环境变量的知识我们将在本篇展开! 本篇主要内容: 常见的环境变量 获取环境变量的三种方式 本…

GORM数据库连接池对接Prometheus

一、背景与介绍 Golang的database/sql包定了关于操作数据库的相关接口,但是没有去做对应数据库的实现。这些实现是预留给开发者或者对应厂商进行实现的。 其中让我比较关注的是Golang的sql包有没有实现连接池pool的机制呢? 毕竟Golang是静态语言,类似J…

pwn(一)前置技能

以下是pwn中的题目(漏洞)类型: 关于pwn的学习: 一.什么是pwn?(二进制的漏洞) "Pwn"是一个俚语,起源于电子游戏社区,经常在英语中用作网络或电子游戏文化中的…

AI中转站计费平台系统源码一站式解决方案安装说明

AI中转站计费平台系统源码一站式解决方案安装说明 功能 | Features AI 联网功能 AI online searching service 多账户均衡负载 Multi-account load balancing HTTP2 Stream 实时响应功能 HTTP2 Stream real-time response function 节流和鉴权体系 Throttling and authenticati…

GitHub中Asterank源码python修改成C++(本人python不太会)

GitHub - typpo/asterank: asteroid database, interactive visualizations, and discovery tools 主要目的是在进行多元线性回归的时候将枚举型转换为数值型 python: # # The constants used in calculations for the values of asteroids. ## General constants GENERAL_I…

基于Detectron2的计算机视觉实践

书籍:Hands-On Computer Vision with Detectron2: Develop object detection and segmentation models with a code and visualization approach 作者:Van Vung Pham,Tommy Dang 出版:Packt Publishing 书籍下载-《基于Detectr…

.OpenNJet应用引擎实践——从 0-1 体验感受

目录 一. 🦁 写在前面二. 🦁 安装使用2.1 安装环境2.2 配置yum源2.3 安装软件包2.4 编译代码2.5 启动 三. 🦁 使用效果3.1 编辑配置文件3.2 编辑 HTML 代码 四. 🦁 使用感受 一. 🦁 写在前面 现在互联网体系越来越往云…

小丑的身份证和复印件 (BFS + Floyd)

本题链接:登录—专业IT笔试面试备考平台_牛客网 题目: 样例: 输入 2 10 (JOKERjoke #####asdr) 输出 12 思路: 根据题意,要求最短时间,实际上也可以理解为最短距离。 所以应该联想到有关最短距离的算法&…

css z-Index 详解--子元素盖在父元素的兄弟元素上

前置知识 1、z-index 只有在定位元素上才会生效&#xff08;即非static定位的元素上&#xff09; 2、同级元素&#xff0c;无论是z-index 相同还是没设置。后面的元素层级比前面 3、元素上有 transform 属性 z-index 会失效 dom结构如下 // dom部分 <div><div id&quo…

latex algorithm2e 库学习总结

案例1 \documentclass{article}\usepackage{xeCJK} \usepackage[]{algorithm2e} %\usepackage{ctex} % 中文包\begin{document}\renewcommand{\algorithmcfname}{算法} % 把标题设置为“算法” \begin{algorithm…

html table thead打印时带重复表头不生效

今天做一个打印功能时要求每页都带相同的表头&#xff0c;使用的方式是table的thead标签来实现&#xff0c;结果发现thead里边的内容放多了之后只有第一页才会有表头。最后发现问题是 thead的内容不能超过table的25%。

实例分割——Mask R-CNN、YOLOV8、RTMDET、DeepLab四种实例分割算法比对

1.概述 1.1 语义分割与实例分割 实例分割和语义分割都是计算机视觉领域中图像分割的任务&#xff0c;它们在目标和方法上有一些区别&#xff1a; 语义分割&#xff1a; 语义分割的目标是对图像中的每个像素打上类别标签&#xff0c;即识别出图像中每个像素属于哪个预定义的…

云动态摘要 2024-05-09

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 [免费试用]即刻畅享自研SaaS产品 腾讯云 2024-04-25 涵盖办公协同、营销拓客、上云安全保障、数据分析处理等多场景 云服务器ECS试用产品续用 阿里云 2024-04-14 云服务器ECS试用产品续用…

YOLOv5,YOLOv7改进之结合​SOCA

1.SOCA moudle结构图 2,YOLOv5,YOLOv7改进之结合​SOCA 1.配置common.py文件 #SOCA moudle 单幅图像超分辨率 class Covpool(Function):@staticmethoddef forward(ctx, input):x = inputbatchSize = x.data.shape[0]dim = x.data.shape[1]h = x.data.shape[2]w = x.data.sha…

PLC学习笔记

PLC学习笔记 前言一、一些基操知识二、GX works2编程2.1 位逻辑1.2 中间寄存器1.3 PLC的扫描方式 总结 前言 我这个人真的是太渴望知识了~ 一、一些基操知识 一般X表示输入&#xff0c;Y表示输出。一般八个为一组X0~X7M表示中间寄存器&#xff0c;M0~M7时间T、计数C 二、GX …

短信群发公司

伴随着移动互联网和智能手机的普及&#xff0c;短信群发成为了企业与个人之间高效沟通的一种重要方式。短信群发公司应运而生&#xff0c;致力于为用户提供专业、安全、高效的群发服务。 服务内容 短信群发公司提供多样化的服务内容&#xff0c;满足不同用户的需求。短信群发公…
最新文章