Linux内存管理之高端内存

Linux内核高端内存(High Memory)简介 由于 32 位系统的虚拟地址空间最大为 4GB(默认内核空间占用 1GB,用户空间 3GB),当物理内存超过内核可直接映射的范围(通常是 896MB)时,剩余的内存需要通过特殊机制进行管理,这就是高端内存的由来。在 64 位架构(如 x86_64)中,内核虚拟地址空间极大(如 128TB),可直接线性映射所有物理内存(`phys_base` 偏移),因此不再需要高端内存机制。- 内核默认将虚拟地址空间的 `0xC0000000`(3GB)到 `0xFFFFFFFF`(4GB)划分为内核空间(共 1GB)。 阅读详情

Linux对内存的管理划分成三个层次,分别是Node、Zone、Page。对这三个层次简介如下:

层次说明
Node(存储节点)CPU被划分成多个节点,每个节点都有自己的一块内存,可以参考NUMA架构有关节点的介绍
Zone(管理区)每一个Node(节点)中的内存被划分成多个管理区域(Zone),用于表示不同范围的内存
Page(页面)每一个管理区又进一步被划分为多个页面,页面是内存管理中最基础的分配单位

它们之间的关系,用一张经典的图表示如下:图片来源

接下来我们重点讲述的是ZONE_HIGNMEM,也就是高端内存。

1 高端内存的由来

在32bit的x86机器中,4G的虚拟地址空间被划分成3G的用户空间(0—3G),1G的内核空间(3-4G)。在64bit的机器中于此不同。也就是说虚拟地址空间从0x0000 0000~0xBFFF FFFF为用户空间,0xC000 0000~0xFFFF FFFF为内核空间。Linux把每个内存节点的物理内存划分成3个管理区,也就是划分成ZONE_DMA、ZONE_NORMAL、ZONE_HIGHMEM。它们的介绍如下:

内存区域说明
ZONE_DMA范围是0~16M,该区域的物理页面专门供I/O设备的DMA使用
ZONE_NORMAL范围是16~896M,该区域的物理页面是内核能够直接使用的
ZONE_HIGHMEM范围是896~结束,高端内存,内核不能直接使用

上面说到虚拟地址空间中的3~4G为Linux内核虚拟地址空间,其中内核空间3G~3G+896M对应物理内存空间的0~896M,并且在内核初始化时就已经将3G~3G+896M(0xC0000 0000~0xF7FF FFFF)虚拟地址空间与物理内存空间的0~896M进行了对应,内核在访问0~896M的内存的时候,只需要将其对应的虚拟地址空间增加一个偏移量就可以了。对于超过896M的物理地址空间,它们属于高端内存,高端内存区包含的内存页不能由内核直接访问,尽管它们也线性地映射到了线性地址空间的第4个G。也就是说对于高端内存区,只有128M的线性地址(0xF800 0000~0xFFFF FFFF)留给它进行映射。

有这样一个问题:内核虚拟地址空间只有1G,也就是说内核只能访问1G物理内存空间,但是如果物理内存是2G,那内核如何访问剩余的1G物理内存空间呢?按照我们刚才说的,这2G的物理内存地址被划分成了3个Zone,物理内存0~896M是内核直接可以访问的,896M~2G这一部分内核要如何访问呢?实际上,当内核想要访问高于896M的物理内存空间时,会从0xF800 0000~0xFFFF FFFF这一块线性地址空间中找一段,然后映射到想要访问的那一块超过896M部分的物理内存,用完之后就归还。由于0xF800 0000~0xFFFF FFFF这一块没有和固定的物理内存空间进行映射,也就是说,这128M的线性地址空间可以和高于896M的物理内存空间短暂的、任意的建立映射,循环使用者128M线性地址空间,这样内核就可以访问剩下的高于896M的物理内存空间了。

2 高端内存简介

刚才说虚拟地址空间的3G~4G部分属于Linux内核空间,其中1G的虚拟内核空间如下图:

上图中PAGE_OFFSET通常为0xC000 0000,而high_memory指的是0xF7FF FFFF,在物理内存映射区和和第一个vmalloc区之间插入的8MB的内存区是一个安全区,其目的是为了“捕获”对内存的越界访问。处于同样的理由,插入其他4KB大小的安全区来隔离非连续的内存区。Linux内核可以采用三种不同的机制将页框映射到高端内存区,分别叫做永久内核映射、临时内核映射以及非连续内存分配。相关区域介绍如下:

