Linux0.12内核之内存管理(3)

《Linux内核完全注释》pdf v3.0 阅读详情

本系列的第三篇文章主要来介绍与共享物理页面相关的两个函数。

//在发生缺页异常的时,首先看看能否与运行同一个文件的其他进程进行页面共享处理。该函数首先判断系统中是否有另外进程也在运行与当前进程一样的执行文件。若有,则在系统当前任务中找寻这样的任务。若找到了这样的任务就尝试与其共享指定地址处的页面。判断系统中是否有另一个进程也在执行同一个可执行文件的方法是利用进程任务数据结构中的executable字段。该字段执行进程正在执行程序的内存中的i节点,根据该i节点的引用次数i_count我们就可以判断。
static int share_page(struct m_inode *inode,unsigned long address)
{
	struct task_struct **p;
	if(inode->i_count<2 || !inode)
		return 0;
	
	for(p=&LAST_TASK;p>&FIRST_TASK;--p)
	{
		if(!*p)
			continue;
		if(current==*p)
			continue;
		if(address<LIBRARY_OFFSET)
			if(inode!=(*p)->executable)
				continue;
		else{
			if(inode!=(*p)->library)
				continue;
			}
		if(try_to_share(address,*p))
			return 1;
	}
	return 0;
}

//在任务p中检查位于线性地址"address"处的页面,看页面是否存在,是否干净。如果p进程address处的页面存在并且没有被修改过的话,就让当前进程与p进程共享之。同时还需要验证置顶的地址处是否已经申请了页面,若是则出错。
static int try_to_share(unsigned long address,struct task_struct *p)
{
	unsigned long from;
	unsigned long to;
	unsigned long from_page;
	unsigned long to_page;
	unsigned long phys_addr;
	
	//首先分别求指定进程p中和当前进程中逻辑地址address对应的页目录项。为了计算方便,先计算出address处“逻辑"页目录项号,即以进程空间0-64MB算出的页目录项号。该"逻辑"页目录项号加上进程p在cpu 4G线性空间中起始地址对应的页目录项即得p中的地址address处页面所对应的4G线性空间中的实际页目录项from_page
	
	from_page=to_page=((address>>20) & 0xffc);
	from_page+=((p->start_code) & 0xffc);
	to_page+=((current->start_code) & 0xffc);
	
	//在得到p和当前进程address对应的页目录项后,下面分别对进程p和当前进程进行处理。首先对p进程的表项进程操作。目标是取得p进程中address对应的物理内存页面地址,并且该物理页面存在并且干净(没被修改)。方法是首先取目录项内容,如果该目录项无效(P=0),表示目录项对应的二级页表不存在,于是返回。否则取该目录项对应的页表地址from,从而计算出逻辑地址address对应的页表项指针,并取出该页表项内容临时保存在phys_addr中。
	from=*(unsigned long*)from_page;
	if(!(from & 1))
		return 0;
	from &=0xfffff000;
	from_page=from+((address+10) &0xffc;
	phys_addr=*(unsigned long*)from_page;
	
	//接着看看页表映射的物理页面是否存在并干净。0x41对应页面中的D和P标志。如果页面不干净或者无效则返回。然后我们从该表象中取出物理地址保存在phys_addr中,最后我们检查这个物理页面地址的有效性。
	if(phys_addr & 0x41)!=0x01)
		return 0;
	phys_addr &=0xfffff000;
	if(phys_addr>=HIGH_MEMORY || phys_addr<LOW_MEM)
		return 0;
	
	//下面对当前进程的表项进程操作。目标是取得当前进程中address对应的页表项地址,并且该页表项还没有映射物理页面,即其P=0.首先取得当前进程页目录项内容->to。如果该目录项无效P=0,即目录项对应的二级页表不存在,则首先申请空闲物理页来存放页表,并更新目录象to_page内容,让其指向该内容页面。
	to=*(unsigned long*)to_page;
	if(!(to & 1))
	{
		if(to=get_free_page())
			*(unsigned long*)to_page=to|7;
		else
			com();
	}
	to&=0xfffff000;
	to_page=to+((address>>10) &0xffc);
	if(1 & *(unsigned long*)to_page)
		panic("try_to_share:to_page already exists");
	
	//共享处理:首先对p进程的页表项进行修改,设置其写保护标志,然后让当前进程复制p进程这个页表项。此时当前进程逻辑地址address处页面就被映射到p进程逻辑地址address处映射的物理页面上。
	*(unsigned long*)from_page&=~2;
	*(unsigned long*)to_page=*(unsigned long*)from_page;
	
	invalidate();
	phys_addr-=LOW_MEM;
	phys_addr>>12;
	mem_map[phys_addr]++;
	return 1;
}

