mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
🔧 对物理页的管理功能进行了一些调整
This commit is contained in:
parent
7d8f89622d
commit
be1c838ff0
@ -14,7 +14,6 @@
|
|||||||
#include "syscall/syscall.h"
|
#include "syscall/syscall.h"
|
||||||
|
|
||||||
unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址
|
unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址
|
||||||
// char fxsave_region[512] __attribute__((aligned(16)));
|
|
||||||
|
|
||||||
struct memory_desc memory_management_struct = {{0}, 0};
|
struct memory_desc memory_management_struct = {{0}, 0};
|
||||||
// struct Global_Memory_Descriptor memory_management_struct = {{0}, 0};
|
// struct Global_Memory_Descriptor memory_management_struct = {{0}, 0};
|
||||||
@ -39,26 +38,52 @@ void show_welcome()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 测试内存管理单元
|
// 测试内存管理单元
|
||||||
/*
|
|
||||||
void test_mm()
|
void test_mm()
|
||||||
{
|
{
|
||||||
kinfo("Testing memory management unit...");
|
kinfo("Testing memory management unit...");
|
||||||
//printk("bmp[0]:%#018x\tbmp[1]%#018lx\n", *memory_management_struct.bmp, *(memory_management_struct.bmp + 1));
|
struct Page *page = NULL;
|
||||||
kinfo("Try to allocate 64 memory pages.");
|
page = alloc_pages(ZONE_NORMAL, 63, 0);
|
||||||
struct Page *page = alloc_pages(ZONE_NORMAL, 64, PAGE_PGT_MAPPED | PAGE_ACTIVE | PAGE_KERNEL);
|
page = alloc_pages(ZONE_NORMAL, 63, 0);
|
||||||
|
|
||||||
for (int i = 0; i <= 65; ++i)
|
printk_color(ORANGE, BLACK, "4.memory_management_struct.bmp:%#018lx\tmemory_management_struct.bmp+1:%#018lx\tmemory_management_struct.bmp+2:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d\n", *memory_management_struct.bmp, *(memory_management_struct.bmp + 1), *(memory_management_struct.bmp + 2), memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
|
||||||
|
|
||||||
|
for (int i = 80; i <= 85; ++i)
|
||||||
{
|
{
|
||||||
printk("page%d\tattr:%#018lx\tphys_addr:%#018lx\t", i, page->attr, page->addr_phys);
|
printk_color(INDIGO, BLACK, "page%03d attr:%#018lx address:%#018lx\t", i, (memory_management_struct.pages_struct + i)->attr, (memory_management_struct.pages_struct + i)->addr_phys);
|
||||||
++page;
|
i++;
|
||||||
if (((i + 1) % 2) == 0)
|
printk_color(INDIGO, BLACK, "page%03d attr:%#018lx address:%#018lx\n", i, (memory_management_struct.pages_struct + i)->attr, (memory_management_struct.pages_struct + i)->addr_phys);
|
||||||
printk("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 140; i <= 145; i++)
|
||||||
|
{
|
||||||
|
printk_color(INDIGO, BLACK, "page%03d attr:%#018lx address:%#018lx\t", i, (memory_management_struct.pages_struct + i)->attr, (memory_management_struct.pages_struct + i)->addr_phys);
|
||||||
|
i++;
|
||||||
|
printk_color(INDIGO, BLACK, "page%03d attr:%#018lx address:%#018lx\n", i, (memory_management_struct.pages_struct + i)->attr, (memory_management_struct.pages_struct + i)->addr_phys);
|
||||||
|
}
|
||||||
|
|
||||||
printk("bmp[0]:%#018x\tbmp[1]%#018lx\n", *(memory_management_struct.bmp), *(memory_management_struct.bmp + 1));
|
free_pages(page, 1);
|
||||||
|
|
||||||
|
printk_color(ORANGE, BLACK, "5.memory_management_struct.bmp:%#018lx\tmemory_management_struct.bmp+1:%#018lx\tmemory_management_struct.bmp+2:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d\n", *memory_management_struct.bmp, *(memory_management_struct.bmp + 1), *(memory_management_struct.bmp + 2), memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
|
||||||
|
|
||||||
|
for (int i = 75; i <= 85; i++)
|
||||||
|
{
|
||||||
|
printk_color(INDIGO, BLACK, "page%03d attr:%#018lx address:%#018lx\t", i, (memory_management_struct.pages_struct + i)->attr, (memory_management_struct.pages_struct + i)->addr_phys);
|
||||||
|
i++;
|
||||||
|
printk_color(INDIGO, BLACK, "page%03d attr:%#018lx address:%#018lx\n", i, (memory_management_struct.pages_struct + i)->attr, (memory_management_struct.pages_struct + i)->addr_phys);
|
||||||
|
}
|
||||||
|
|
||||||
|
page = alloc_pages(ZONE_UNMAPPED_IN_PGT, 63, 0);
|
||||||
|
|
||||||
|
printk_color(ORANGE, BLACK, "6.memory_management_struct.bmp:%#018lx\tmemory_management_struct.bmp+1:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d\n", *(memory_management_struct.bmp + (page->addr_phys >> PAGE_2M_SHIFT >> 6)), *(memory_management_struct.bmp + 1 + (page->addr_phys >> PAGE_2M_SHIFT >> 6)), (memory_management_struct.zones_struct + ZONE_UNMAPPED_INDEX)->count_pages_using, (memory_management_struct.zones_struct + ZONE_UNMAPPED_INDEX)->count_pages_free);
|
||||||
|
|
||||||
|
free_pages(page, 1);
|
||||||
|
|
||||||
|
printk_color(ORANGE, BLACK, "7.memory_management_struct.bmp:%#018lx\tmemory_management_struct.bmp+1:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d\n", *(memory_management_struct.bmp + (page->addr_phys >> PAGE_2M_SHIFT >> 6)), *(memory_management_struct.bmp + 1 + (page->addr_phys >> PAGE_2M_SHIFT >> 6)), (memory_management_struct.zones_struct + ZONE_UNMAPPED_INDEX)->count_pages_using, (memory_management_struct.zones_struct + ZONE_UNMAPPED_INDEX)->count_pages_free);
|
||||||
|
|
||||||
|
test_slab();
|
||||||
|
kinfo("Memory management module test completed!");
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
void test_slab()
|
void test_slab()
|
||||||
{
|
{
|
||||||
@ -84,25 +109,23 @@ void test_slab()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 测试自动扩容
|
// 测试自动扩容
|
||||||
kmalloc(kmalloc_cache_group[15].size, 0);
|
void *ptrs[7];
|
||||||
kmalloc(kmalloc_cache_group[15].size, 0);
|
for (int i = 0; i < 7; ++i)
|
||||||
kmalloc(kmalloc_cache_group[15].size, 0);
|
ptrs[i] = kmalloc(kmalloc_cache_group[15].size, 0);
|
||||||
kmalloc(kmalloc_cache_group[15].size, 0);
|
|
||||||
kmalloc(kmalloc_cache_group[15].size, 0);
|
|
||||||
kmalloc(kmalloc_cache_group[15].size, 0);
|
|
||||||
kmalloc(kmalloc_cache_group[15].size, 0);
|
|
||||||
|
|
||||||
|
|
||||||
struct slab_obj *slab_obj_ptr = kmalloc_cache_group[15].cache_pool_entry;
|
struct slab_obj *slab_obj_ptr = kmalloc_cache_group[15].cache_pool_entry;
|
||||||
int count=0;
|
int count = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
kdebug("bmp(%d): addr=%#018lx\t value=%#018lx", count, slab_obj_ptr->bmp, *slab_obj_ptr->bmp);
|
kdebug("bmp(%d): addr=%#018lx\t value=%#018lx", count, slab_obj_ptr->bmp, *slab_obj_ptr->bmp);
|
||||||
|
|
||||||
slab_obj_ptr = container_of(list_next(&slab_obj_ptr->list), struct slab_obj, list);
|
slab_obj_ptr = container_of(list_next(&slab_obj_ptr->list), struct slab_obj, list);
|
||||||
++count;
|
++count;
|
||||||
} while (slab_obj_ptr != kmalloc_cache_group[15].cache_pool_entry);
|
} while (slab_obj_ptr != kmalloc_cache_group[15].cache_pool_entry);
|
||||||
|
|
||||||
|
for (int i = 0; i < 7; ++i)
|
||||||
|
kfree(ptrs[i]);
|
||||||
|
|
||||||
kinfo("SLAB test completed!");
|
kinfo("SLAB test completed!");
|
||||||
}
|
}
|
||||||
// 初始化系统各模块
|
// 初始化系统各模块
|
||||||
@ -133,9 +156,10 @@ void system_initialize()
|
|||||||
|
|
||||||
cpu_init();
|
cpu_init();
|
||||||
|
|
||||||
test_slab();
|
// test_slab();
|
||||||
// 再初始化进程模块。顺序不能调转
|
test_mm();
|
||||||
// process_init();
|
// 再初始化进程模块。顺序不能调转
|
||||||
|
// process_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
//操作系统内核从这里开始执行
|
//操作系统内核从这里开始执行
|
||||||
|
196
kernel/mm/mm.c
196
kernel/mm/mm.c
@ -141,33 +141,30 @@ void mm_init()
|
|||||||
|
|
||||||
memory_management_struct.pages_struct->zone = memory_management_struct.zones_struct;
|
memory_management_struct.pages_struct->zone = memory_management_struct.zones_struct;
|
||||||
memory_management_struct.pages_struct->addr_phys = 0UL;
|
memory_management_struct.pages_struct->addr_phys = 0UL;
|
||||||
memory_management_struct.pages_struct->attr = 0;
|
set_page_attr(memory_management_struct.pages_struct, PAGE_PGT_MAPPED | PAGE_KERNEL_INIT | PAGE_KERNEL);
|
||||||
memory_management_struct.pages_struct->ref_counts = 0;
|
memory_management_struct.pages_struct->ref_counts = 1;
|
||||||
memory_management_struct.pages_struct->age = 0;
|
memory_management_struct.pages_struct->age = 0;
|
||||||
|
// 将第0页的标志位给置上
|
||||||
|
//*(memory_management_struct.bmp) |= 1UL;
|
||||||
|
|
||||||
// 计算zone结构体的总长度(按照64位对齐)
|
// 计算zone结构体的总长度(按照64位对齐)
|
||||||
memory_management_struct.zones_struct_len = (memory_management_struct.count_zones * sizeof(struct Zone) + sizeof(ul) - 1) & (~(sizeof(ul) - 1));
|
memory_management_struct.zones_struct_len = (memory_management_struct.count_zones * sizeof(struct Zone) + sizeof(ul) - 1) & (~(sizeof(ul) - 1));
|
||||||
|
|
||||||
/*
|
ZONE_DMA_INDEX = 0;
|
||||||
printk_color(ORANGE, BLACK, "bmp:%#18lx, bmp_len:%#18lx, bits_size:%#18lx\n", memory_management_struct.bmp, memory_management_struct.bmp_len, memory_management_struct.bits_size);
|
ZONE_NORMAL_INDEX = 0;
|
||||||
|
ZONE_UNMAPPED_INDEX = 0;
|
||||||
|
|
||||||
printk_color(ORANGE, BLACK, "pages_struct:%#18lx, count_pages:%#18lx, pages_struct_len:%#18lx\n", memory_management_struct.pages_struct, memory_management_struct.count_pages, memory_management_struct.pages_struct_len);
|
for (int i = 0; i < memory_management_struct.count_zones; ++i)
|
||||||
|
|
||||||
printk_color(ORANGE, BLACK, "zones_struct:%#18lx, count_zones:%#18lx, zones_struct_len:%#18lx\n", memory_management_struct.zones_struct, memory_management_struct.count_zones, memory_management_struct.zones_struct_len);
|
|
||||||
*/
|
|
||||||
ZONE_DMA_INDEX = 0; // need rewrite in the future
|
|
||||||
ZONE_NORMAL_INDEX = 0; // need rewrite in the future
|
|
||||||
|
|
||||||
for (int i = 0; i < memory_management_struct.count_zones; ++i) // need rewrite in the future
|
|
||||||
{
|
{
|
||||||
struct Zone *z = memory_management_struct.zones_struct + i;
|
struct Zone *z = memory_management_struct.zones_struct + i;
|
||||||
// printk_color(ORANGE, BLACK, "zone_addr_start:%#18lx, zone_addr_end:%#18lx, zone_length:%#18lx, pages_group:%#18lx, count_pages:%#18lx\n",
|
// printk_color(ORANGE, BLACK, "zone_addr_start:%#18lx, zone_addr_end:%#18lx, zone_length:%#18lx, pages_group:%#18lx, count_pages:%#18lx\n",
|
||||||
// z->zone_addr_start, z->zone_addr_end, z->zone_length, z->pages_group, z->count_pages);
|
// z->zone_addr_start, z->zone_addr_end, z->zone_length, z->pages_group, z->count_pages);
|
||||||
|
|
||||||
// 1GB以上的内存空间不做映射
|
// 1GB以上的内存空间不做映射
|
||||||
if (z->zone_addr_start == 0x100000000)
|
if (z->zone_addr_start >= 0x100000000 && (!ZONE_UNMAPPED_INDEX))
|
||||||
ZONE_UNMAPED_INDEX = i;
|
ZONE_UNMAPPED_INDEX = i;
|
||||||
}
|
}
|
||||||
|
kdebug("ZONE_DMA_INDEX=%d\tZONE_NORMAL_INDEX=%d\tZONE_UNMAPPED_INDEX=%d", ZONE_DMA_INDEX, ZONE_NORMAL_INDEX, ZONE_UNMAPPED_INDEX);
|
||||||
// 设置内存页管理结构的地址,预留了一段空间,防止内存越界。
|
// 设置内存页管理结构的地址,预留了一段空间,防止内存越界。
|
||||||
memory_management_struct.end_of_struct = (ul)((ul)memory_management_struct.zones_struct + memory_management_struct.zones_struct_len + sizeof(long) * 32) & (~(sizeof(long) - 1));
|
memory_management_struct.end_of_struct = (ul)((ul)memory_management_struct.zones_struct + memory_management_struct.zones_struct_len + sizeof(long) * 32) & (~(sizeof(long) - 1));
|
||||||
|
|
||||||
@ -177,16 +174,31 @@ void mm_init()
|
|||||||
// 初始化内存管理单元结构所占的物理页的结构体
|
// 初始化内存管理单元结构所占的物理页的结构体
|
||||||
|
|
||||||
ul mms_max_page = (virt_2_phys(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT); // 内存管理单元所占据的序号最大的物理页
|
ul mms_max_page = (virt_2_phys(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT); // 内存管理单元所占据的序号最大的物理页
|
||||||
printk("mms_max_page=%ld\n", mms_max_page);
|
kdebug("mms_max_page=%ld", mms_max_page);
|
||||||
for (ul j = 0; j <= mms_max_page; ++j)
|
|
||||||
|
struct Page *tmp_page = NULL;
|
||||||
|
ul page_num;
|
||||||
|
// 第0个page已经在上方配置
|
||||||
|
for (ul j = 1; j <= mms_max_page; ++j)
|
||||||
{
|
{
|
||||||
page_init(memory_management_struct.pages_struct + j, PAGE_PGT_MAPPED | PAGE_KERNEL | PAGE_KERNEL_INIT | PAGE_ACTIVE);
|
tmp_page = memory_management_struct.pages_struct + j;
|
||||||
|
page_init(tmp_page, PAGE_PGT_MAPPED | PAGE_KERNEL | PAGE_KERNEL_INIT);
|
||||||
|
page_num = tmp_page->addr_phys >> PAGE_2M_SHIFT;
|
||||||
|
*(memory_management_struct.bmp + (page_num >> 6)) |= (1UL << (page_num % 64));
|
||||||
|
++tmp_page->zone->count_pages_using;
|
||||||
|
--tmp_page->zone->count_pages_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
global_CR3 = get_CR3();
|
global_CR3 = get_CR3();
|
||||||
|
|
||||||
flush_tlb();
|
flush_tlb();
|
||||||
|
|
||||||
|
kdebug("global_CR3\t:%#018lx", global_CR3);
|
||||||
|
kdebug("*global_CR3\t:%#018lx", *phys_2_virt(global_CR3) & (~0xff));
|
||||||
|
kdebug("**global_CR3\t:%#018lx", *phys_2_virt(*phys_2_virt(global_CR3) & (~0xff)) & (~0xff));
|
||||||
|
|
||||||
|
kdebug("1.memory_management_struct.bmp:%#018lx\tzone->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
|
||||||
|
|
||||||
kinfo("Memory management unit initialize complete!");
|
kinfo("Memory management unit initialize complete!");
|
||||||
|
|
||||||
// 初始化slab内存池
|
// 初始化slab内存池
|
||||||
@ -198,12 +210,21 @@ void mm_init()
|
|||||||
*
|
*
|
||||||
* @param page 内存页结构体
|
* @param page 内存页结构体
|
||||||
* @param flags 标志位
|
* @param flags 标志位
|
||||||
* 对于新页面: 初始化struct page
|
* 本函数只负责初始化内存页,允许对同一页面进行多次初始化
|
||||||
* 对于当前页面属性/flags中含有引用属性或共享属性时,则只增加struct page和struct zone的被引用计数。否则就只是添加页表属性,并置位bmp的相应位。
|
* 而维护计数器及置位bmp标志位的功能,应当在分配页面的时候手动完成
|
||||||
* @return unsigned long
|
* @return unsigned long
|
||||||
*/
|
*/
|
||||||
unsigned long page_init(struct Page *page, ul flags)
|
unsigned long page_init(struct Page *page, ul flags)
|
||||||
{
|
{
|
||||||
|
page->attr |= flags;
|
||||||
|
// 若页面的引用计数为0或是共享页,增加引用计数
|
||||||
|
if ((!page->ref_counts) || (page->attr & PAGE_SHARED))
|
||||||
|
{
|
||||||
|
++page->ref_counts;
|
||||||
|
++page->zone->total_pages_link;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
/*
|
||||||
// 全新的页面
|
// 全新的页面
|
||||||
if (!page->attr)
|
if (!page->attr)
|
||||||
{
|
{
|
||||||
@ -231,37 +252,48 @@ unsigned long page_init(struct Page *page, ul flags)
|
|||||||
page->attr |= flags;
|
page->attr |= flags;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 从已初始化的页结构中搜索符合申请条件的、连续num个struct page
|
* @brief 从已初始化的页结构中搜索符合申请条件的、连续num个struct page
|
||||||
*
|
*
|
||||||
* @param zone_select 选择内存区域, 可选项:dma, mapped in pgt(normal), unmapped in pgt
|
* @param zone_select 选择内存区域, 可选项:dma, mapped in pgt(normal), unmapped in pgt
|
||||||
* @param num 需要申请的连续内存页的数量 num<=64
|
* @param num 需要申请的连续内存页的数量 num<64
|
||||||
* @param flags 将页面属性设置成flag
|
* @param flags 将页面属性设置成flag
|
||||||
* @return struct Page*
|
* @return struct Page*
|
||||||
*/
|
*/
|
||||||
struct Page *alloc_pages(unsigned int zone_select, int num, ul flags)
|
struct Page *alloc_pages(unsigned int zone_select, int num, ul flags)
|
||||||
{
|
{
|
||||||
ul zone_start = 0, zone_end = 0;
|
ul zone_start = 0, zone_end = 0;
|
||||||
|
if (num >= 64 && num <= 0)
|
||||||
|
{
|
||||||
|
kerror("alloc_pages(): num is invalid.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul attr = flags;
|
||||||
switch (zone_select)
|
switch (zone_select)
|
||||||
{
|
{
|
||||||
case ZONE_DMA:
|
case ZONE_DMA:
|
||||||
// DMA区域
|
// DMA区域
|
||||||
zone_start = 0;
|
zone_start = 0;
|
||||||
zone_end = ZONE_DMA_INDEX;
|
zone_end = ZONE_DMA_INDEX;
|
||||||
|
attr |= PAGE_PGT_MAPPED;
|
||||||
break;
|
break;
|
||||||
case ZONE_NORMAL:
|
case ZONE_NORMAL:
|
||||||
zone_start = ZONE_DMA_INDEX;
|
zone_start = ZONE_DMA_INDEX;
|
||||||
zone_end = ZONE_NORMAL_INDEX;
|
zone_end = ZONE_NORMAL_INDEX;
|
||||||
|
attr |= PAGE_PGT_MAPPED;
|
||||||
break;
|
break;
|
||||||
case ZONE_UNMAPPED_IN_PGT:
|
case ZONE_UNMAPPED_IN_PGT:
|
||||||
zone_start = ZONE_NORMAL_INDEX;
|
zone_start = ZONE_NORMAL_INDEX;
|
||||||
zone_end = ZONE_UNMAPED_INDEX;
|
zone_end = ZONE_UNMAPPED_INDEX;
|
||||||
|
attr = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
kwarn("In alloc_pages: param: zone_select incorrect.");
|
kerror("In alloc_pages: param: zone_select incorrect.");
|
||||||
// 返回空
|
// 返回空
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
@ -274,30 +306,36 @@ struct Page *alloc_pages(unsigned int zone_select, int num, ul flags)
|
|||||||
|
|
||||||
struct Zone *z = memory_management_struct.zones_struct + i;
|
struct Zone *z = memory_management_struct.zones_struct + i;
|
||||||
|
|
||||||
// 区域对应的起止页号以及区域拥有的页面数
|
// 区域对应的起止页号
|
||||||
ul page_start = (z->zone_addr_start >> PAGE_2M_SHIFT);
|
ul page_start = (z->zone_addr_start >> PAGE_2M_SHIFT);
|
||||||
ul page_end = (z->zone_addr_end >> PAGE_2M_SHIFT);
|
ul page_end = (z->zone_addr_end >> PAGE_2M_SHIFT);
|
||||||
ul page_num = (z->zone_length >> PAGE_2M_SHIFT);
|
|
||||||
|
|
||||||
ul tmp = 64 - page_start % 64;
|
ul tmp = 64 - page_start % 64;
|
||||||
for (ul j = page_start; j <= page_end; j += ((j % 64) ? tmp : 64))
|
for (ul j = page_start; j < page_end; j += ((j % 64) ? tmp : 64))
|
||||||
{
|
{
|
||||||
// 按照bmp中的每一个元素进行查找
|
// 按照bmp中的每一个元素进行查找
|
||||||
// 先将p定位到bmp的起始元素
|
// 先将p定位到bmp的起始元素
|
||||||
ul *p = memory_management_struct.bmp + (j >> 6);
|
ul *p = memory_management_struct.bmp + (j >> 6);
|
||||||
|
|
||||||
ul shift = j % 64;
|
ul shift = j % 64;
|
||||||
|
ul tmp_num = ((1UL << num) - 1);
|
||||||
for (ul k = shift; k < 64 - shift; ++k)
|
for (ul k = shift; k < 64; ++k)
|
||||||
{
|
{
|
||||||
// 寻找连续num个空页
|
// 寻找连续num个空页
|
||||||
if (!(((*p >> k) | (*(p + 1) << (64 - k))) & (num == 64 ? 0xffffffffffffffffUL : ((1UL << num) - 1))))
|
if (!((k ? ((*p >> k) | (*(p + 1) << (64 - k))) : *p) & tmp_num))
|
||||||
|
|
||||||
{
|
{
|
||||||
ul start_page_num = j + k - shift; // 计算得到要开始获取的内存页的页号(书上的公式有问题,这个是改过之后的版本)
|
ul start_page_num = j + k - shift; // 计算得到要开始获取的内存页的页号
|
||||||
for (ul l = 0; l < num; ++l)
|
for (ul l = 0; l < num; ++l)
|
||||||
{
|
{
|
||||||
struct Page *x = memory_management_struct.pages_struct + start_page_num + l;
|
struct Page *x = memory_management_struct.pages_struct + start_page_num + l;
|
||||||
page_init(x, flags);
|
|
||||||
|
// 分配页面,手动配置属性及计数器
|
||||||
|
// 置位bmp
|
||||||
|
*(memory_management_struct.bmp + ((x->addr_phys >> PAGE_2M_SHIFT) >> 6)) |= (1UL << (x->addr_phys >> PAGE_2M_SHIFT) % 64);
|
||||||
|
++z->count_pages_using;
|
||||||
|
--z->count_pages_free;
|
||||||
|
x->attr = attr;
|
||||||
}
|
}
|
||||||
// 成功分配了页面,返回第一个页面的指针
|
// 成功分配了页面,返回第一个页面的指针
|
||||||
// printk("start page num=%d\n",start_page_num);
|
// printk("start page num=%d\n",start_page_num);
|
||||||
@ -309,44 +347,94 @@ struct Page *alloc_pages(unsigned int zone_select, int num, ul flags)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 清除页面的引用计数, 计数为0时清空除页表已映射以外的所有属性
|
||||||
|
*
|
||||||
|
* @param p 物理页结构体
|
||||||
|
* @return unsigned long
|
||||||
|
*/
|
||||||
unsigned long page_clean(struct Page *p)
|
unsigned long page_clean(struct Page *p)
|
||||||
{
|
{
|
||||||
if (!p->attr)
|
--p->ref_counts;
|
||||||
p->attr = 0;
|
--p->zone->total_pages_link;
|
||||||
else if ((p->attr & PAGE_REFERENCED) || (p->attr & PAGE_K_SHARE_TO_U))
|
|
||||||
{
|
|
||||||
// 被引用的页或内核共享给用户态的页
|
|
||||||
--p->ref_counts;
|
|
||||||
--p->zone->total_pages_link;
|
|
||||||
|
|
||||||
// 当引用为0时
|
// 若引用计数为空,则清空除PAGE_PGT_MAPPED以外的所有属性
|
||||||
if (!p->ref_counts)
|
if (!p->ref_counts)
|
||||||
{
|
{
|
||||||
p->attr = 0;
|
p->attr &= PAGE_PGT_MAPPED;
|
||||||
--p->zone->count_pages_using;
|
}
|
||||||
++p->zone->count_pages_free;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the page's attr
|
||||||
|
*
|
||||||
|
* @param page 内存页结构体
|
||||||
|
* @return ul 属性
|
||||||
|
*/
|
||||||
|
ul get_page_attr(struct Page *page)
|
||||||
|
{
|
||||||
|
if (page == NULL)
|
||||||
|
{
|
||||||
|
kBUG("get_page_attr(): page == NULL");
|
||||||
|
return EPAGE_NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return page->attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the page's attr
|
||||||
|
*
|
||||||
|
* @param page 内存页结构体
|
||||||
|
* @param flags 属性
|
||||||
|
* @return ul 错误码
|
||||||
|
*/
|
||||||
|
ul set_page_attr(struct Page *page, ul flags)
|
||||||
|
{
|
||||||
|
if (page == NULL)
|
||||||
|
{
|
||||||
|
kBUG("get_page_attr(): page == NULL");
|
||||||
|
return EPAGE_NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 将bmp复位
|
page->attr = flags;
|
||||||
*(memory_management_struct.bmp + ((p->addr_phys >> PAGE_2M_SHIFT) >> 6)) &= ~(1UL << ((p->addr_phys >> PAGE_2M_SHIFT) % 64));
|
return 0;
|
||||||
|
|
||||||
p->attr = 0;
|
|
||||||
p->ref_counts = 0;
|
|
||||||
--p->zone->count_pages_using;
|
|
||||||
++p->zone->count_pages_free;
|
|
||||||
--p->zone->total_pages_link;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 释放连续number个内存页
|
* @brief 释放连续number个内存页
|
||||||
*
|
*
|
||||||
* @param page 第一个要被释放的页面的结构体
|
* @param page 第一个要被释放的页面的结构体
|
||||||
* @param number 要释放的内存页数量 number<64
|
* @param number 要释放的内存页数量 number<64
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void free_pages(struct Page *page, int number)
|
void free_pages(struct Page *page, int number)
|
||||||
{
|
{
|
||||||
// @todo: 释放连续number个内存页
|
if (page == NULL)
|
||||||
|
{
|
||||||
|
kerror("free_pages() page is invalid.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (number >= 64 || number <= 0)
|
||||||
|
{
|
||||||
|
kerror("free_pages(): number %d is invalid.", number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul page_num;
|
||||||
|
for (int i = 0; i < number; ++i, ++page)
|
||||||
|
{
|
||||||
|
page_num = page->addr_phys >> PAGE_2M_SHIFT;
|
||||||
|
// 复位bmp
|
||||||
|
*(memory_management_struct.bmp + (page_num >> 6)) &= ~(1UL << (page_num % 64));
|
||||||
|
// 更新计数器
|
||||||
|
--page->zone->count_pages_using;
|
||||||
|
++page->zone->count_pages_free;
|
||||||
|
page->attr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
@ -43,26 +43,26 @@
|
|||||||
#define ZONE_UNMAPPED_IN_PGT (1 << 2)
|
#define ZONE_UNMAPPED_IN_PGT (1 << 2)
|
||||||
|
|
||||||
// ===== 页面属性 =====
|
// ===== 页面属性 =====
|
||||||
// 页面在页表中已被映射
|
// 页面在页表中已被映射 mapped=1 unmapped=0
|
||||||
#define PAGE_PGT_MAPPED (1 << 0)
|
#define PAGE_PGT_MAPPED (1 << 0)
|
||||||
// 内核初始化程序的页
|
|
||||||
|
// 内核初始化程序的页 init-code=1 normal-code/data=0
|
||||||
#define PAGE_KERNEL_INIT (1 << 1)
|
#define PAGE_KERNEL_INIT (1 << 1)
|
||||||
// 引用的页
|
|
||||||
#define PAGE_REFERENCED (1 << 2)
|
// 1=设备寄存器映射的内存 0=物理内存
|
||||||
// 脏页
|
#define PAGE_DEVICE (1 << 2)
|
||||||
#define PAGE_DIRTY (1 << 3)
|
|
||||||
// 使用中的页
|
// 内核层页 kernel=1 memory=0
|
||||||
#define PAGE_ACTIVE (1 << 4)
|
#define PAGE_KERNEL (1 << 3)
|
||||||
// 过时的页
|
|
||||||
#define PAGE_UP_TO_DATE (1 << 5)
|
// 共享的页 shared=1 single-use=0
|
||||||
// 设备对应的页
|
#define PAGE_SHARED (1<<4)
|
||||||
#define PAGE_DEVICE (1 << 6)
|
|
||||||
// 内核层页
|
|
||||||
#define PAGE_KERNEL (1 << 7)
|
|
||||||
// 内核共享给用户态程序的页面
|
// ===== 错误码定义 ====
|
||||||
#define PAGE_K_SHARE_TO_U (1 << 8)
|
// 物理页结构体为空
|
||||||
// slab内存分配器的页
|
#define EPAGE_NULL 1
|
||||||
#define PAGE_SLAB (1 << 9)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 刷新TLB的宏定义
|
* @brief 刷新TLB的宏定义
|
||||||
@ -169,7 +169,7 @@ extern char _end;
|
|||||||
|
|
||||||
int ZONE_DMA_INDEX = 0;
|
int ZONE_DMA_INDEX = 0;
|
||||||
int ZONE_NORMAL_INDEX = 0; // low 1GB RAM ,was mapped in pagetable
|
int ZONE_NORMAL_INDEX = 0; // low 1GB RAM ,was mapped in pagetable
|
||||||
int ZONE_UNMAPED_INDEX = 0; // above 1GB RAM,unmapped in pagetable
|
int ZONE_UNMAPPED_INDEX = 0; // above 1GB RAM,unmapped in pagetable
|
||||||
|
|
||||||
ul *global_CR3 = NULL;
|
ul *global_CR3 = NULL;
|
||||||
|
|
||||||
@ -181,8 +181,8 @@ void mm_init();
|
|||||||
*
|
*
|
||||||
* @param page 内存页结构体
|
* @param page 内存页结构体
|
||||||
* @param flags 标志位
|
* @param flags 标志位
|
||||||
* 对于新页面: 初始化struct page
|
* 本函数只负责初始化内存页,允许对同一页面进行多次初始化
|
||||||
* 对于当前页面属性/flags中含有引用属性或共享属性时,则只增加struct page和struct zone的被引用计数。否则就只是添加页表属性,并置位bmp的相应位。
|
* 而维护计数器及置位bmp标志位的功能,应当在分配页面的时候手动完成
|
||||||
* @return unsigned long
|
* @return unsigned long
|
||||||
*/
|
*/
|
||||||
unsigned long page_init(struct Page *page, ul flags);
|
unsigned long page_init(struct Page *page, ul flags);
|
||||||
@ -205,17 +205,17 @@ unsigned long *get_CR3()
|
|||||||
* @brief 从已初始化的页结构中搜索符合申请条件的、连续num个struct page
|
* @brief 从已初始化的页结构中搜索符合申请条件的、连续num个struct page
|
||||||
*
|
*
|
||||||
* @param zone_select 选择内存区域, 可选项:dma, mapped in pgt(normal), unmapped in pgt
|
* @param zone_select 选择内存区域, 可选项:dma, mapped in pgt(normal), unmapped in pgt
|
||||||
* @param num 需要申请的内存页的数量 num<=64
|
* @param num 需要申请的内存页的数量 num<64
|
||||||
* @param flags 将页面属性设置成flag
|
* @param flags 将页面属性设置成flag
|
||||||
* @return struct Page*
|
* @return struct Page*
|
||||||
*/
|
*/
|
||||||
struct Page *alloc_pages(unsigned int zone_select, int num, ul flags);
|
struct Page *alloc_pages(unsigned int zone_select, int num, ul flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 释放内存页
|
* @brief 清除页面的引用计数, 计数为0时清空除页表已映射以外的所有属性
|
||||||
*
|
*
|
||||||
* @param page 内存页结构体
|
* @param p 物理页结构体
|
||||||
* @return unsigned long
|
* @return unsigned long
|
||||||
*/
|
*/
|
||||||
unsigned long page_clean(struct Page *page);
|
unsigned long page_clean(struct Page *page);
|
||||||
|
|
||||||
@ -227,6 +227,23 @@ unsigned long page_clean(struct Page *page);
|
|||||||
*/
|
*/
|
||||||
void free_pages(struct Page *page, int number);
|
void free_pages(struct Page *page, int number);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the page's attr
|
||||||
|
*
|
||||||
|
* @param page 内存页结构体
|
||||||
|
* @return ul 属性
|
||||||
|
*/
|
||||||
|
ul get_page_attr(struct Page* page);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the page's attr
|
||||||
|
*
|
||||||
|
* @param page 内存页结构体
|
||||||
|
* @param flags 属性
|
||||||
|
* @return ul 错误码
|
||||||
|
*/
|
||||||
|
ul set_page_attr(struct Page* page, ul flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 内存页表结构体
|
* @brief 内存页表结构体
|
||||||
*
|
*
|
||||||
|
@ -233,7 +233,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
struct process_control_block *tsk = NULL;
|
struct process_control_block *tsk = NULL;
|
||||||
|
|
||||||
// 获取一个物理页并在这个物理页内初始化pcb
|
// 获取一个物理页并在这个物理页内初始化pcb
|
||||||
struct Page *pp = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED | PAGE_ACTIVE | PAGE_KERNEL);
|
struct Page *pp = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED | PAGE_KERNEL);
|
||||||
|
|
||||||
tsk = (struct process_control_block *)phys_2_virt(pp->addr_phys);
|
tsk = (struct process_control_block *)phys_2_virt(pp->addr_phys);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user