虚拟内存区域说明
物理内存映射映射了物理内存空间0~896M部分,这一部分是内核可以直接访问的
永久内核映射允许内核建立高端页框到内核虚拟地址空间的长期映射。永久内核映射不能用于中断处理程序和可延迟函数,因为建立永久内核映射可能阻塞当前进程
固定映射的线性地址空间其中的一部分用于建立临时内核映射
vmalloc区该区用于建立非连续内存分配,本文重点讨论的内容

实际上,把内存区映射到一组连续的页框是最好的选择,这样可以充分利用高速缓存就并获得较低的平均访问时间。不过,如果对内存区的请求不是很频繁,那通过连续的线性地址来访问非连续的页框这样一种分配方式将会很有意义,因为这样可以避免外部碎片,而缺点是必须打乱内核页表。在内核虚拟地址空间中,为非连续内存区保留的线性地址空间的起始地址由VMALLOC_START宏定义,而末尾地址有VMALLOC_END宏定义。下面重点讲述非连续内存区,也就是vmalloc区。

3 vmalloc区相关数据结构

在Linux的实现中,每一个非连续内存区都对应着一个类型为struct vm_struct的描述符,源代码如下:源代码网址

struct vm_struct {
	struct vm_struct	*next;/*指向下一个vm_struct结构体的指针*/
	void			*addr;/*内存区内第一个内存单元的线性地址*/
	unsigned long		size;/*内存区的大小(以字节为单位)加4096字节(4096为内存区之间的安全区间的大小)*/
	unsigned long		flags;/*非连续内存区映射的内存类型*/
	struct page		**pages;/*指向nr_pages数组的指针,该数组有指向页描述符的指针组成*/
	unsigned int		nr_pages;/*内存区填充的页的个数*/
	phys_addr_t		phys_addr;
	const void		*caller;
};

下面我们重点分析vmalloc()和vfree()函数的实现。下面是vmalloc()函数的源代码:源代码网址

static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
				 pgprot_t prot, int node)
{
	const int order = 0;
	struct page **pages;
	unsigned int nr_pages, array_size, i;
	gfp_t nested_gfp = ((GFP_KERNEL | __GFP_HIGHMEM) & GFP_RECLAIM_MASK) | __GFP_ZERO;
	/*
	计算连续的线性地址空间对应多少个页框
	*/
	nr_pages = get_vm_area_size(area) >> PAGE_SHIFT;
	/*
	接下来需要创建一个数组,数组元素为指向page的指针,数组元素个数nr_pages
	这一步是用来计算创建数组需要多大的内存空间
	*/
	array_size = (nr_pages * sizeof(struct page *));
	/*设置area结构体中nr_pages域的值*/
	area->nr_pages = nr_pages;
	/* Please note that the recursion is strictly bounded. */
	/*下面的if...else...就是创建一个数组,返回的是一个二级指针*/
	if (array_size > PAGE_SIZE) {
		pages = __vmalloc_node(array_size, 1, nested_gfp|__GFP_HIGHMEM,
				PAGE_KERNEL, NUMA_NO_NODE, area->caller);
		area->flags |= VM_VPAGES;
	} else {
		pages = kmalloc_node(array_size, nested_gfp, NUMA_NO_NODE);
	}
	/*设置设置area结构体中pages域*/
	area->pages = pages;
	if (!area->pages) {//错误处理
		remove_vm_area(area->addr);
		kfree(area);
		return NULL;
	}

	/*
	接下来就是重头戏,要分配页框了...
	需要说明的是,这里是一个一个页框的分配,这些页框在物理内存上不一定连续
	刚才创建的数组,在下面也用到了...
	如果页面分配正常,没有出错就继续下面的处理,分配失败则需要进行出错处理
	*/
	for (i = 0; i < area->nr_pages; i++) {
		struct page *page;
		gfp_t tmp_mask = (GFP_KERNEL | __GFP_HIGHMEM) | __GFP_NOWARN;

		if (NUMA_NO_NODE == NUMA_NO_NODE)
			page = alloc_page(tmp_mask);
		else
			page = alloc_pages_node(NUMA_NO_NODE, tmp_mask, order);

		if (unlikely(!page)) {
			/* Successfully allocated i pages, free them in __vunmap() */
			area->nr_pages = i;
			goto fail;
		}
		area->pages[i] = page;
	}
	/*
	执行到这里,说明前面的线性地址空间获取、页面分配都没有错误
	连续线性地址空间有了,物理页面也获取到了,接下来需要做的就是将线性地址空间与这些
	页框建立联系,而map_vm_area函数所做的就是修改内核使用的页表项,以此表明分配给
	非连续内存区的每个页框现在对应着一个线性地址
	看一下map_vm_area函数的调用链,其中缩进表示函数调用,处于同一缩进的表示函数的调用先后
	--map_vm_area
		--vmap_page_range
			-- vmap_page_range_noflush
				--pgd_offset_k
				--pud_alloc
				--vmap_pud_range
					--pud_alloc
					--vmap_pmd_range
						--pmd_alloc
						--vmap_pte_range
							--pte_alloc_kernel
							--set_pte_at
	*/
	if (map_vm_area(area, PAGE_KERNEL, &pages))
		goto fail;
	return area->addr;

fail:
	warn_alloc_failed(GFP_KERNEL | __GFP_HIGHMEM, order,
			  "vmalloc: allocation failure, allocated %ld of %ld bytes\n",
			  (area->nr_pages*PAGE_SIZE), area->size);
	vfree(area->addr);
	return NULL;
}

