linux内核编程之二:vm_area_struct结构体

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

 

结构体struct vm_area_struct

它表示的是一块连续虚拟地址空间区域,进程使用的,地址空间范围是0~3G,对应的物理页面都可以是不连续的

结构体struct vm_struct

表示一块连续虚拟地址空间区域。给内核使用,地址空间范围是(3G + 896M + 8M) ~ 4G,对应的物理页面都可以是不连续的

两者的区别是什么呢?

在Linux中,struct vm_area_struct表示的虚拟地址是给进程使用的,而struct vm_struct表示的虚拟地址是给内核使用的,它们对应的物理页面都可以是不连续的。struct vm_area_struct表示的地址空间范围是0~3G,而struct vm_struct表示的地址空间范围是(3G + 896M + 8M) ~ 4G。struct vm_struct表示的地址空间范围为什么不是3G~4G呢?

原来,3G ~ (3G + 896M)范围的地址是用来映射连续物理页面的,这个范围的虚拟地址和对应的实际物理地址有着简单的对应关系,即对应0~896M的物理地址空间,

而(3G + 896M) ~ (3G + 896M + 8M)是安全保护区域(例如,所有指向这8M地址空间的指针都是非法的),因此struct vm_struct使用(3G + 896M + 8M) ~ 4G地址空间来映射非连续的物理页面。

/*
 * This struct defines a memory VMM memory area. There is one of these
 * per VM-area/task.  A VM area is any part of the process virtual memory
 * space that has a special rule for the page-fault handlers (ie a shared
 * library, the executable area etc).
 * 此结构定义了内存VMM内存区域。 每个VM区域/任务中有一个。 VM区域是进程虚拟内存空间的任何部分,
 * 它具有页面错误处理程序的特殊规则(即共享库,可执行区域等)。
 */
struct vm_area_struct {
	/* The first cache line has the info for VMA tree walking.
	   第一个缓存行具有VMA树移动的信息 */
	
	unsigned long vm_start;		/* Our start address within vm_mm. 我们的起始地址在vm_mm内*/
	unsigned long vm_end;		/* The first byte after our end address within vm_mm. 我们的结束地址在vm_mm之后的第一个字节*/

	/* linked list of VM areas per task, sorted by address 
	   每个任务的VM区域的链接列表,按地址排序  */
	struct vm_area_struct *vm_next, *vm_prev;

	struct rb_node vm_rb;

	/*
	 * Largest free memory gap in bytes to the left of this VMA.
	 * Either between this VMA and vma->vm_prev, or between one of the
	 * VMAs below us in the VMA rbtree and its ->vm_prev. This helps
	 * get_unmapped_area find a free area of the right size.
	 * 此VMA左侧最大的可用内存间隙(以字节为单位)。在此VMA和vma-> vm_prev之间,
	 * 或者在VMA rbtree中我们下面的一个VMA与其->vm_prev之间。
	 * 这有助于get_unmapped_area找到合适大小的空闲区域。
	 */
	unsigned long rb_subtree_gap;

	/* Second cache line starts here. 
	   第二个缓存行从这里开始 */

	struct mm_struct *vm_mm;	/* The address space we belong to. 我们所属的address space*/
	pgprot_t vm_page_prot;		/* Access permissions of this VMA. 此VMA的访问权限 */
	unsigned long vm_flags;		/* Flags, see mm.h. */

	/*
	 * For areas with an address space and backing store,
	 * linkage into the address_space->i_mmap interval tree.
	 * 对于具有地址空间(address apace)和后备存储(backing store)的区域,
	 * 链接到address_space->i_mmap间隔树,或者链接到address_space-> i_mmap_nonlinear列表中的vma。
	 */
	struct {
		struct rb_node rb;
		unsigned long rb_subtree_last;
	} shared;

	/*
	 * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
	 * list, after a COW of one of the file pages.	A MAP_SHARED vma
	 * can only be in the i_mmap tree.  An anonymous MAP_PRIVATE, stack
	 * or brk vma (with NULL file) can only be in an anon_vma list.
	 * 在其中一个文件页面的COW之后,文件的MAP_PRIVATE vma可以在i_mmap树和anon_vma列表中。
	 * MAP_SHARED vma只能位于i_mmap树中。
	 * 匿名MAP_PRIVATE,堆栈或brk vma(带有NULL文件)只能位于anon_vma列表中。
	 */
	struct list_head anon_vma_chain; /* Serialized by mmap_sem &
					  * page_table_lock 由mmap_sem和* page_table_lock序列化*/
	struct anon_vma *anon_vma;	/* Serialized by page_table_lock 由page_table_lock序列化*/

	/* Function pointers to deal with this struct. 
	   用于处理此结构体的函数指针 */
	const struct vm_operations_struct *vm_ops;

	/* Information about our backing store: 
	   后备存储(backing store)的信息:*/
	unsigned long vm_pgoff;		/* Offset (within vm_file) in PAGE_SIZE units 以PAGE_SIZE为单位的偏移量(在vm_file中)*/
	struct file * vm_file;		/* File we map to (can be NULL). 我们映射到文件(可以为NULL)*/
	void * vm_private_data;		/* was vm_pte (shared mem) 是vm_pte(共享内存) */

