初步内存管理

初级内存管理

展示如何获取物理内容信息、统计可用物理内存 页数量以及内存分配物理页等相对基础的功能。

关于可用物理内存的相关信息,已经在Loader引导加载程序中通过BIOS中断服务程序获得,同时系统采用2MB物理页。

获取物理内存信息

物理信息通过BIOS中断服务程序INT 15h AX=E820h获得,并保存在物理地址7E00h处。接下来,将会把物理地址7E00h处的信息提取出来,转换成相应结构体再加以统计。

地址7E00h出的物理地址空间信息存有若干组,他们描述计算机平台的地址空间划分情况,其数量会依据当前主板硬件配置和物理内存容量信息而定,每条物理址空间信息占20B,详细 定义如代码

struct Memory_E820_Formate
{
	unsigned int address1;
    unsigned int address2;
    unsigned int length1;
    unsigned int length2;
    unsigned int type;
};

准备好数据解析结构后,视同结构体格式化物理地址7E00h处的数据。不过7E00h是物理地址,必须经过页表映射后才能配程序使用,转换后的线性地址是ffff800000007e00h,这边是程序要操作的目标地址。

分配可用物理内存页

在操作系统中,内存管理单元是操作系统最为重要的一个组成部分,而物理内存页是内存 管理单元的基础管理对象。因此,初始化内存管理单元的首要任务就是 汇总可用的物理内存也的相关信息,放可实现可用物理内存也的分配功能。

为了汇总可用物理内存信息并方便以后管理,现在特将整个内存空间(通过E820功能返回的各个内存段信息包括RAM,ROM 保留空间等),按2MB大小的物理内存页进行分割和对齐。分割后的每个物理内存页由一个struct page结构体负责管理,然后使用区域空间结构体struct zone代表各个可用物理内存区域(可用物理段),并记录和管理本区域物理内存页的分配情况。最后将struct page 和struct zone 结构体都保存到全局结构体struct Global_Memory_Descriptor内。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bp3kX7Gu-1635080641317)(C:\Users\86187\AppData\Roaming\Typora\typora-user-images\image-20211020200122002.png)]

struct结构包含所有内存页结构体,zones_struct结构体包含所有区域空间结构体,他们增强了全局结构体struct Global_Memory_Descriptor中索引出对应的区域空间结构和内存结构,并调整区域空间结构的管理信息与页结构的属性和参数。所需要的数据结构有

struct E820
{
    /* data */
    unsigned long address;
    unsigned long length;
    unsigned int type;
}__attribute__((packed));

struct Global_Memory_Descriptor
{
    struct E820 e820[32];   //物理内存段结构数组
    unsigned long e820_length; //物理内存段结构数组长度

    unsigned long *     bit_map; //物理地址空间页映射位图
    unsigned long       bit_size; //物理地址空间页数量
    unsigned long       bit_length; //物理地址空间也映射位图长度

    struct Page *       pages_struct; // 指向全局struct page 结构体数组的指针
    unsigned long       pages_size; // struct page结构体总数
    unsigned long       pages_length; // struct page 结构体数组长度

    struct Zone *       zones_struct; //指向全局struct zone 结构体数组的指针
    unsigned long       zones_size; // 结构体数量
    unsigned long       zones_length; // 结构体数组长度
                    //  内核程序的起始代码段地址
    unsigned long       start_code,
     end_code, // 内核程序的结束代码段地址
      end_data, //内核程序的结束数据段地址
      end_brk; // 内核程序的结束地址

    unsigned long       end_of_struct; // 内存页管理结构的结尾地址
};

extern struct Global_memory_Descriptor memory_management_struct;

struct Global_Memory_Descriptor memory_management_struct = {{0},0};

struct Page
{
    struct Zone *   zone_struct;// 指向本页所属的区域结构体
    unsigned long   PHY_address;// 页的物理地址
    unsigned long   attribute; // 页的属性

    unsigned long   reference_count; //描述的是该页的引用次数

    unsigned long   age; // 描述的是该页的创建时间
};


struct Zone
{
    struct Page *   pages_group;//struct page 结构体数组指针
    unsigned long   pages_length; // 本区域包涵的struct page结构体数量
    unsigned long   zone_start_address;// 本区域的起始页对齐地址
    unsigned long   zone_end_address; // 本区域的结束页对齐 地址
    unsigned long   zone_length; // 本区域经过页对齐后的地址长度
    unsigned long   attribute; // 本区域空间的属性

    struct Global_Memory_Descriptorr *  GMD_struct;//指向 全局结构体 struct Global_Memory_Descriptor

    unsigned long   page_using_count;   // 本区域已使用物理内存页数量
    unsigned long   page_free_count; // 本区域空闲物理内存页数量
 
    unsigned long total_pages_link; // 本区域物理页被引用次数
};

表中的bits_***相关字段是page结构体的位图映射,他们是一一对应的关系。建立bits位图映射的目的是为了方便检索pages_struct中的空闲页表映射,而pages_xxx和zones_xxx相关变量就比较好理解,他们用来揭露page和zone结构体数组的首地址以及资源分配情况等信息。至于start_code、end_code、end_data、end_brk这4个成员变量,他们用于保存内核程序编译后的各段首尾地址(包括代码段、数据段、BSS段等),而 首尾地址则是kernel.lds文件中定义

掩码

掩码是串二进制代码对目标字段进行位与运算,屏蔽当前的输入位。

代码中追加了判断条件,来截断并提出E820数组中的脏数据。之后,根据物理地址空间划分信息计算物理地址空间 的结束地址(目前的结束地址位于最后一条物理内存段信息中,但不排除其他可能性。)。把物理地址空间的结束地址按2MB页对齐,从而统计出物理地址空间可分页数。这个物理地址空间可分页数不仅包括可用物理内存,还包括内存空洞和ROM地址空间,将物理地址空间可分页数赋值给bits_size成员变量。成员变量bits_map是映射位图的指针,他指向内核程序结束地址end_brk的4KB上边界对齐

内存布局

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e3bRPJ4q-1635080641320)(C:\Users\86187\AppData\Roaming\Typora\typora-user-images\image-20211022234516691.png)]
在这里插入图片描述

内存最多可从DMA区域空间、已映射区域空间或者未映射页表区域空间里,一次性申请64个连续的物理页,并设置这些物理页对应的struct page属性。

​ alloc_pages会根据zone_select参数来判定需要检索的内存区域空间,如果zone_select参数无法匹配到相应的区域空间,则会打印错误日志信息并使函数返回。目前的bochs虚拟机只能开辟出2GB的物理内存空间,以至于虚拟平台仅有一个可用物理内存段,因此zone_dma_index、zone_normal_index和zone_unmaped_index三个变量均代表同一内存区域空间,即使用默认值0代表的内存区域空间。

​ 既然已经确认检测的目标内内存区域空间,接下来将从该区域空间中遍历出申请条件的struct page结构体数组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值