/**
 *	vmalloc  -  allocate virtually contiguous memory
 *	@size:		allocation size
 *	Allocate enough pages to cover @size from the page level
 *	allocator and map them into contiguous kernel virtual space.
 *
 *	For tight control over page level allocator and protection flags
 *	use __vmalloc() instead.
 */
void *vmalloc(unsigned long size)
{
	struct vm_struct *area;
	void *addr;
	unsigned long real_size = size;

	size = PAGE_ALIGN(size);
	/*
	如果申请的字节数为0或者申请的页面数(size >> PAGE_SHIFT就是申请的页面数)大于系统总页面数时,申请失败
	*/
	if (!size || (size >> PAGE_SHIFT) > totalram_pages)
		goto fail;

	/*
	从__get_vm_area_node()函数调用的参数中我们看到了之前提到的VMALLOC_START和VMALLOC_END,这其实就是
	vmalloc区的开始和结束,在这里,__get_vm_area_node这个函数简单来说就是在VMALLOC_START与VMALLOC_END之间
	找个空闲的线性地址空间,然后返回内存区结构体vm_struct,而vm_struct中的addr代表了返回的内存区的线性地址的其实
	
	*/
	area = __get_vm_area_node(size, 1, VM_ALLOC | VM_UNINITIALIZED,
				  VMALLOC_START, VMALLOC_END, NUMA_NO_NODE, GFP_KERNEL | __GFP_HIGHMEM, __builtin_return_address(0));
	if (!area)
		goto fail;
	/*
	连续的线性地址空间得到了,接下来就需要得到这些线性地址对应的页框了,这将由__vmalloc_area_node函数来实现,关于本函数的分析,请看上面
	*/
	addr = __vmalloc_area_node(area, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, NUMA_NO_NODE);
	if (!addr)
		return NULL;

	/*
	 * In this function, newly allocated vm_struct has VM_UNINITIALIZED
	 * flag. It means that vm_struct is not fully initialized.
	 * Now, it is fully initialized, so remove this flag here.
	 */
	clear_vm_uninitialized_flag(area);

	/*
	 * A ref_count = 2 is needed because vm_struct allocated in
	 * __get_vm_area_node() contains a reference to the virtual address of
	 * the vmalloc'ed block.
	 */
	kmemleak_alloc(addr, real_size, 2, GFP_KERNEL | __GFP_HIGHMEM);

	return addr;

fail:
	warn_alloc_failed(GFP_KERNEL | __GFP_HIGHMEM, 0,
			  "vmalloc: allocation failure: %lu bytes\n",
			  real_size);
	return NULL;
}