使用一个图来总结share_page的工作:


用Linux5.0的视角看《Linux内核设计与实现》——(四)内存管理 在看完了内核中的进程管理,接下来我们看看内存管理——操作系统的另一大块,个人觉得当你对进程管理和内存管理都有一定的了解后,对“内核”这一词就会有一个比较清晰的概念。 12.1 页(page) 页,是内核管理物理内存的基本单位。虽然处理器处理内存可以以字节为单位,但是一般来讲在处理器和物理内存之间,还存在着一个处理单元,我们称之为内存管理单元(MMU),主要负责虚拟地址到物理地址的转换。(关于为什么我们总是需要一个MMU在CPU和物理内存之间,这是计算机系统设计的一个总要知识,挖坑中……) 在内核中,用str 阅读详情

相关推荐

Linux 0.12源码深入解析与学习指南

本文还有配套的精品资源,点击获取 简介:Linux 0.12作为Linux操作系统的一个早期版本,提供了对于操作系统工作原理及Linux内核发展历史的宝贵洞见。通过赵炯的《深入理解Linux内核》或类似书籍,结合Linux 0.12的源代码,可以深入学习内核架构、进程管理、内存管理、文件系统、设备驱动、网络支持、系统调用、编译构建、调试工具等关键知识点。本资料旨在帮助开发者...

weixin_42298778的博客 1029

Linux 0.12 内核对内存的管理

Linux 0.12 内核对内存的管理 其着重点在于分段,用分段的机制把进程间的虚拟地址分隔开。 每个进程都有一张段表LDT,整个系统有一张GDT表,且整个系统只有一个总页表。   其地址翻译过程为: 程序中给出的32位地址(实际上被看做段内偏移地址),再根据代码段寄存器CS中的16位段选择子,可在GDT或LDT中查找相应的段描述符。从段描述符中提取段的基地址,与程序

菜鸟的自留地-mooyang 3626

电力电子技术复习笔记

通常在开关过程前后加入谐振,使开关开通前电压先降到0,关断前电流先降到0,消除开关过程电压、电流的重叠,降低它们的变化率,从而大大减小甚至消除开关损耗。小信号线性化模型的原理:忽略开关频率分量和开关频率谐波分量及其边频分量,建立占空比、输入电压等的低频扰动对变换器中的电压、电流影响的模型。解:可以利用变压器的变比改变输出电压大小,避免控制过程的占空比过小或过大,提高控制精度,同时有利于减轻输出电路中电力电子器件的耐压要求。驱动电路:用于控制功率半导体器件的开关,从而控制电路的电流和电压。

Miracle Fan的博客 1万+

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

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

OSKernelLAB(gatieme) 1万+

HAL库:中断处理函数 及 weak弱声明中断回调函数 详解

HAL库中断处理函数 及 weak弱声明中断回调函数

L_Z_J_I的博客 5169

openMVS ---dense point cloud(代码理解)

openMVS ---dense point cloud(代码理解)0 代码实现原理1 代码实现步骤1.1 参数传递1.2 loading .mvs数据1.3 稠密重建1.3.0 相关变量及概念1.3.1 ComputeDepthMaps(data) --计算多张深度图1.3.1.1. pre1.3.1.2 为每一张depth map Select view(s) !!!1.3.1.2.1 N neighbors --- global score + filter1.3.1.2.2 MRF ---- t

小rivaaaa的博客 5328

Linux0.12内核之内存管理(2)

本文主要介绍Linux0.12内核memory.c中的函数 1.void free_page(unsigned long addr) //释放物理地址addr处的一页内存。用于free_page_tables()函数 void free_page(unsigned long addr) { //首先判定给定物理地址的合理性。如果物理地址addr小于内存低端1M,对此不///予处理。如果a

GetnextWindow的专栏 1525

ControlCAN.dll开发适配USBCAN_E/2E_U设备