	atomic_long_t swap_readahead_info;
#ifndef CONFIG_MMU
	struct vm_region *vm_region;	/* NOMMU mapping region NOMMU映射区域  */
#endif
#ifdef CONFIG_NUMA
	struct mempolicy *vm_policy;	/* NUMA policy for the VMA 针对VMA的NUMA政策 */
#endif
	struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
} __randomize_layout;

linux内核使用vm_area_struct结构来表示一个独立的虚拟内存区域,由于每个不同质的虚拟内存区域功能和内部机制都不同,因此一个进程使用多个vm_area_struct结构来分别表示不同类型虚拟内存区域。各个vm_area_struct结构使用链表或树形结构链接,方便进程快速访问,如下图所示:
在这里插入图片描述

vm_area_struct结构中包含区域起始终止地址以及其他相关信息,同时也包含一个vm_ops指针,其内部可引出所有针对这个区域可以使用的系统调用函数。这样,进程对某一虚拟内存区域的任何操作需要用要的信息,都可以从vm_area_struct中获得。mmap函数就是要创建一个新的vm_area_struct结构,并将其与文件的物理磁盘地址相连

linux内核学习笔记——VMALLOC 位置:vmalloc区位是一段虚拟地址空间,位于内核地址空间,介于低端内存映射区和持久映射区之间,虚拟地址范围从VMALLOC_START至VMALLOC_END,如下图土黄色部分:   功能:调用vmalloc函数时,会从该VMALLOC区申请一部分连续的虚拟地址空间,从物理内存申请一些不连续的物理内存页,将其关联起来,并修改内核页表使内核通过该连续的虚拟地址访问到不连续的物理内存页帧。 阅读详情

相关推荐

linux内核学习笔记-struct vm_area_struct

vm_area_struct linux 内核使用 vm_area_struct 结构来表示一个独立的虚拟内存区域,由于每个不同地址的虚拟内存区域功能和内部机制都不同,因此 一个进程使用多个vm_area_struct结构来分别表示不同类型的虚拟内存区域,包括虚拟内存的起始和结束地址,以及内存的访问权限等 。各个vm_area_struct结构使用链表或者树形结构链接,方便进程快速访问,如下图所示: Linux内核中,关于虚存管理的 最基本的管理单元 应该是 struct vm_area_struct

的博客 1391

内核解读之内存管理(12)进程虚拟内存管理 vm_area_struct

在32位的系统上,线性地址空间可达到4GB,这4GB一般按照3:1的比例进行分配,也就是说用户进程享有前3GB线性地址空间,而内核独享最后1GB线性地址空间。由于虚拟内存的引入,每个进程都可拥有3GB的虚拟内存,并且用户进程之间的地址空间是互不可见、互不影响的,也就是说即使两个进程对同一个地址进行操作,也不会产生问题。

二进制君 2414

Linux内核:mm_struct简介

虚拟地址区间vm_area_struct是虚拟内存的1部份,内存描写符mm_struct指向全部虚拟空间,而vm_area_struct只是指向了虚拟空间的1段。之所以这样分隔是由于每一个虚拟区间可能来源不同,有的可能来自可履行映像,有的可能来自同享库,而有的多是动态内存分配的内存区,所以对每一个由vm_area_struct结构所描写的区间的处理操作和它前后范围的处理操作不同,因此linux把虚拟内存分割管理,并利用了虚拟内存处理例程vm_ops来抽象对不同来源虚拟内存的处理方法。

m0_74282605的博客 1580

03_008内存映射原理_虚拟内存区域vm_area_struct详解,和mmap系统钓调用及物理内存结构体完全分析

上一个记录中的 虚拟地址里的虚拟内存区域没有说的很完全这次补充一下 同时记录一些 物理地址空间 内存映射原理 最后直接通过进程使用函数完成虚拟空间到物理空间的映射1、mmap0----创建内存映射为什么要使用mmap映射呢 直接读写文件不香吗???1.系统调用mmap():进程创建匿名的内存映射,把内存的物理页映射到进程的虚拟地址空间。2.进程把文件映射到进程的虚拟地址空间,可以像访问内存一样访问文件,不需要调用系统调用read()/write()访问文件,

weixin_43898067的博客 1145

vm_area_struct

原文:http://blog.csdn.net/ywf861029/article/details/6114794 Linux内核中,关于虚存管理的最基本的管理单元应该是struct vm_area_struct了,它描述的是一段连续的、具有相同访问属性的虚存空间,

ganggexiongqi的专栏 2万+

Linux内核有什么之内存管理子系统有什么——基础篇之struct vm_area_struct(2)

Linux内核有什么之内存管理子系统有什么——基础篇之struct vm_area_struct(2)

phmatthaus的专栏 1588

Linux内存管理章节八:进程虚拟内存的蓝图:深入理解vm_area_struct与缺页异常

进程虚拟内存的蓝图:深入理解vm_area_struct与缺页异常

深耕嵌入式领用多年, 致力于分享嵌入式领域技术! 873

runtime 分类结构体_Linux 内存管理 重要结构体 (转)