上面的代码其实并不是真正的vmalloc函数的实现,真正的实现是函数嵌套函数的,我把这些函数调用进行展开得到的就是上面的代码。有关vmalloc函数实现的具体分析,请看上面的代码以及其中的中文注释。

这里说一个宏:PAGE_ALIGN,这是一个嵌套的宏,最后翻译过来就是:#define PAGE_ALIGN(addr)    (addr + PAGE_SIZE-1)&PAGE_MASK,其中,PAGE_SIZE=1<<12,PAGE_MASK= ~(PAGE_SIZE-1),说人话,这个宏定义到底是做什么的呢?其实就是将size的值设置为4096的整数倍,举个例子,我们要申请1byte,也就是原来的size=1,执行size=PAGE_ALIGN(size)后,相当于size=(1+4096-1)&PAGE_MASK=4096&PAGE_MASK=4096,正好是4096的一倍,再举个例子,要申请4097字节,即size=4098,执行size=PAGE_ALIGN(size)后,size=(4098+4096-1)&PAGE_MASK=(8192+1)&PAGE_MASK=8192,也就是说,当我们申请的字节数不足4096字节(一个普通页面大小为4K,也就是4096字节)时,按照一个页面进行申请,超过一个页面但不足两个页面时按照两个页面进行申请。

与vmalloc函数相对的是vfree,其过程类似,这里不再展开。

常见问题:问题来自参考博客

1、用户空间(进程)是否有高端内存概念?

用户进程没有高端内存概念。只有在内核空间才存在高端内存。用户进程最多只可以访问3G物理内存,而内核进程可以访问所有物理内存。

2、64位内核中有高端内存吗?

目前现实中,64位Linux内核不存在高端内存,因为64位内核可以支持超过512GB内存。若机器安装的物理内存超过内核地址空间范围,就会存在高端内存。

3、用户进程能访问多少物理内存?内核代码能访问多少物理内存?

32位系统用户进程最大可以访问3GB,内核代码可以访问所有物理内存。

64位系统用户进程最大可以访问超过512GB,内核代码可以访问所有物理内存。

4、为什么不把所有的地址空间都分配给内核?

若把所有地址空间都给内存,那么用户进程怎么使用内存?怎么保证内核使用内存和用户进程不起冲突?

本人水平有限,如您发现文中有错误,请评论或者发邮箱:ieyaolulu@163.com,谢谢!