摘要:本文提供了USBCAN_E/2E_U设备的配置指南:1)安装专用驱动;2)获取最新的ControlCAN.dll文件;3)修改VCI调用顺序,新增VCI_SetReference函数设置波特率;4)使用工具计算波特率配置值,并给出了常见波特率对应的代码参考值(如500K对应0x060007)。配置过程强调使用特定工具计算精确的波特率参数,并提供了相关软件下载链接。

weixin_43969033的博客 387

关于Linux kernel里的high memory

From:http://blog.sina.com.cn/s/blog_6488248f0100wu6v.html再参考《Linux kernel development》中memory management一章的内容就更容易理解。high memory只存在于32位kernel下,以下文字都针对32位kernel。1)什么是high memory,为什么要有high memoryLinux人...

weixin_30446197的博客 305

PCL RANSAC拟合直线并插值

空间直线线性插值的原理与实现方法。

点云侠的博客 136

Linux 0.12内核与现代内核在内存管理上的区别

0.12内核的内存管理比较简单粗暴,内核只用了一个页目录,只能映射4G的线性空间,所以每个进程的虚拟空间(逻辑空间)只能给到64M,最多64个进程;每个进程都有对应的任务号nr,当一个进程需要分配进程空间时,只需要nr乘以64M就可以得出该进程空间的线性起始地址。然后该进程的代码段、数据段描述符里面的基址字段会被设定为(nr x 64M),同时可以为进程分配页目录项和页目录表用以承载映射关系。

Linux Kernel Developer 924

C++实现设计ATM机系统

这个示例实现了一个基本的ATM机系统,支持注册、登录、存款、取款、查询余额和保存数据等功能。当然,这只是一个简单的ATM机模拟,实际的ATM机系统需要更复杂的逻辑和更严格的安全措施。C++编写一个简单的ATM机系统,我将提供一个基本的实现示例,但由于ATM机系统的复杂性和安全性要求,这只是一个简单的模拟,不适合在实际环境中使用。试设计一简单模拟ATM机系统,系统以菜单方式工作,采用自定义函数设计各功能模块被主菜单调用,使之能提供以下基本选项。=========欢迎使用ATM=========

走向CTO的路上... 1241

linux-0.12内核之内存管理(1)

1.内存分页管理机制 内存分页管理是通过页目录表和内存页表所组成的二级表组成的,其中页目录表和页表的结构是一样的,表项结构也相同。页目录表中的每个表项(4B)来寻址一个页表,而每个页表项(4B)来指定一页物理内存页。因此,当指定了一个页目录项和一个页表项,我们就可以唯一地确定所对应的物理内存页。在Linux 0.12内核中,所有进程都是用一个页目录表,而每个进程都有自己的页表。内核代码和数据段长

GetnextWindow的专栏 1596

ABAP Module Pool 编程入门:把 Table Control 用透,在 Dynpro 里做出可编辑的列表界面

摘要:Table Control是SAP GUI中用于对话式事务的多行数据交互控件,具备滚动、选择、修改等功能。它通过CXTAB_CONTROL/CXTAB_COLUMN结构实现动态控制,需在PBO/PAI中配合LOOP循环处理数据流。开发时需注意LINES、TOP_LINE等关键字段设置,并采用并行循环简化编码。典型应用包括订单行维护、主数据管理等场景,支持多选删除、列排序等业务需求。(150字)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 340

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Linux内核之内存管理

NUMA(Non-Uniform Memory Access,非统一内存访问)是一种多处理器系统的内存架构。内存被划分为多个节点(node),每个节点与一个或多个处理器核心相关联。处理器访问本地节点内存的延迟较低,访问远程节点内存的延迟较高。以上是我自己学习内存管理时所做的笔记,很多抽象的东西用了通俗的语言来解释清楚,方便在学习的过程中理解,如果你正好是在学习内存管理的相关内容,可以以我的笔记作为参考,如果你是需要突击内存管理相关的知识,也可以结合着大语言模型来进行学习。

qq_56187001的博客 1128

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Linux内核源代码分析一(Linux0.12)