linux采用了一种与具体体系结构无关代码的三层页表机制来完成内存管理,即使底层的体系结构并不支持这个概念。每一个进程都有一个指向其自己的PGD指针(mm_struct->pgd),这就是一个物理页面号,其中包含了一个pgd_t类型的数组,进程页表的载入是通过把这个结构体复制到cr3寄存器完成。PGD表中每个有效的项都指向一个页面号,此页面号包含一个pmd_t类型的PMD项数组,每一个pmd...

weixin_39675728的博客 141

Linux 内核 vm_area_structvm_struct

Linux 内核 vm_area_structvm_struct,缺页异常,Swap

tangzhangyin的专栏 1116

task_struct 结构,mm_struct 结构, vm_area_struct 结构

task_struct 结构,mm_struct 结构, vm_area_struct 结构 1、task_struct 每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,Linux内核的进程控制块是task_struct结构体。 位置:<include\linux\sched.h> - 593行 部分代码如下: struct task_struct { /*...*/ struct mm_struct *mm; struct mm_struct *activ

FF_programming的博客 4231

Linux 内核 内存管理】内存映射相关数据结构 ① ( vm_area_struct 结构体 | task_struct、mm_structvm_area_struct 3 个结构体之间的关系)

一、vm_area_struct 结构体、 二、task_struct 进程描述符、mm_struct 内存描述符、vm_area_struct 虚拟内存区间 之间的关系

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 2655

Linux】【进程】进程管理task_struct,mm_structvm_area_struct

每个 vm_area_struct 结构对应于虚拟内存空间中的唯一虚拟内存区域 VMA,vm_start 指向了这块虚拟内存区域的起始地址(最低地址),vm_start 本身包含在这块虚拟内存区域内。保存了上一次找到的vma,根据局部性原理,下一次要用到的vma正好是上次使用的vma的可能性是比较大的,因此使用find_vma()函数查找vma时,会首先从mmap_cache中找,找到了就直接返回。stack_vm是栈中所映射的内存页数目,这些变量均是表示进程虚拟内存空间中的虚拟内存使用情况。

m0_64014551的博客 1492

Linux 内核 内存管理】内存映射相关数据结构 ④ ( vm_area_struct 结构体成员分析 | vm_ops 成员 | vm_operations_struct 结构体成员分析 )

一、vm_area_struct 结构体成员分析、 1、vm_ops 成员、 二、vm_operations_struct 结构体成员分析、 1、open 函数指针、 2、close 函数指针、 3、mremap 函数指针、 4、fault 函数指针、 5、huge_fault 函数指针、 6、map_pages 函数指针、 7、page_mkwrite 函数指针、 三、vm_area_struct 结构体完整源码、 四、vm_operations_struct 结构体完整源码、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 3713

Linux内核有什么之内存管理子系统有什么——基础篇之struct vm_area_struct(1)

Linux内核有什么之内存管理子系统有什么——基础篇之struct vm_area_struct(1)

phmatthaus的专栏 1962

内核模块编程——打印一个进程的vm_area_struct

本文是一个小程序,目的是打印一个进程的vm_area_struct结构体变量,进一步加深对mm_structvm_area_struct结构体的理解。那我们首先来理解一下吧。mm_struct主要是用来描述一个进程的虚拟内存,它的结构体定义如下:struct mm_struct {    int count;    pgd_t * pgd;    unsigned long context

sunjiangangok的博客 1423

vm_area_structVMA)

Linux内核中,关于虚存管理的最基本的管理单元应该是struct vm_area_struct了,它描述的是一段连续的、具有相同访问属性的虚存空间,该虚存空间的大小为物理内存页面的整数倍。   下面是struct vm_area_struct结构体的定义: [cpp] view plaincopyprint? "font-family:Microsoft YaHei

jeffade的专栏 5918

【mm_structvm_area_struct 关系详解】

结构体角色管理范围关键信息mm_struct总经理整个进程的虚拟地址空间页表根 (pgd)、VMA链表/红黑树头、整体布局部门经理一段连续的虚拟内存区域区域起止地址、访问权限、映射的文件简单来说,mm_struct是总纲,而是细则。内核通过这种两级管理机制,既能够宏观掌控整个地址空间,又能够高效、精细地管理每一片具有不同属性的内存区域。

Beaman的博客 1039

源码之linux进程:vm_area_struct与虚拟内存的关系

前言 在虚拟内存中,我提到了linux虚拟内存区域的结构,但具体其是如何在linux中表示与实现的呢? 我利用了linux2.6的源码进行了浅显的分析。 正文 task_structlinux中,进程控制块即PCB的结构为task_struct,我们以linux2.6为例,其源码如下: struct task_struct { //表示进程当前运行状态 //volatile避免...

Hpsyche的博客 2345
上一篇: 【Android camera】开发之三:深入理解相机ISP(图像信号处理)必看文章
下一篇: 【genius_platform软件平台开发】第四点:size_t在不同的win32位和win64宏定义的区别
隨意的風
隨意的風 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄18年 1万+粉丝 551原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

隨意的風

如果你觉得有帮助,期待你的打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值