linux内核高端内存管理之固定内存区与映射 前面总结了高端内存中永久内核映射和临时内核映射。linux高端内存中的临时内存区为固定内存区的一部分,下面是Linux内存布局图 对于固定内存在linux内核中有下面描述 enum fixed_addresses { #ifdef CONFIG_X86_32 FIX_HOLE, FIX_VDSO, #else VSYSCALL_LAST_PAGE, VSYSCALL_FIR 阅读详情

相关推荐

光耦继电器电路分析

光耦电路的分析笔记

MingYue_SSS的博客 6873

Linux内核高端内存

Linux将内核地址空间划分为三部分ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,高端内存HIGH_MEM地址空间范围为 0xF8000000 ~ 0xFFFFFFFF(896MB~1024MB)。这种方式很简单,因为通过 vmalloc() ,在”内核动态映射空间”申请内存的时候,就可能从高端内存获得页面(参看 vmalloc 的实现),因此说高端内存有可能映射到”内核动态映射空间”中。:借一段地址空间,建立临时地址映射,用完后释放,达到这段地址空间可以循环使用,访问所有物理内存。

谢谢大家的关注 1265

告别OpenAI API调用:手把手在本地CPU/GPU上部署fast-whisper中文语音识别模型

本文详细指导如何在本地CPU/GPU上部署fast-whisper中文语音识别模型,摆脱对OpenAI API的依赖。从环境准备、模型获取与优化,到CPU/GPU环境的具体部署步骤和性能优化技巧,全面覆盖本地化语音识别的实现方案,帮助开发者提升效率并保障数据隐私。

weixin_29988907的博客 305

linux高端内存

高端内存是指物理地址大于 896M 的内存。对于这样的内存,无法在“内核直接映射空间”进行映射。 为什么?   因为“内核直接映射空间”最多只能从 3G 到 4G,只能直接映射 1G 物理内存,对于大于 1G 的物理内存,无能为力。   实际上,“内核直接映射空间”也达不到 1G, 还得留点线性空间给“内核动态映射空间” 呢。   因此,Linux 规定“内核直接映射空

xqzhan的专栏 586

【软考高项】五十一、常见必会的几种进度网络图(单代号、双代号、七格图、横道图)

软考高项计算题进度网络图画图介绍

有莘不破的博客 3万+

从Mate到Mate40 Pro+:华为旗舰核心配置演进与选购避坑指南

本文回顾了华为Mate系列从初代到Mate40 Pro+的核心配置演进历程,重点分析了处理器性能、影像系统、屏幕设计及续航快充的技术突破。针对选购需求,提供了区分版本、5G选择及存储配置的实用避坑建议,帮助消费者明智选择华为旗舰机型。

weixin_30015371的博客 492

32位Linux内核空间地址映射--------总结

对于32位机,总的来说物理内存被分为高端和地段内存两部分。我们可以使用virt_to_phys() 和 phys_to_virt() 方法用于896MB以下低端内存的虚拟地址和物理内存地址之间换算关系,高端内存的虚拟地址和物理内存地址之间不存在如此简单的换算关系。内核将高端内存划分为3部分:VMALLOC_START ~ VMALLOC_END、KMAP_BASE ~ FIXADDR_START和FIXADDR_START ~ 4G。对于高端内存的3部分,内存映射有三种方式:

katerdaisy的博客 1919

使用STM32F103C8T6控制舵机丝滑运转附代码

使用STM32F103C8T6控制舵机丝滑运转原理和案例,附代码。

m0_63566592的博客 4237

Linux内存描述之高端内存

内核将其中的前896MB与物理内存的0~896MB进行直接映射, 即线性映射, 将剩余的128M线性地址空间作为访问高于896M的内存的一个窗口. 引入高端内存映射这样一个概念的主要原因就是我们所安装的内存大于1G时,内核的1G线性地址空间无法建立一个完全的直接映射来触及整个物理内存空间,而对于80x86开启PAE的情况下,允许的最大物理内存可达到64G,因此内核将自己的最后128M的线性地址空间腾出来,用以完成对高端内存的暂时性映射。从而,线性区映射的物理内存成为低端内存,剩下的物理内存被成为高端内存。

m0_74282605的博客 499

从材料到磁场:ANSYS Workbench永磁体仿真全流程解析

本文详细解析了在ANSYS Workbench中进行永磁体仿真的完整流程。从钕铁硼等永磁材料的特性讲起,逐步指导如何在软件中搭建模型、定义关键磁化方向、设置边界条件与网格划分,并解读磁场分布结果。文章旨在帮助工程师掌握静磁场仿真核心技术,为电机、传感器等设备的设计与优化提供精准指导。

weixin_29229989的博客 272

鼎捷T100—二次开发:客制化联络对象维护作业 aooi350

鼎捷T100二次开发,客制化

weixin_52342654的博客 1132

Linux 内存管理 —— 高端内存

高端内存

Jia ming 的日常学习笔记 1027

【软件系统架构】系列六:MBSE(基于模型的系统工程)

基于模型的系统工程(MBSE)是一种以模型为核心的系统工程方法论,通过结构化、可视化的模型取代传统文档,实现从需求到验证的全生命周期管理。MBSE采用SysML建模语言,包含需求、功能、架构和验证四大要素,支持自动追踪、仿真分析和代码生成。相比文档式工程,MBSE具有变更影响自动分析、跨团队协作和高可视化等优势,广泛应用于航空航天、汽车电子等领域。典型开发流程包括需求建模、行为建模、架构建模等阶段,配合MagicDraw、Cameo等工具链实现。MBSE正与数字孪生、AI技术融合,推动自动化建模和智能验证的

moton2017的博客 2782

Linux内核-内存管理之高端内存

看了linux内核内存管理,参考网上的意见整理了一下,认为两个比较好的博文: http://blog.youkuaiyun.com/chobit_s/article/details/6029527 http://blog.youkuaiyun.com/do2jiang/article/details/5495675 1.页框管理        Linux采用4KB页框大小作为标准的内存分配单元。内

继续微笑lsj 2166

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

linux 内核高端内存意义,Linux内核高端内存管理

原先一直都对Linux高端内存的管理认识模模糊糊的,可能主要是初次接触Linux kernel 是0.11版吧,当初的内存设计是16M,Linus对拥有32M的内存都是觊觎万分,1G内存恐怕是天方夜谭了。16M内存哪里还顾得上高端内存,脑子就一直没有这种概念。先我们还是来看看为什么要有高端内存?80386的线性寻址空间是4G,内核空间从3G开始,如果全部采用"线性映射"(物理地址和逻辑地址只差一个...

weixin_26786277的博客 265

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

linux内存管理之高端内存

linux内核只能访问1G的内存空间,对于超出1G的内存,需要借助于page管理 linux 用户空间与内核空间——高端内存详解 https://blog.youkuaiyun.com/Tommy_wxie/article/details/17122923...

shipinsky的博客 202

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Linux内存描述之高端内存--Linux内存管理(五)

日期 内核版本 架构 作者 GitHub 优快云 2016-08-31 Linux-4.7 X86 & arm gatieme LinuxDeviceDrivers Linux内存管理 http://blog.youkuaiyun.com/vanbreaker/article/details/75799411 前景回顾前面我们讲到服务器体系(SMP, NUMA, M

OSKernelLAB(gatieme) 1万+

Linux内核高端内存管理

Linux内核高端内存管理

qq_43678612的博客 129

linux高端内存管理之非连续内存区(描述)

总结了高端内存区的固定内核映射区、临时内核映射与永久内核映射。但是对于高端内存中各个区间的布置我们任然不是很清楚,首先我们从整体上看看内核对高端内存的划分情况。 如果内存足够大(比如用户:内核线性空间=3:1,内核就只能访问线性空间的第4GB内容,如果物理内存超过1GB则视为足够大),内核线性空间无法同时映射所有内存。这就需要将内核线性空间分出一段不直接映射物理内存,而是作为窗口分时映射使用

bullbat的专栏 4474

linux高端物理内存,Linux内存管理之高端内存

看了Linux内核内存管理,参考网上的意见整理了一下。1.页框管理Linux采用4KB页框大小作为标准的内存分配单元。内核必须记录每个页框的状态,这种状态信息保存在一个类型为page的页描述符中,所有的页描述存放在mem_map中。virt_to_page(addr)产生线性地址对应的页描述符地址。pfn_to_page(pfn)产生对应页框号的页描述符地址。在页框描述符中,几个关键的字段我认为:...

weixin_32447969的博客 362

Linux内存管理:内存描述之高端内存

《Linux内存管理:内存描述之内存节点node》 《Linux内存管理:内存描述之内存区域zone》 《Linux内存管理:内存描述之内存页面page》 《Linux内存管理:内存描述之高端内存》 《Linux用户空间与内核空间(理解高端内存)》 目录 1 前景回顾 1.1 UMA和NUMA两种模型 1.2 Linux如何描述物理内存 1.3 典型架构(x86)上内存区域划分 2 内核空间和用户空间 2.1 把内核空间和用户空间分开 2.2 linux为什么把内核映射到3G-4G这

RToax 1136

Linux 内存管理 -- 高端内存的映射方式

http://blog.youkuaiyun.com/chenziwen/article/details/5932396   Linux 内存管理 -- 高端内存的映射方式 分类: server开发2010-10-11 00:27 1146人阅读 评论(1) 收藏 举报 linuxstructlinux内核数据结构table算法   高端内存是指物理地址大于 896M 的内存。

zdy0_2004的专栏 1308

linux非连续内存,(转)linux高端内存管理之非连续内存区(描述)

总结了高端内存区的固定内核映射区、临时内核映射与永久内核映射。但是对于高端内存中各个区间的布置我们任然不是很清楚,首先我们从整体上看看内核对高端内存的划分情况。如果内存足够大(比如用户:内核线性空间=3:1,内核就只能访问线性空间的第4GB内容,如果物理内存超过1GB则视为足够大),内核线性空间无法同时映射所有内存。这就需要将内核线性空间分出一段不直接映射物理内存,而是作为窗口分时映射使用到的未映...

weixin_28976057的博客 226
上一篇: Linux内存管理之SLAB分配器
下一篇: Linux内核中的链表
ibless
博客等级 码龄9年 66粉丝 56原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值