内存管理

内存管理

1.内存相关结构体

设计了E820结构体,Zone结构体,Page结构体,Slab结构体,SlabPool结构体,Memory结构体。

1.E820
struct E820{
    unsigned long address;//该块内存的物理开始地址
    unsigned long length;//该块内存的长度
    unsigned int   type;//该块内存的类型
}__attribute__((packed));

E820结构体保存的是一块物理内存的信息,该信息在loader阶段保存到物理地址0x7e00处,kernel的内存初始化阶段将会从0x7e00处读取所有的物理内存信息并赋值E820结构体。

表 type物理内存类型

类型值描述
01h可用物理内存
02h保留或无效值(包括ROM、设备内存)
03hACPI的回收内存
04hACPINVS内存
其他值未定义,保留使用
2.Page
struct Page
{
    //区域属性
    unsigned long zoneAttribute;//对应于上述的type类型
    //页的开始物理地址
    unsigned long   physicsAddress;
    //页的属性(0:未使用,1:内核使用,2:用户使用,3:Slab使用)
    unsigned long  attribute;
    //保留
    unsigned long reserve[2];
};

Page对应一个物理页的信息,KePOS操作系统设计的一个页大小为2M。

3.Zone
struct Zone{
    //该区域的页位图映射
    unsigned long * bitmap;
    //区域管理的开始页位置
    struct Page * pages;
    //该区域管理的页总数
    unsigned long length;
};

Zone结构体对应每一个类型的物理内存区域,总共有5中类型的区域(等于E820.type),所以内存结构体Memory会维护一个Zone[5]数组。

pages与length共同表示一个变长的数组Pages[length]。

4.SlabPool和slab

这两个结构体主要的功能是:分配和回收一块物理内存给内核代码使用,借鉴了linux中的设计与实现。

如果内核某个代码申请一块物理内存,则可以使用getMemoryBlock(unsigned long blockSize)获取一块不大于blockSize的物理内存,该函数会返回申请到的内存块的开始线性地址。相应的可以使用backMemoryBlock(unsigned long virtualAddress)归坏一块物理内存。

//代表一块特定大小(blockSize)的内存池对象
struct SlabPool{
    unsigned long blockSize; //该slabPool课分配的最大blocksize
    struct Slab * head; //指向第一个slab
    struct Slab * now;	//未使用
    struct Slab * reserve; //未使用
    unsigned long useCount; //当前slabPool已经使用了的内存块
    unsigned long freeCount;//当前slabPool还空闲的内存块
};
struct Slab{
    //链子(双向循环链表)
    struct Slab * prev; 
    struct Slab * next;
    //管理的页
    unsigned long pageID;
    //使用计数
    unsigned long usingCount;
    //空闲计数
    unsigned long freeCount;
    //对应的虚拟地址
    unsigned long virtualAddress;
    //区域的位图映射
    unsigned long * bitMap;
    //位图长度
    unsigned long bitMapLength;
};
//KePOS支持的blockSize(32b-->4096b)
struct SlabPool temSlabPool[7] = {
            {32,NULL,NULL,NULL,0,0},
            {64,NULL,NULL,NULL,0,0},
            {128,NULL,NULL,NULL,0,0},
            {256,NULL,NULL,NULL,0,0},
            {512,NULL,NULL,NULL,0,0},
            {1024,NULL,NULL,NULL,0,0},
            {4096,NULL,NULL,NULL,0,0}, 
    };

每一个slap结构体保存到一个物理页的开始部分,然后管理该物理页的可用内存块。

初始时每一个slabpool的head为NULL,当需要分配该slabpool管理的一块内存时,会首先获取一个物理页,然后将该物理页的开始部分赋值一个slap结构体。

5.Memory
//保存在内核.bss段
struct Memory{
    //管理的E820结构体
    struct E820 e820[32];
    unsigned int e820Length;
    //管理的区域
    struct Zone zone[5];
    //SlabPooL
    struct SlabPool slabPool[7];
};

该结构体只有一个全局变量memory,用于管理系统的各个内存结构体。

图 内存结构体关系图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3m6eE7k0-1619108954616)(https://z3.ax1x.com/2021/04/22/cOZatg.gif)]

2.内存地址

1.地址转换

地址转换具体就是在长模式中,把线性地址->物理地址。本系统只使用了GDT,IDT段表,和3级页表(即最后每一个物理页为2M)

2.线性地址划分

系统中内核占据线性地址0xffff800000000000->0xffffffffffffffff,在内核的内存代码运行完后,物理地址空间中的所有物理地址(a)都被映射为线性地址(a+0xffff800000000000),即内核代码可以访问任意物理地址。

用户代码使用线性地址0-0x00007fffffffffff。

3.CDT表
GDT_Table:
   .quad  0x0000000000000000       /*0    NULL descriptor                  00*/
   .quad  0x0020980000000000       /*1    KERNEL Code   64-bit Segment    08*/
   .quad  0x0000920000000000       /*2    KERNEL Data   64-bit Segment    10*/
   .quad  0x0000f20000000000       /*3    USER   Data   64-bit Segment    18*/
   .quad  0x0020f80000000000       /*4    USER   Code   64-bit Segment 20*/
   .quad  0x00cf9a000000ffff       /*5    KERNEL Code   32-bit Segment    28*/
   .quad  0x00cf92000000ffff       /*6    KERNEL Data   32-bit Segment    30*/
   .fill  10,8,0             /*8 ~ 9    TSS (jmp one segment <7>) in long-mode 128-bit 40*/
GDT_END:

在GDT表中:

内核态代码和数据分别使用1,2;对应的段选择子为(08,10)

用户态代码和数据分别使用4,3;对应的段选择子为(20,18)

8~9为TSS的描述符

3.参考

AMD64 Architecture Programmer’s Manual Volume 2: System Programming)

一个64位操作系统的设计与实现(第 6 章 处理器体系结构)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值