Linux 内核主要由 5 个模块构成,它们分别是:进程调度模块、内存管理模块、文件系统模块、进程间通信模块和网络接口模块。首先说一下pc机的启动流程,在加电后,80X86会先进入实模式并进入地址0XFFFF0开始自动执行代码,这个地址一般带表了BIOS的代码地址,PC的BIOS将会执行硬件检测和诊断功能,并在0地址进行中断向量的初始化,最后BIOS会将启动设备的第一个扇区读入地址0X7C00位置,并从这个位置开始执行代码。boot目录下包含三个汇编代码文件bootsect文件是在记录在磁盘的第一个扇区中,

qq_43147121的博客 3023

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Linux0.12内核源码解读(6)-main.c

大家好,我是呼噜噜,好久没有更新old linux了,上次我们讲到了Linux0.12内核的,内核正式完成从汇编到c程序的切换,本文我们一起来看看main.s究竟发生了什么?系列文章目录main.c在内核源代码的init/目录下,我们知到main函数通常是C语言的入口,所以我们可以知晓这里的main是操作系统很重要的入口文件,main.c文件不是很大,但却包括了内核初始化的所有工作,主要是完成操作系统各种硬件数据结构的初始化。

小牛呼噜噜的博客 1405

内核解读之内存管理(5)内存模型

还是用于进程的页表?如果物理内存空间是一个连续的,没有空洞的地址空间,那么这种计算机系统的内存模型就是Flat memory,如图所示,我们将内存分成一页一页的Page frame,描述page frame的结构体page组成一个数组mem_map,通过将地址转换成页帧号(即该地址对应的page在page数组中的索引)可以取得该地址对应的page,就可以访问任何一页物理内存。如果是极致sparse内存模式,用一个page的大小来存放一个root的所有mem_section,也就是一个root有。

二进制君 2041

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

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

二进制君 2429

[Linux内核源码阅读笔记] 3 内存管理基础

文章目录虚拟地址空间1 内存管理子系统1.1 物理层面1.2 内核层面1.3 用户层面2 物理内存以及内核空间虚拟内存的管理2.1 页表的工作原理2.2 TLB的管理2.3 伙伴系统2.4 Slab/Slub/Slob块分配器2.5 不连续页分配器3 用户空间虚拟内存的管理3.1 用户虚拟地址空间的布局3.2 内存映射的实现3.3 堆的管理4 关于缺页异常5 用户空间与内核空间的数据拷贝补充:物理内存的组织结构 虚拟地址空间 虚拟地址的引入使得一个进程所能使用的最大地址空间与实际可用的物理内存数量无关。也就

jiang_T的博客 1455

Linux 内核解读之内存管理----memory.c

转载请注明原文出处http://blog.csdn.net/lizhiliang06/article/details/8655115 80x86体系结构中,Linux内核的内存管理程序使用分页管理方式。利用页目录和页表结构处理内核中其他部分代码对内存申请和释放操作。Memory.s是linux内存管理的核心,80x86内存管理最大寻址范围是4G的内存空间,在最大1024*1024*4KB的范

2026

linux0.12 内存管理

该文章主要介绍了Linux系统中的内存管理机制。首先说明了物理内存的划分结构,包括内核模块、高速缓冲区和主内存区。其次详细解释了四种内存地址类型:虚拟地址、逻辑地址、线性地址和物理地址。文章重点阐述了内存分段机制的工作原理,包括实模式和保护模式下的寻址方式,以及全局描述符表(GDT)和局部描述符表(LDT)的作用。最后介绍了内存分页管理机制,说明了如何通过分页将线性地址转换为物理地址,并提到CR3寄存器保存当前页目录表的基地址。这些机制共同构成了Linux系统的虚拟内存管理框架。

无 650

linux内核开发-3:linux内核源码介绍

孙子兵法·谋攻篇》中提到“知彼知己,百战不殆”。因此想学习linux内核开发,首先需要对内核源码有个基本的认识,然而linux源码太大,以为例,解压后为1.2G,这么多的代码让人不知如何下手,因此需要对Linux内核源码的各个部分有所了解才能缓解代码焦虑。本系列是学习B站”简说linux“老师的《linux内核开发50讲》的学习文档,有兴趣的可以看原版视频。

sydwy的专栏 1777
上一篇: Linux0.12内核之内存管理(2)
下一篇: Linux内核之内存管理(4)--缺页处理程序
OS技术解密
博客等级 码龄16年 3760粉丝 189原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值