《深入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.mzph.cn/diannao/8865.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自注意力架构大成者_Transformer(Pytorch 17)

1 模型简介 在上节比较了 卷积神经网络(CNN)、循环神经网络(RNN)和 自注意力(self‐attention)。值得注意的是, 自注意力同时具有并行计算和最短的最大路径长度这两个优势。因此,使…

【微机原理及接口技术】存储器

【微机原理及接口技术】存储器 文章目录 【微机原理及接口技术】存储器前言一、半导体存储器技术1.半导体存储器概述2.半导体存储器的分类3.半导体存储器芯片的结构 二、半导体存储器芯片1.RAM芯片2.ROM芯片 三、半导体存储器与CPU的连接1.存储芯片数据线的连接2.存储芯片地址线…

webrtc初步了解

WebRTC搭建点对点实时音视频对话,起始需要保证完成两点: 1.媒体协商,了解彼此支持的媒体格式。参与视频通讯的双方必须先交换SDP信息,交换SDP的过程。 2.网络协商,了解彼此的网络环境,找到一条相互通讯的链…

Linux学习之禁用防火墙

查看防火墙状态 systemctl status firewalld.service 第一行前面的圆圈是有颜色的就是开启状态 黑色的就是关闭状态 关闭防火墙 systemctl stop firewalld.service 输入密码认证 再次查看防火墙状态 systemctl status firewalld.service 第一行前面的圆圈变成黑色说明关闭…

ThreeJS:补间动画与Tween.JS

补间动画 补间动画指的是做FLASH动画时,在两个关键帧中间需要做“补间动画”,才能实现图画的运动;插入补间动画后两个关键帧之间的插补帧是由计算机自动运算而得到的。 ——摘自《百度百科:补间动画_百度百科》 Tween.js Tween.js…

xCode升级后: Library ‘iconv2.4.0’ not found

报错信息: targets 选中 xxxNotification: Build Phases ——> Link Binary With Libraries 中,移除 libiconv.2.4.0.tbd libiconv.2.4.0.dylib 这两个库(只有一个的移除一个就好)。 然后重新添加 libiconv.tbd 修改完…

(代码以上传,超级详细)面试必备算法题----Leeecode290单词规律

文章目录 概要题目要求测试and提交结果技术细节 概要 来自Leecode ​ 代码已上传)仓库,需要测试实例和其他题型解决,可以去自行浏览 点击这里进入仓库领取代码喔!顺便点个star给原子加油吧! ​ 题目要求 使用哈希表 …

GD32F103RCT6/GD32F303RCT6(9)高级定时器互补PWM波输出实验

本文章基于兆易创新GD32 MCU所提供的2.2.4版本库函数开发 后续项目主要在下面该专栏中发布: 手把手教你嵌入式国产化_不及你的温柔的博客-CSDN博客 感兴趣的点个关注收藏一下吧! 电机驱动开发可以跳转: 手把手教你嵌入式国产化-实战项目-无刷电机驱动&am…

【设计模式】之观察者模式

系列文章目录 【设计模式】之装饰器模式【设计模式】之工厂模式(三种)【设计模式】之工厂模式(三种) 前言 今天给大家介绍另一种设计模式--观察者模式,有了解webscoket实现原理的小伙伴应该对这个设计模式不陌生。不清…

微服务核心01-Maven【项目管理工具】基础

一、Maven 简介 1.1 传统项目管理: 1.2 Maven 的作用 项目构建:提供标准的、跨平台的自动化项目构建方式。依赖管理:管理项目依赖的资源(jar 包),避免资源间的版本冲突问题统一开发结构:提供标…

Web LLM 攻击实验:利用 LLM API 实现 SQL 注入

前言 Web LLM 攻击 各组织都在急于集成大型语言模型 (LLM),以改善其在线客户体验。这使他们面临 Web LLM 攻击,这些攻击利用模型对攻击者无法直接访问的数据、API 或用户信息的访问权限。例如,攻击可能: 检索 LLM 有权访问的数…

【valse 2024】会议内容汇总(持续更新)

系列文章目录 提示:更新中,一周左右更新完毕。需要具体课件的可私信 文章目录 系列文章目录开幕式主旨报告-1:大模型时代的机遇和挑战主旨报告-2:以深度学习框架为牵引促进自主 AI生态发展主旨报告-3:从洞穴的影子到智能的光辉--连接和交互方式的改变塑造…

别出心裁的自动化网页数据采集:Chrome插件和mitmproxy

别出心裁的自动化网页数据采集:Chrome插件和mitmproxy 前言 在信息时代,数据已成为决策的关键。传统的数据采集方法往往依赖于手动操作或简单的自动化脚本,这限制了数据的时效性和精确性。为了克服这些限制,本文介绍了一种结合C…

文件批量移动:按路径名称指引,高效文件管理与批量归类实战

在数字化时代,文件批量移动成为了一项至关重要的技能,它能够帮助我们高效地管理和归类大量的文件。通过按路径名称指引进行文件批量移动,我们可以使文件组织更加有序,提高文件检索的速度,从而提升工作效率。 一、明确路…

多线程学习Day09

10.Tomcat线程池 LimitLatch 用来限流,可以控制最大连接个数,类似 J.U.C 中的 Semaphore 后面再讲 Acceptor 只负责【接收新的 socket 连接】 Poller 只负责监听 socket channel 是否有【可读的 I/O 事件】 一旦可读,封装一个任务对象&#x…

【建议收藏】CSP-J/S信奥赛,小白报名教程!

✅ 信奥介绍 信息学奥赛是五大学科(数学、物理、化学、生物、信息学)奥林匹克竞赛中唯一一个可以贯穿小学、初中、高中的特长生项目。由中国计算机学会主办,主要考察信息学,即编程的相关知识和能力。 ✅ 报名流程 👉登…

智能绘画系统源码系统 后台自由设置会员套餐 带网站的安装包以及安装部署教程

在当今数字化与智能化快速发展的时代,艺术与技术正以前所未有的速度相互融合。为了满足广大绘画爱好者和专业艺术家的需求,我们精心打造了一款智能绘画系统源码系统。该系统不仅具备高度的智能化特性,还提供了丰富的后台管理功能,…

CTF-密码学基础

概述 密码学(Cryptolopy):是研究信息系统安全保密的科学 密码学研究的两个方向: 密码编码学(Cryptography):主要研究对信息进行编码,实现对信息的隐蔽密码分析学(Cryptanalytics):主要研究加密信息的破译或消息的伪造…

多客陪玩系统源码APP小程序H5陪玩开发伴游源码游戏陪玩平台源码陪玩平台开发约单源码线下陪玩接单平台app小程序H5源码游戏陪玩app小程序H5开发

出售成品陪玩app小程序H5源码,免费搭建部署和售后服务,并提供源码二开、定制开发等相关服务。 一、陪玩app源码的功能介绍 1、语音聊天: 陪玩app小程序H5源码用户随时创建语音聊天室,实现多用户上麦功能,提高互动聊天体验。 2、游…

【Qt 开发基础体系】字符串类应用和常用的数据类型

文章目录 1. Qt 字符串类应用1.1 操作字符串1.2 QString::append()函数1.3 QString::sprintf()函数1.4 QString::arg()函数 2. 查询字符串2.1 函数 QString::startsWith()2.2 函数 QString::contains()2.3 函数 QString::toInt()2.4 函数 QString::compare()2.5 将 QString 转换…