欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自己动手写操作系统(六)

程序员文章站 2024-03-24 11:51:04
...

    今天开始进入内存管理的编写。按照顺序,我们首先要实现的是kmalloc。在arale os中我们用coalition_allocator来进行kmalloc对应的内存管理。实际上,coalition_allocator的内存管理方法是参照了buddy来的。有兴趣的同学可以在网上找到很多关于buddy的内存管理文章,这里就不在多说了。

    我们先来看几个比较关键的结构体:

1.已分配内存头:    

typedef struct pmm_stamp
{
    int type;
    union 
    {
        mm_page page;
        core_mem_cache_content cache_content;
    };
}pmm_stamp;
    这个结构体实际上是用来标记了分配出去的内存类型/相关的page信息。每次分配内存时,我们都会多分配一些内存来保存这个信息。方便之后的内存释放和管理。下图就是实际的内存非配内容:

    |pmm_stamp|memory

                           |

                           |

                           这里是返回给上层的地址(addr),我们可以通过(pmm_stamp *)(addr - sizeof(pmm_stamp))就可以获取当前分配出内存的所有信息。

其中type主要有下面几类:

enum PMM_TYPE {
    PMM_TYPE_NORMAL = 0,
    PMM_TYPE_PMEM,
    PMM_TYPE_CACHE
};
PMM_TYPE_NORMAL:正常的物理内存,它的头长度就是sizeof(pmm_stamp)

PMM_TYPE_PMEM:4K对齐物理内存,这个主要是用来给PGD用的,因为注册PGD的内存必须是4K对齐,所以它的起始地址也必须是4K对齐。如果使用NORMAL,有可能出现未4K对齐的情况。

PMM_TYPE_CACHE:小内存使用。


2.page信息

typedef struct mm_page 
{
    struct list_head ll;
    addr_t start_pa;
    uint32_t size;
    int type;
    core_mem_cache_content *cache; 
}mm_page;
    ll:主要用来插入free/used队列

   start_pa:记录物理地址

   size:记录内存大小,方便free

   cache:之后用来做小内存的slab管理


3.memory zone信息

typedef struct mm_zone
{
    addr_t start_pa;
    addr_t end_pa;
    //use the follow three param to do kswap.
    uint32_t pages_low;
    uint32_t pages_high;
    uint32_t pages_mid;

    //free pages
    uint32_t total_free_pages;
    zone_area nr_area[ZONE_FREE_MAX_ORDER]; //4K,8K,16K
    void (*alloctor_init)(addr_t start_address,uint32_t size);
    void* (*alloctor_get_memory)(uint32_t size);
    int (*alloctor_free)(addr_t address);
    void* (*alloctor_pmem)(uint32_t size);
    void (*alloctor_pmem_free)(addr_t address);
}mm_zone;
kmalloc主要是针对normal zone做的内存分配。所以我们用nr_area[]来管理4K/8K/16K/32K等等。而zone_area其实就是一个包含2个list的struct

typedef struct zone_area
{
    struct list_head free_page_list;
    struct list_head used_page_list;
    //uint32_t nr_free_pages; no use
}zone_area;
free_page_list:用来存放当前块对应的free 内存

user_page_list:用来存放当前块已分配的内存


内存关键的数据结构基本上就是上面这几个。接下来的处理就是用这些数据结构来管理物理内存。具体流程下篇继续。


arale os github:

https://github.com/wangsun1983/arale

    

    


相关标签: 操作系统