热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux0.11内核源码分析系列:内存管理get_empty_page()与put_page()函数分析

**Author:DavidLin*Date:2014-11-22pm*Email:linpeng1577@163.comorlinpeng1577@gmail.com*w
/*   
 *Author  : DavidLin   
 *Date    : 2014-11-22pm   
 *Email   : linpeng1577@163.com or linpeng1577@gmail.com   
 *world   : the city of SZ, in China   
 *Ver     : 000.000.001   
 *history :     editor      time            do   
 *          1)LinPeng       2014-11-22      created this file!   
 *          2)   
 */ 
/*
 * This function puts a page in memory at the wanted address.
 * It returns the physical address of the page gotten, 0 if
 * out of memory (either when trying to access page-table or
 * page.)
 */	
unsigned long put_page(unsigned long page,unsigned long address)
{
	unsigned long tmp, *page_table;

/* NOTE !!! This uses the fact that _pg_dir=0 */    
//页目录表从0地址开始是先决条件
	if (page = HIGH_MEMORY)  
		printk("Trying to put page %p at %p\n",page,address);
        //物理地址是主内存地址?否则发出警告
        
	if (mem_map[(page-LOW_MEM)>>12] != 1)       
		printk("mem_map disagrees with %p at %p\n",page,address);
        //检查主内存管理数组相应物理页索引值
        //如果不是已经被申请次数为1
        //的物理地址,发出警告
        
	page_table = (unsigned long *) ((address>>20) & 0xffc); 
        //获取页目录项
        //此处page_table代表页目录项
        //页表是保存在页目录项中
        //一个页目录项管理一个页表
        //一个页表有1024个页表项
        
	if ((*page_table)&1)     //检查页表有效位P是否在内存中  
		page_table = (unsigned long *) (0xfffff000 & *page_table);
        //页目录项所保存的页表有效
        //获取页表
        //将页表值存入页目录项,所以31-21位不清零
        //此处page_table代表页表
	else {                                      //页目录项所保存的页表无效
		if (!(tmp=get_free_page()))         //申请一块空闲物理页保存页表 
			return 0;                   //如果失败,返回0
		*page_table = tmp|7;                //将页表地址保存到页目录项
		page_table = (unsigned long *) tmp; //页表指针指向新申请的物理页
                                                    //此处page_table只用于
                                                    //页表项在页表中偏移地址计算
	}                                           //一个页表管理1024个页表项
                                                    //一个页表项对应4K物理地址
	page_table[(address>>12) & 0x3ff] = page | 7;
        //(addree>>12) & 0x3ff可以获取物理页(页表项)在页表中的偏移地址
        //因为与0x3ff相与,即011,1111,1111B可以清除address中保存的页目录项的值
        //page | 7表示用户级,可读写,页最低位P有效
        
/* no need for invalidate */
        //因为只是更新页表,没有实际物理内容更新,不需要更新换高速缓存
        
	return page;   //返回物理页地址
}

//用于将线性地址address映射到实际物理页
void get_empty_page(unsigned long address)
{
	unsigned long tmp;

	if (!(tmp=get_free_page()) || !put_page(tmp,address)) {
        //如果没有空闲物理页,die
        //如果无法将申请的物理页挂载到线性地址中,die
		free_page(tmp);		/* 0 is ok - ignored */
                //释放该物理页
		oom();
                //内存溢出,报错,死机
	}
}





Linux-0.11内核源码分析系列:内存管理get_empty_page()与put_page()函数分析


推荐阅读
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了指针的概念以及在函数调用时使用指针作为参数的情况。指针存放的是变量的地址,通过指针可以修改指针所指的变量的值。然而,如果想要修改指针的指向,就需要使用指针的引用。文章还通过一个简单的示例代码解释了指针的引用的使用方法,并思考了在修改指针的指向后,取指针的输出结果。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
author-avatar
毒菇求败的zyqy_654
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有