ucore lab2 物理内存管理 学习笔记
总的来讲把的LAB1代码逻辑理顺后再往后学就轻松了一大截.LAB2过遍课程视频,再多翻翻实验指导书基本上就没遇到啥大坎儿.对这节学得东西做个总结就是一张图:
练习0:填写已有实验
本实验依赖实验1。请把你做的实验1的代码填入本实验中代码中有“LAB1”的注释相应部分。
提示:可采用diff和patch工具进行半自动的合并(merge),也可用一些图形化的比较/merge
工具来手动合并,比如meld,eclipse中的diff/merge工具,understand中的diff/merge工具
等。
我是用meld手动合并的.也就那几个填空的函数合一下
文件结构分析
bootasm.S:
将内存分布状态存储到0x8000
kernel.ld:
把kernel入口函数设为了kern_entry
entry.S:
初始化页表
建立物理内存0~4M到虚拟内存KERNBASE+0 ~ KERNBASE+4M的映射
使能页机制
长跳指令进入高内存地址
设置内核栈
调用init.c的kern_init
init.c:
无修改
memlayout.h:
增加KERNBASE等相关常量
增加E820MAP结构体描述内存分布
增加Pages结构体及相关的setter和getter宏
mmu.h:
增加线性地址相关的宏
pmm.c&.h:
增加了pmm_manager抽象类(运用结构体和函数指针实现)
增加了
增加物理地址与虚拟地址换算的宏
pmm_init:
设置CR3寄存器
初始化pmm_manager
初始化page
检测分配的page
检测PD
把pgdir插入到pgdir自身中
将物理地址映射到虚拟地址中
LA: KERNBASE~KERNBASE+KMEMSIZE -> PA: 0 ~ KMEMSIZE
初始化GDT
init_pmm_manager:
将default_pmm_manager设为当前PMM,并初始化
init_page:
根据E820MAP求出最大物理内存,总页数
将page数组放到KERNEL末尾之后的内存区域
(0----KERNEL----PAGE数组----自由内存区域---最大内存)
将所有page设为保留状态
对E820MAP里的所有内存块进行初始化内存映射(init_memmap)
init_memmap
调用PMM的init_memmap
练习1:实现 first-fit 连续物理内存分配算法(需要编程)
在实现first fit 内存分配算法的回收函数时,要考虑地址连续的空闲块之间的合并操作。提示:
在建立空闲页块链表时,需要按照空闲页块起始地址来排序,形成一个有序的链表。可能会
修改default_pmm.c中的default_init,default_init_memmap,default_alloc_pages,
default_free_pages等相关函数。请仔细查看和理解default_pmm.c中的注释。
就硬照着给的参考代码撸就行.撸完再改改BUG.
default_pmm.c&.h:
实现了一个默认的pmm_manager
default_init:
空闲块链表置空
空闲块计数器归零
default_init_memmap:
将给定的page区域初始化,设置页状态(空闲头页,非保留)并放入空闲块链表
default_alloc_pages:
实现最先匹配法分配页,更新页状态(保留,非空闲头页),更新空闲块链表状态
default_free_pages:
释放页,并把相邻的空闲块合并,更新空闲块链表
练习2:实现寻找虚拟地址对应的页表项(需要编程)
通过设置页表和对应的页表项,可建立虚拟内存地址和物理内存地址的对应关系。其中的
get_pte函数是设置页表项环节中的一个重要步骤。此函数找到一个虚地址对应的二级页表项
的内核虚地址,如果此二级页表项不存在,则分配一个包含此项的二级页表。本练习需要补
全get_pte函数 in kern/mm/pmm.c,实现其功能。请仔细查看和理解get_pte函数中的注释。
牵扯到指向指针的指针,物理地址与线性地址选择.做的时候就很晕.引用BALDR SKY DRIVE里的一幕:
//PDE,PTE本身存储的是物理地址和标志位
//各类指针变量用的是线性地址
pde_t *pdep=pgdir+PDX(la); //指针指向要访问的PDE
if((*pdep)&PTE_P){ //当PDE存在,对应的二级页表也存在
return ((pte_t*)KADDR((PDE_ADDR(*pdep))))+PTX(la);
//返回PDE对应的PTE的指针
//1.清空PDE末尾标志位,使其变成物理地址
//2.物理地址转为线性地址
//3.转化为指向pt头部的指针
//4.指向目标pte
}
else{
if(!create){//页表不存在又不创建新页表,返回空
return NULL;
}
struct Page *page=alloc_pages(1);//每个页表1024项,每项4B,刚好占一页
if(page==NULL){//分配不成功
return NULL;
}
page->ref=1;//引用一次
uintptr_t pa=page2pa(page);//求出page的物理地址
memset(KADDR(pa),0,PGSIZE);//把新建页表的内存区域清零
(*pdep)=pa|PTE_P|PTE_W|PTE_U;//更新PDE的信息(物理内存和标志位)
return ((pte_t*)KADDR((PDE_ADDR(*pdep))))+PTX(la);
//返回PDE对应的PTE的指针
}
请描述页目录项(Page Directory Entry)和页表项(Page Table Entry)中每个组成部分的含义以及对ucore而言的潜在用处:
这俩玩意都占32B,高24位为物理地址,低12位为标志位.具体含义直接看源码
练习3:释放某虚地址所在的页并取消对应二级页表项的映射(需要编程)
当释放一个包含某虚地址的物理内存页时,需要让对应此物理内存页的管理数据结构Page做
相关的清除处理,使得此物理内存页成为空闲;另外还需把表示虚地址与物理地址对应关系
的二级页表项清除。请仔细查看和理解page_remove_pte函数中的注释。为此,需要补全在
kern/mm/pmm.c中的page_remove_pte函数。
注释给的太全了,直接出代码就行
数据结构Page的全局变量(其实是一个数组)的每一项与页表中的页目录项和页表项有
无对应关系?如果有,其对应关系是啥?
页目录项存着对应页表项的物理地址,页表项存着对应Page的物理地址
疑问解答
如何理解lab2的内存布局?
/* *
* Virtual memory map: Permissions
* kernel/user
*
* 4G ------------------> +---------------------------------+
* | |
* | Empty Memory (*) |
* | |
* +---------------------------------+ 0xFB000000
* | Cur. Page Table (Kern, RW) | RW/-- PTSIZE
* VPT -----------------> +---------------------------------+ 0xFAC00000
* | Invalid Memory (*) | --/--
* KERNTOP -------------> +---------------------------------+ 0xF8000000
* | |
* | Remapped Physical Memory | RW/-- KMEMSIZE
* | |
* KERNBASE ------------> +---------------------------------+ 0xC0000000
* | |
* | |
* | |
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* (*) Note: The kernel ensures that "Invalid Memory" is *never* mapped.
* "Empty Memory" is normally unmapped, but user programs may map pages
* there if desired.
*
* */
初看不理解,读完代码再看就指导了.KERNBASE,KMEMSIZE等等这些数都是代码里规定好的常量,是人为规定的分布.
ucore lab2 物理内存管理 学习笔记的更多相关文章
- ucore操作系统学习笔记(二) ucore lab2物理内存管理分析
一.lab2物理内存管理介绍 操作系统的一个主要职责是管理硬件资源,并向应用程序提供具有良好抽象的接口来使用这些资源. 而内存作为重要的计算机硬件资源,也必然需要被操作系统统一的管理.最初没有操作系统 ...
- ucore lab3 虚拟内存管理 学习笔记
做个总结,这节说是讲虚拟内存管理,大部分的时间都在搞SWAP机制和服务于此机制的一些个算法.难度又降了一截. 不过现在我的电脑都16G内存了,能用完一半的情景都极少见了,可能到用到退休都不见得用的上S ...
- C++内存管理学习笔记(7)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- C++内存管理学习笔记(5)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- C++内存管理学习笔记(6)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- Docker Image管理学习笔记,ZT
Docker Image管理学习笔记 http://blog.csdn.net/junjun16818/article/details/38423391
- ChCore Lab2 内存管理 实验笔记
本文为上海交大 ipads 研究所陈海波老师等人所著的<现代操作系统:原理与实现>的课程实验(LAB)的学习笔记的第二篇.所有章节的笔记可在此处查看:chcore | 康宇PL's Blo ...
- Linux内存管理学习笔记 转
https://yq.aliyun.com/articles/11192?spm=0.0.0.0.hq1MsD 随着要维护的服务器增多,遇到的各种稀奇古怪的问题也会增多,要想彻底解决这些“小”问题往往 ...
- Linux文件与目录管理(学习笔记)
本笔记为<鸟哥linux私房菜>第六章学习笔记 一.目录与路径 相对路径与绝对路径 绝对路径:一定由根目录 / 写起 正确度比较好 相对路径:不是由 / 写起 ...
随机推荐
- Dubbo 用到哪些设计模式?
Dubbo 框架在初始化和通信过程中使用了多种设计模式,可灵活控制类加载.权 限控制等功能. 工厂模式 Provider 在 export 服务时,会调用 ServiceConfig 的 export ...
- Kafka 的设计架构你知道吗?
Producer :消息生产者,就是向 kafka broker 发消息的客户端. Consumer :消息消费者,向 kafka broker 取消息的客户端. Topic :可以理解为一个队列,一 ...
- 如何在自定义端口上运行 Spring Boot 应用程序?
为了在自定义端口上运行 Spring Boot 应用程序,您可以在 application.properties 中指定端口. server.port = 8090
- 有哪些类型的通知(Advice)?
Before - 这些类型的 Advice 在 joinpoint 方法之前执行,并使用 @Before 注解标记进行配置. After Returning - 这些类型的 Advice 在连接点方法 ...
- 学习MFS(三)
1.MooseFS是什么 一个类MooseFS是一个具备冗余容错功能的分布式网络文件系统,它将数据分别存放在多个物理服务器或单独磁盘或分区上,确保一份数据有多个备份副本,然而对于访问MFS的客户端或者 ...
- pygame.error: video system not initialized
在pygame写游戏出现pygame.error: video system not initialized 源代码 import sysimport pygamedef run_game(): py ...
- 搞懂高并发性能指标:QPS、TPS、RT、吞吐量
一.QPS,每秒查询 QPS:Queries Per Second意思是"每秒查询率",是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的 ...
- 开源HTML5游戏引擎Kiwi.js 1.0正式发布
Kiwi.js是由GameLab开发的一款全新的开源HTML5 JavaScript游戏引擎.在经过一年多的开发和测试之后,终于在日前正式发布了Kiwi.js 1.0版本. 其创始人Dan Milwa ...
- 活字格发布新版本,插件公开,引领Web开发新潮流
日前,活字格Web 应用生成平台发布V4.0版本,首次公开插件机制,强大的扩展性和系统集成能力,引起业内瞩目. 活字格是由西安葡萄城自主研发的 Web 应用生成平台,提供易用的类Excel可视化设计器 ...
- Redis 中的过期删除策略和内存淘汰机制
Redis 中 key 的过期删除策略 前言 Redis 中 key 的过期删除策略 1.定时删除 2.惰性删除 3.定期删除 Redis 中过期删除策略 从库是否会脏读主库创建的过期键 内存淘汰机制 ...