mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 15:26:47 +00:00
🆕 初始化内存池组
This commit is contained in:
parent
dc3aa2ae8a
commit
8e1a0c9a4b
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -14,6 +14,8 @@
|
|||||||
"asm.h": "c",
|
"asm.h": "c",
|
||||||
"memory.h": "c",
|
"memory.h": "c",
|
||||||
"irq.h": "c",
|
"irq.h": "c",
|
||||||
"multiboot2.h": "c"
|
"multiboot2.h": "c",
|
||||||
|
"kprint.h": "c",
|
||||||
|
"8259a.h": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ void mm_init()
|
|||||||
struct multiboot_mmap_entry_t *mb2_mem_info;
|
struct multiboot_mmap_entry_t *mb2_mem_info;
|
||||||
int count;
|
int count;
|
||||||
multiboot2_iter(multiboot2_get_memory, mb2_mem_info, &count);
|
multiboot2_iter(multiboot2_get_memory, mb2_mem_info, &count);
|
||||||
|
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
//可用的内存
|
//可用的内存
|
||||||
@ -68,7 +68,7 @@ void mm_init()
|
|||||||
memory_management_struct.bmp_len = (((unsigned long)(max_addr >> PAGE_2M_SHIFT) + sizeof(unsigned long) * 8 - 1) / 8) & (~(sizeof(unsigned long) - 1)); // bmp由多少个unsigned long变量组成
|
memory_management_struct.bmp_len = (((unsigned long)(max_addr >> PAGE_2M_SHIFT) + sizeof(unsigned long) * 8 - 1) / 8) & (~(sizeof(unsigned long) - 1)); // bmp由多少个unsigned long变量组成
|
||||||
|
|
||||||
// 初始化bitmap, 先将整个bmp空间全部置位。稍后再将可用物理内存页复位。
|
// 初始化bitmap, 先将整个bmp空间全部置位。稍后再将可用物理内存页复位。
|
||||||
memset(memory_management_struct.bmp, 0xff, memory_management_struct.bmp_len);
|
memset(memory_management_struct.bmp, 0xffffffffffffffff, memory_management_struct.bmp_len);
|
||||||
|
|
||||||
// 初始化内存页结构
|
// 初始化内存页结构
|
||||||
// 将页结构映射于bmp之后
|
// 将页结构映射于bmp之后
|
||||||
@ -184,18 +184,6 @@ void mm_init()
|
|||||||
|
|
||||||
global_CR3 = get_CR3();
|
global_CR3 = get_CR3();
|
||||||
|
|
||||||
/*
|
|
||||||
printk_color(INDIGO, BLACK, "cr3:\t%#018lx\n", cr3);
|
|
||||||
printk_color(INDIGO, BLACK, "*cr3:\t%#018lx\n", *(phys_2_virt(cr3)) & (~0xff));
|
|
||||||
printk_color(INDIGO, BLACK, "**cr3:\t%#018lx\n", *phys_2_virt(*(phys_2_virt(cr3)) & (~0xff)) & (~0xff));
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
// 消除一致性页表映射,将页目录(PML4E)的前10项清空
|
|
||||||
for (int i = 0; i < 10; ++i)
|
|
||||||
*(phys_2_virt(global_CR3) + i) = 0UL;
|
|
||||||
*/
|
|
||||||
|
|
||||||
flush_tlb();
|
flush_tlb();
|
||||||
|
|
||||||
kinfo("Memory management unit initialize complete!");
|
kinfo("Memory management unit initialize complete!");
|
||||||
@ -347,4 +335,15 @@ unsigned long page_clean(struct Page *p)
|
|||||||
++p->zone->count_pages_free;
|
++p->zone->count_pages_free;
|
||||||
--p->zone->total_pages_link;
|
--p->zone->total_pages_link;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 释放连续number个内存页
|
||||||
|
*
|
||||||
|
* @param page 第一个要被释放的页面的结构体
|
||||||
|
* @param number 要释放的内存页数量 number<64
|
||||||
|
*/
|
||||||
|
void free_pages(struct Page *page, int number)
|
||||||
|
{
|
||||||
|
// @todo: 释放连续number个内存页
|
||||||
|
}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
// 虚拟地址与物理地址转换
|
// 虚拟地址与物理地址转换
|
||||||
#define virt_2_phys(addr) ((unsigned long)(addr)-PAGE_OFFSET)
|
#define virt_2_phys(addr) ((unsigned long)(addr)-PAGE_OFFSET)
|
||||||
#define phys_2_virt(addr) ((unsigned long *)((unsigned long)(addr) + PAGE_OFFSET))
|
#define phys_2_virt(addr) ((unsigned long *)((unsigned long)(addr) + PAGE_OFFSET))
|
||||||
|
// 获取对应的页结构体
|
||||||
#define Virt_To_2M_Page(kaddr) (memory_management_struct.pages_struct + (virt_2_phys(kaddr) >> PAGE_2M_SHIFT))
|
#define Virt_To_2M_Page(kaddr) (memory_management_struct.pages_struct + (virt_2_phys(kaddr) >> PAGE_2M_SHIFT))
|
||||||
#define Phy_to_2M_Page(kaddr) (memory_management_struct.pages_struct + ((unsigned long)(kaddr) >> PAGE_2M_SHIFT))
|
#define Phy_to_2M_Page(kaddr) (memory_management_struct.pages_struct + ((unsigned long)(kaddr) >> PAGE_2M_SHIFT))
|
||||||
|
|
||||||
@ -219,7 +219,13 @@ struct Page *alloc_pages(unsigned int zone_select, int num, ul flags);
|
|||||||
*/
|
*/
|
||||||
unsigned long page_clean(struct Page *page);
|
unsigned long page_clean(struct Page *page);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 释放连续number个内存页
|
||||||
|
*
|
||||||
|
* @param page 第一个要被释放的页面的结构体
|
||||||
|
* @param number 要释放的内存页数量 number<64
|
||||||
|
*/
|
||||||
|
void free_pages(struct Page *page, int number);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 内存页表结构体
|
* @brief 内存页表结构体
|
||||||
|
@ -294,22 +294,21 @@ ul slab_free(struct slab *slab_pool, void *addr, ul arg)
|
|||||||
// 有对应的析构函数,调用析构函数
|
// 有对应的析构函数,调用析构函数
|
||||||
if (slab_pool->destructor != NULL)
|
if (slab_pool->destructor != NULL)
|
||||||
slab_pool->destructor((char *)slab_obj_ptr->vaddr + slab_pool->size * index, arg);
|
slab_pool->destructor((char *)slab_obj_ptr->vaddr + slab_pool->size * index, arg);
|
||||||
|
|
||||||
// 当前内存对象池的正在使用的内存对象为0,且内存池的空闲对象大于当前对象池的2倍,则销毁当前对象池,以减轻系统内存压力
|
// 当前内存对象池的正在使用的内存对象为0,且内存池的空闲对象大于当前对象池的2倍,则销毁当前对象池,以减轻系统内存压力
|
||||||
if((slab_obj_ptr->count_using==0)&&((slab_pool->count_total_free>>1)>=slab_obj_ptr->count_free))
|
if ((slab_obj_ptr->count_using == 0) && ((slab_pool->count_total_free >> 1) >= slab_obj_ptr->count_free))
|
||||||
{
|
{
|
||||||
// 防止删除了slab_pool的cache_pool入口
|
// 防止删除了slab_pool的cache_pool入口
|
||||||
if(slab_pool->cache_pool==slab_obj_ptr)
|
if (slab_pool->cache_pool == slab_obj_ptr)
|
||||||
slab_pool->cache_pool = container_of(list_next(&slab_obj_ptr->list), struct slab_obj, list);
|
slab_pool->cache_pool = container_of(list_next(&slab_obj_ptr->list), struct slab_obj, list);
|
||||||
|
|
||||||
list_del(&slab_obj_ptr->list);
|
list_del(&slab_obj_ptr->list);
|
||||||
slab_pool->count_total_free -= slab_obj_ptr->count_free;
|
slab_pool->count_total_free -= slab_obj_ptr->count_free;
|
||||||
|
|
||||||
kfree(slab_obj_ptr->bmp);
|
kfree(slab_obj_ptr->bmp);
|
||||||
page_clean(slab_obj_ptr->page);
|
page_clean(slab_obj_ptr->page);
|
||||||
free_pages(slab_obj_ptr->page,1);
|
free_pages(slab_obj_ptr->page, 1);
|
||||||
kfree(slab_obj_ptr);
|
kfree(slab_obj_ptr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -319,6 +318,89 @@ ul slab_free(struct slab *slab_pool, void *addr, ul arg)
|
|||||||
return ENOT_IN_SLAB;
|
return ENOT_IN_SLAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化内存池组
|
||||||
|
* 在初始化通用内存管理单元期间,尚无内存空间分配函数,需要我们手动为SLAB内存池指定存储空间
|
||||||
|
* @return ul
|
||||||
|
*/
|
||||||
|
ul slab_init()
|
||||||
|
{
|
||||||
|
// 将slab的内存池空间放置在mms的后方
|
||||||
|
ul tmp_addr = memory_management_struct.end_of_struct;
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
// 将slab内存池对象的空间放置在mms的后面,并且预留4个unsigned long 的空间以防止内存越界
|
||||||
|
kmalloc_cache_group[i].cache_pool = (struct slab_obj *)memory_management_struct.end_of_struct;
|
||||||
|
memory_management_struct.end_of_struct += sizeof(struct slab_obj) + (sizeof(ul) << 2);
|
||||||
|
|
||||||
|
list_init(&(kmalloc_cache_group[i].cache_pool->list));
|
||||||
|
|
||||||
|
// 初始化内存池对象
|
||||||
|
kmalloc_cache_group[i].cache_pool->count_using = 0;
|
||||||
|
kmalloc_cache_group[i].cache_pool->count_free = PAGE_2M_SIZE / kmalloc_cache_group[i].size;
|
||||||
|
kmalloc_cache_group[i].cache_pool->bmp_len = (((kmalloc_cache_group[i].cache_pool->count_free + sizeof(ul) * 8 - 1) >> 6) << 3);
|
||||||
|
kmalloc_cache_group[i].cache_pool->bmp_count = kmalloc_cache_group[i].cache_pool->count_free;
|
||||||
|
|
||||||
|
// 在slab对象后方放置bmp
|
||||||
|
kmalloc_cache_group[i].cache_pool->bmp = (ul *)memory_management_struct.end_of_struct;
|
||||||
|
|
||||||
|
// bmp后方预留4个unsigned long的空间防止内存越界,且按照8byte进行对齐
|
||||||
|
memory_management_struct.end_of_struct += kmalloc_cache_group[i].cache_pool->bmp_len + ((sizeof(ul) << 2) & (~sizeof(ul) - 1));
|
||||||
|
|
||||||
|
memset(kmalloc_cache_group[i].cache_pool->bmp, 0, kmalloc_cache_group[i].cache_pool->bmp_len);
|
||||||
|
|
||||||
|
kmalloc_cache_group[i].count_total_using = 0;
|
||||||
|
kmalloc_cache_group[i].count_total_free = kmalloc_cache_group[i].cache_pool->count_free;
|
||||||
|
/*
|
||||||
|
memset(kmalloc_cache_size[i].cache_pool->color_map,0xff,kmalloc_cache_size[i].cache_pool->color_length);
|
||||||
|
|
||||||
|
for(j = 0;j < kmalloc_cache_size[i].cache_pool->color_count;j++)
|
||||||
|
*(kmalloc_cache_size[i].cache_pool->color_map + (j >> 6)) ^= 1UL << j % 64;
|
||||||
|
|
||||||
|
kmalloc_cache_size[i].total_free = kmalloc_cache_size[i].cache_pool->color_count;
|
||||||
|
kmalloc_cache_size[i].total_using = 0;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Page *page = NULL;
|
||||||
|
|
||||||
|
// 将上面初始化内存池组时,所占用的内存页进行初始化
|
||||||
|
ul tmp_page_mms_end = virt_2_phys(memory_management_struct.end_of_struct >> PAGE_2M_SHIFT);
|
||||||
|
for (int i = PAGE_2M_ALIGN(virt_2_phys(tmp_addr)); i < tmp_page_mms_end; ++i)
|
||||||
|
{
|
||||||
|
page = memory_management_struct.pages_struct + i;
|
||||||
|
|
||||||
|
// 下面注释掉的这部分工作貌似在page_init()里面已经做了
|
||||||
|
// 在mms的bmp中,置位对应的位
|
||||||
|
//*(memory_management_struct.bmp + ((page->addr_phys>>PAGE_2M_SHIFT)>>6)) |= 1UL<<((page->addr_phys >> PAGE_2M_SHIFT)%64);
|
||||||
|
|
||||||
|
//++(page->zone->count_pages_using);
|
||||||
|
//--(page->zone->count_pages_free);
|
||||||
|
|
||||||
|
page_init(page, PAGE_KERNEL_INIT | PAGE_KERNEL | PAGE_PGT_MAPPED);
|
||||||
|
}
|
||||||
|
|
||||||
|
printk_color(ORANGE, BLACK, "2.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d\n", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
|
||||||
|
|
||||||
|
// 为slab内存池对象分配内存空间
|
||||||
|
ul *virt = NULL;
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
// 获取一个新的空页并添加到空页表,然后返回其虚拟地址
|
||||||
|
virt = (ul*)(PAGE_2M_ALIGN(memory_management_struct.end_of_struct+PAGE_2M_SIZE*i));
|
||||||
|
page = Virt_To_2M_Page(virt);
|
||||||
|
|
||||||
|
page_init(page, PAGE_PGT_MAPPED|PAGE_KERNEL|PAGE_KERNEL_INIT);
|
||||||
|
|
||||||
|
kmalloc_cache_group[i].cache_pool->page = page;
|
||||||
|
kmalloc_cache_group[i].cache_pool->vaddr = virt;
|
||||||
|
}
|
||||||
|
printk_color(ORANGE, BLACK, "3.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d\n", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 通用内存分配函数
|
* @brief 通用内存分配函数
|
||||||
*
|
*
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#define ESLAB_NOTNULL 101
|
#define ESLAB_NOTNULL 101
|
||||||
#define ENOT_IN_SLAB 102
|
#define ENOT_IN_SLAB 102
|
||||||
|
|
||||||
|
|
||||||
struct slab_obj
|
struct slab_obj
|
||||||
{
|
{
|
||||||
struct List *list;
|
struct List *list;
|
||||||
@ -26,15 +25,15 @@ struct slab_obj
|
|||||||
void *vaddr;
|
void *vaddr;
|
||||||
|
|
||||||
// 位图
|
// 位图
|
||||||
ul bmp_len; // 位图的长度(字节)
|
ul bmp_len; // 位图的长度(字节)
|
||||||
ul bmp_count; // 位图的有效位数
|
ul bmp_count; // 位图的有效位数
|
||||||
ul *bmp;
|
ul *bmp;
|
||||||
};
|
};
|
||||||
|
|
||||||
// slab内存池
|
// slab内存池
|
||||||
struct slab
|
struct slab
|
||||||
{
|
{
|
||||||
ul size;
|
ul size; // 单位:byte
|
||||||
ul count_total_using;
|
ul count_total_using;
|
||||||
ul count_total_free;
|
ul count_total_free;
|
||||||
// 内存池对象
|
// 内存池对象
|
||||||
@ -58,11 +57,11 @@ void *kmalloc(unsigned long size, unsigned long flags);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 通用内存释放函数
|
* @brief 通用内存释放函数
|
||||||
*
|
*
|
||||||
* @param address 要释放的内存地址
|
* @param address 要释放的内存地址
|
||||||
* @return unsigned long
|
* @return unsigned long
|
||||||
*/
|
*/
|
||||||
unsigned long kfree(void * address);
|
unsigned long kfree(void *address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 创建一个内存池
|
* @brief 创建一个内存池
|
||||||
@ -79,26 +78,53 @@ struct slab *slab_create(ul size, void *(*constructor)(void *vaddr, ul arg), voi
|
|||||||
* @brief 销毁内存池对象
|
* @brief 销毁内存池对象
|
||||||
* 只有当slab对象是空的时候才能销毁
|
* 只有当slab对象是空的时候才能销毁
|
||||||
* @param slab_pool 要销毁的内存池对象
|
* @param slab_pool 要销毁的内存池对象
|
||||||
* @return ul
|
* @return ul
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
ul slab_destroy(struct slab * slab_pool);
|
ul slab_destroy(struct slab *slab_pool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 分配SLAB内存池中的内存对象
|
* @brief 分配SLAB内存池中的内存对象
|
||||||
*
|
*
|
||||||
* @param slab_pool slab内存池
|
* @param slab_pool slab内存池
|
||||||
* @param arg 传递给内存对象构造函数的参数
|
* @param arg 传递给内存对象构造函数的参数
|
||||||
* @return void* 内存空间的虚拟地址
|
* @return void* 内存空间的虚拟地址
|
||||||
*/
|
*/
|
||||||
void* slab_malloc(struct slab *slab_pool, ul arg);
|
void *slab_malloc(struct slab *slab_pool, ul arg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 回收slab内存池中的对象
|
* @brief 回收slab内存池中的对象
|
||||||
*
|
*
|
||||||
* @param slab_pool 对应的内存池
|
* @param slab_pool 对应的内存池
|
||||||
* @param addr 内存对象的虚拟地址
|
* @param addr 内存对象的虚拟地址
|
||||||
* @param arg 传递给虚构函数的参数
|
* @param arg 传递给虚构函数的参数
|
||||||
* @return ul
|
* @return ul
|
||||||
*/
|
*/
|
||||||
ul slab_free(struct slab* slab_pool, void* addr, ul arg);
|
ul slab_free(struct slab *slab_pool, void *addr, ul arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化内存池组
|
||||||
|
* 在初始化通用内存管理单元期间,尚无内存空间分配函数,需要我们手动为SLAB内存池指定存储空间
|
||||||
|
* @return ul
|
||||||
|
*/
|
||||||
|
ul slab_init();
|
||||||
|
|
||||||
|
struct slab kmalloc_cache_group[16] =
|
||||||
|
{
|
||||||
|
{32, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{64, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{128, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{256, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{512, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{1024, 0, 0, NULL, NULL, NULL, NULL}, // 1KB
|
||||||
|
{2048, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{4096, 0, 0, NULL, NULL, NULL, NULL}, // 4KB
|
||||||
|
{8192, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{16384, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{32768, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{65536, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{131072, 0, 0, NULL, NULL, NULL, NULL}, // 128KB
|
||||||
|
{262144, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{524288, 0, 0, NULL, NULL, NULL, NULL},
|
||||||
|
{1048576, 0, 0, NULL, NULL, NULL, NULL}, // 1MB
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user