操作系统实战 45 讲
彭东
网名 LMOS,Intel 傲腾项目关键开发者
65203 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 60 讲
尝尝鲜:从一个Hello到另一个Hello (2讲)
特别放送 (1讲)
操作系统实战 45 讲
15
15
1.0x
00:00/00:00
登录|注册

17 | 划分土地(中):如何实现内存页面初始化?

合并内存页到内存区
处理初始内存占用问题
内存区结构初始化
内存页结构初始化
初始化汇总
初始化内存页结构
思考题
重点回顾
初始化
划分土地(中):如何实现内存页面初始化?

该思维导图由 AI 生成,仅供参考

你好,我是 LMOS。
上节课,我们确定了用分页方式管理内存,并且一起动手设计了表示内存页、内存区相关的内存管理数据结构。不过,虽然内存管理相关的数据结构已经定义好了,但是我们还没有在内存中建立对应的实例变量
我们都知道,在代码中实际操作的数据结构必须在内存中有相应的变量,这节课我们就去建立对应的实例变量,并初始化它们。

初始化

前面的课里,我们在 hal 层初始化中,初始化了从二级引导器中获取的内存布局信息,也就是那个 e820map_t 数组,并把这个数组转换成了 phymmarge_t 结构数组,还对它做了排序。
但是,我们 Cosmos 物理内存管理器剩下的部分还没有完成初始化,下面我们就去实现它。
Cosmos 的物理内存管理器,我们依然要放在 Cosmos 的 hal 层。
因为物理内存还和硬件平台相关,所以我们要在 cosmos/hal/x86/ 目录下建立一个 memmgrinit.c 文件,在这个文件中写入一个 Cosmos 物理内存管理器初始化的大总管——init_memmgr 函数,并在 init_halmm 函数中调用它,代码如下所示。
//cosmos/hal/x86/halmm.c中
//hal层的内存初始化函数
void init_halmm()
{
init_phymmarge();
init_memmgr();
return;
}
//Cosmos物理内存管理器初始化
void init_memmgr()
{
//初始化内存页结构msadsc_t
//初始化内存区结构memarea_t
return;
}
根据前面我们对内存管理相关数据结构的设计,你应该不难想到,在 init_memmgr 函数中应该要完成内存页结构 msadsc_t 和内存区结构 memarea_t 的初始化,下面就分别搞定这两件事。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了在内存中实现内存页面初始化的过程,以及解决内存占用问题的重要性。作者首先确定了使用分页方式管理内存,并设计了表示内存页、内存区相关的内存管理数据结构。在Cosmos物理内存管理器中完成初始化的过程中,作者详细介绍了从二级引导器中获取内存布局信息并转换成phymmarge_t结构数组的排序过程。文章还详细介绍了内存页结构的初始化过程,包括如何找到可用的内存地址,扫描phymmarge_t结构体数组中的信息,并建立一个msadsc_t结构体数组。通过详细的步骤和代码示例,读者可以了解如何在内存中实现内存页面初始化,并解决内存占用问题。 此外,文章还介绍了解决内存占用问题的重要性,以及如何标记已被占用的内存页面所对应的msadsc_t结构,以避免内存分配算法错误地分配已被占用的内存页。通过详细的步骤和代码示例,读者可以了解如何在内存中实现内存页面初始化,并解决内存占用问题。 总的来说,本文是一篇技术性较强的文章,通过详细的步骤和代码示例,帮助读者了解了如何在内存中实现内存页面初始化,以及解决内存占用问题。文章内容涉及内存管理数据结构设计、内存页结构初始化、解决内存占用问题的重要性等方面,对于从事系统开发和内存管理的技术人员具有一定的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《操作系统实战 45 讲》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(27)

  • 最新
  • 精选
  • neohope
    一、稍微整理了一下流程: init_hal->init_halmm->init_memmgr //每个页对应一个msadsc_t 结构体,循环填充msadsc_t 结构体数组 ->init_msadsc //初始化三类memarea_t,硬件区、内核区、用户区 ->init_memarea //对已使用的页打上标记,包括:BIOS中断表、内核栈、内核、内核映像 ->init_search_krloccupymm(&kmachbsp); //将页面按地址范围,分配给内存区 //然后按顺序依次查找最长连续的页面,根据连续页面的长度, //将这些页面的msadsc_t挂载到memdivmer_t 结构下的bafhlst_t数组dm_mdmlielst中 ->init_merlove_mem(); //物理地址转为虚拟地址,便于以后使用 ->init_memmgrob(); 二、对于最后的问题,用了虚拟机进行测试,但无论内存大小,总有56K内存没能找到【有知道的小伙伴,麻烦帮忙解答一下】: 1、4G内存情况如下: 理论内存:0x1 0000 0000 = 4,194,304K 可用内存:0xfff8fc00 = 4,193,855K 预留区域:0x52400 = 329K 硬件使用:0x10000 = 64K 没能找到:0xE000 = 56K msadsc_t结构体大小为40,使用内存总计为: 4,193,855K/4K*40=41,938,520=接近40M 2、2G内存情况如下 理论内存:0x8000 0000 =2,097,152K 可用内存:0x7ff8fc00 = 2,096,703K 预留区域:0x52400 = 329K 硬件使用:0x10000 = 64K 没能找到:0xE000 = 56K msadsc_t结构体大小为40,使用内存总计为: 2,096,703K/4K*40=20,967,030=接近20M 3、1G内存情况如下 理论内存:0x4000 0000= 1,048,576K 可用内存:0x3ff8fc00 = 1,048,127K 预留区域:0x52400 = 329K 硬件使用:0x10000 = 64K 没能找到:0xE000 = 56K msadsc_t结构体大小为40,使用内存总计为: 1,048,127K/4K*40=10,481,270=接近10M 三、如果想节约msadsc_t内存的话,感觉有几种方案: 1、最简单的方法,就是大内存时采用更大的分页,但应用在申请内存时,同样会有更多内存浪费 2、也可以用更复杂的页面管理机制,比如相同属性的连续页面不要用多个单独msadsc_t表示,而用一个msadsc_t表示并标明其范围,并通过skiplist等数据结构加速查询。但无论是申请内存还是归还内存时,性能会有所下降,感觉得不偿失。 3、页面分组情况较少的时候,可以通过每个组建立一个链表记录哪些页面属于某个链表,而msadsc_t中只记录地址等少量信息,不适合复杂系统。

    作者回复: 大神 6666

    2021-06-17
    5
    26
  • 黄光华
    老师,我觉得这个类、变量的命名可读性,还是非常非常重要的 这个项目是您手写的,每一个命名什么意思,你了然于胸 但是我们都是新手,很多变量命名真的太简略了,有很多命名就算琢磨也不一定能知道是什么意思。 真心建议命名可读性还是要增强一下哈~~

    作者回复: 好的

    2021-09-02
    25
  • 小李飞刀
    大佬的这个变量命名是真的把我看懵了。。。

    作者回复: 哈哈

    2022-06-25
    2
  • 朱炜敏
    老师,初始化这些数据结构的过程跟行为,让我想到了自己在电脑上装上4G内存条后,上电后发现系统反馈的可用内存一般只有3.8G左右。 是不是类似的,消失的几百兆内存里,存放的就是这些页管理的数据结构?

    作者回复: 还有内核 的其它数据 但32位下 只能使用2.8GB

    2021-11-04
    2
  • pedro
    胡乱一猜~ msadsc_t 占用内存 = 4GB/4KB(页大小) * sizeof(msadsc_t )

    作者回复: 是的

    2021-06-16
    3
    2
  • 秋宇雨
    u1s1,代码命名真心看晕了

    编辑回复: 攻略:关注下这些代码要实现的功能是啥。还是死磕不出来的展开说说,大家一起讨论解决。

    2022-01-28
    1
  • 浮生尽歇
    怎么调试内核呢?

    作者回复: KPrint

    2021-11-14
    1
  • 杨军
    这一讲的内容、概念很多,尤其是内存页合并到内存区的代码不好理解,建议大家把16讲的内存页面组织结构图放在手边,对照代码多看几次慢慢就有感觉了,加油,过了内存管理这道坎,就看见胜利的曙光了

    作者回复: 哈哈

    2021-09-19
    1
  • Geek_a5edac
    代码的命名,不太好懂,能说下命名规则么,一些看很久才知道是哪些缩写

    作者回复: 不需要搞懂的,不要陷入名词概念之中

    2021-07-24
    1
  •     
    求助一下可能是编译或者是链接方面的问题。不知道为什么全局变量被定义到了很远的位置。比如kernel.bin的大小只有56512Byte。地址从0x2000000开始。所以我设定mb_nextwtpadr的初始值为0x200e000。但是全局变量的地址却被定义在了0x220e000。这样导致了用mb_nextwtpadr向后申请内存的最终会覆盖掉全局变量的数据。想知道gcc或者ld的什么参数可以改变全局变量所在的位置啊?

    作者回复: 看看链接器脚本 data 和 bss 的位置

    2022-12-06归属地:湖北
    2
收起评论
显示
设置
留言
27
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部