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"
|
||||
|
||||
unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址
|
||||
// char fxsave_region[512] __attribute__((aligned(16)));
|
||||
|
||||
struct memory_desc memory_management_struct = {{0}, 0};
|
||||
// struct Global_Memory_Descriptor memory_management_struct = {{0}, 0};
|
||||
@ -39,26 +38,52 @@ void show_welcome()
|
||||
}
|
||||
|
||||
// 测试内存管理单元
|
||||
/*
|
||||
|
||||
void test_mm()
|
||||
{
|
||||
kinfo("Testing memory management unit...");
|
||||
//printk("bmp[0]:%#018x\tbmp[1]%#018lx\n", *memory_management_struct.bmp, *(memory_management_struct.bmp + 1));
|
||||
kinfo("Try to allocate 64 memory pages.");
|
||||
struct Page *page = alloc_pages(ZONE_NORMAL, 64, PAGE_PGT_MAPPED | PAGE_ACTIVE | PAGE_KERNEL);
|
||||
struct Page *page = NULL;
|
||||
page = alloc_pages(ZONE_NORMAL, 63, 0);
|
||||
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);
|
||||
++page;
|
||||
if (((i + 1) % 2) == 0)
|
||||
printk("\n");
|
||||
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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
@ -84,17 +109,12 @@ void test_slab()
|
||||
}
|
||||
|
||||
// 测试自动扩容
|
||||
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);
|
||||
kmalloc(kmalloc_cache_group[15].size, 0);
|
||||
kmalloc(kmalloc_cache_group[15].size, 0);
|
||||
|
||||
void *ptrs[7];
|
||||
for (int i = 0; i < 7; ++i)
|
||||
ptrs[i] = kmalloc(kmalloc_cache_group[15].size, 0);
|
||||
|
||||
struct slab_obj *slab_obj_ptr = kmalloc_cache_group[15].cache_pool_entry;
|
||||
int count=0;
|
||||
int count = 0;
|
||||
do
|
||||
{
|
||||
kdebug("bmp(%d): addr=%#018lx\t value=%#018lx", count, slab_obj_ptr->bmp, *slab_obj_ptr->bmp);
|
||||
@ -103,6 +123,9 @@ void test_slab()
|
||||
++count;
|
||||
} 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!");
|
||||
}
|
||||
// 初始化系统各模块
|
||||
@ -133,9 +156,10 @@ void system_initialize()
|
||||
|
||||
cpu_init();
|
||||
|
||||
test_slab();
|
||||
// 再初始化进程模块。顺序不能调转
|
||||
// process_init();
|
||||
// test_slab();
|
||||
test_mm();
|
||||
// 再初始化进程模块。顺序不能调转
|
||||
// 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->addr_phys = 0UL;
|
||||
memory_management_struct.pages_struct->attr = 0;
|
||||
memory_management_struct.pages_struct->ref_counts = 0;
|
||||
set_page_attr(memory_management_struct.pages_struct, PAGE_PGT_MAPPED | PAGE_KERNEL_INIT | PAGE_KERNEL);
|
||||
memory_management_struct.pages_struct->ref_counts = 1;
|
||||
memory_management_struct.pages_struct->age = 0;
|
||||
// 将第0页的标志位给置上
|
||||
//*(memory_management_struct.bmp) |= 1UL;
|
||||
|
||||
// 计算zone结构体的总长度(按照64位对齐)
|
||||
memory_management_struct.zones_struct_len = (memory_management_struct.count_zones * sizeof(struct Zone) + sizeof(ul) - 1) & (~(sizeof(ul) - 1));
|
||||
|
||||
/*
|
||||
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_DMA_INDEX = 0;
|
||||
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);
|
||||
|
||||
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
|
||||
for (int i = 0; i < memory_management_struct.count_zones; ++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",
|
||||
// z->zone_addr_start, z->zone_addr_end, z->zone_length, z->pages_group, z->count_pages);
|
||||
|
||||
// 1GB以上的内存空间不做映射
|
||||
if (z->zone_addr_start == 0x100000000)
|
||||
ZONE_UNMAPED_INDEX = i;
|
||||
if (z->zone_addr_start >= 0x100000000 && (!ZONE_UNMAPPED_INDEX))
|
||||
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));
|
||||
|
||||
@ -177,16 +174,31 @@ void mm_init()
|
||||
// 初始化内存管理单元结构所占的物理页的结构体
|
||||
|
||||
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);
|
||||
for (ul j = 0; j <= mms_max_page; ++j)
|
||||
kdebug("mms_max_page=%ld", mms_max_page);
|
||||
|
||||
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();
|
||||
|
||||
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!");
|
||||
|
||||
// 初始化slab内存池
|
||||
@ -198,12 +210,21 @@ void mm_init()
|
||||
*
|
||||
* @param page 内存页结构体
|
||||
* @param flags 标志位
|
||||
* 对于新页面: 初始化struct page
|
||||
* 对于当前页面属性/flags中含有引用属性或共享属性时,则只增加struct page和struct zone的被引用计数。否则就只是添加页表属性,并置位bmp的相应位。
|
||||
* 本函数只负责初始化内存页,允许对同一页面进行多次初始化
|
||||
* 而维护计数器及置位bmp标志位的功能,应当在分配页面的时候手动完成
|
||||
* @return unsigned long
|
||||
*/
|
||||
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)
|
||||
{
|
||||
@ -231,37 +252,48 @@ unsigned long page_init(struct Page *page, ul flags)
|
||||
page->attr |= flags;
|
||||
}
|
||||
return 0;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从已初始化的页结构中搜索符合申请条件的、连续num个struct page
|
||||
*
|
||||
* @param zone_select 选择内存区域, 可选项:dma, mapped in pgt(normal), unmapped in pgt
|
||||
* @param num 需要申请的连续内存页的数量 num<=64
|
||||
* @param num 需要申请的连续内存页的数量 num<64
|
||||
* @param flags 将页面属性设置成flag
|
||||
* @return struct Page*
|
||||
*/
|
||||
struct Page *alloc_pages(unsigned int zone_select, int num, ul flags)
|
||||
{
|
||||
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)
|
||||
{
|
||||
case ZONE_DMA:
|
||||
// DMA区域
|
||||
zone_start = 0;
|
||||
zone_end = ZONE_DMA_INDEX;
|
||||
attr |= PAGE_PGT_MAPPED;
|
||||
break;
|
||||
case ZONE_NORMAL:
|
||||
zone_start = ZONE_DMA_INDEX;
|
||||
zone_end = ZONE_NORMAL_INDEX;
|
||||
attr |= PAGE_PGT_MAPPED;
|
||||
break;
|
||||
case ZONE_UNMAPPED_IN_PGT:
|
||||
zone_start = ZONE_NORMAL_INDEX;
|
||||
zone_end = ZONE_UNMAPED_INDEX;
|
||||
zone_end = ZONE_UNMAPPED_INDEX;
|
||||
attr = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
kwarn("In alloc_pages: param: zone_select incorrect.");
|
||||
kerror("In alloc_pages: param: zone_select incorrect.");
|
||||
// 返回空
|
||||
return NULL;
|
||||
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;
|
||||
|
||||
// 区域对应的起止页号以及区域拥有的页面数
|
||||
// 区域对应的起止页号
|
||||
ul page_start = (z->zone_addr_start >> 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;
|
||||
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中的每一个元素进行查找
|
||||
// 先将p定位到bmp的起始元素
|
||||
ul *p = memory_management_struct.bmp + (j >> 6);
|
||||
|
||||
ul shift = j % 64;
|
||||
|
||||
for (ul k = shift; k < 64 - shift; ++k)
|
||||
ul tmp_num = ((1UL << num) - 1);
|
||||
for (ul k = shift; k < 64; ++k)
|
||||
{
|
||||
// 寻找连续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)
|
||||
{
|
||||
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);
|
||||
@ -309,44 +347,94 @@ struct Page *alloc_pages(unsigned int zone_select, int num, ul flags)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 清除页面的引用计数, 计数为0时清空除页表已映射以外的所有属性
|
||||
*
|
||||
* @param p 物理页结构体
|
||||
* @return unsigned long
|
||||
*/
|
||||
unsigned long page_clean(struct Page *p)
|
||||
{
|
||||
if (!p->attr)
|
||||
p->attr = 0;
|
||||
else if ((p->attr & PAGE_REFERENCED) || (p->attr & PAGE_K_SHARE_TO_U))
|
||||
{
|
||||
// 被引用的页或内核共享给用户态的页
|
||||
--p->ref_counts;
|
||||
--p->zone->total_pages_link;
|
||||
--p->ref_counts;
|
||||
--p->zone->total_pages_link;
|
||||
|
||||
// 当引用为0时
|
||||
if (!p->ref_counts)
|
||||
{
|
||||
p->attr = 0;
|
||||
--p->zone->count_pages_using;
|
||||
++p->zone->count_pages_free;
|
||||
}
|
||||
// 若引用计数为空,则清空除PAGE_PGT_MAPPED以外的所有属性
|
||||
if (!p->ref_counts)
|
||||
{
|
||||
p->attr &= PAGE_PGT_MAPPED;
|
||||
}
|
||||
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
|
||||
{
|
||||
// 将bmp复位
|
||||
*(memory_management_struct.bmp + ((p->addr_phys >> PAGE_2M_SHIFT) >> 6)) &= ~(1UL << ((p->addr_phys >> PAGE_2M_SHIFT) % 64));
|
||||
|
||||
p->attr = 0;
|
||||
p->ref_counts = 0;
|
||||
--p->zone->count_pages_using;
|
||||
++p->zone->count_pages_free;
|
||||
--p->zone->total_pages_link;
|
||||
page->attr = flags;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 释放连续number个内存页
|
||||
*
|
||||
* @param page 第一个要被释放的页面的结构体
|
||||
* @param number 要释放的内存页数量 number<64
|
||||
*/
|
||||
|
||||
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)
|
||||
|
||||
// ===== 页面属性 =====
|
||||
// 页面在页表中已被映射
|
||||
// 页面在页表中已被映射 mapped=1 unmapped=0
|
||||
#define PAGE_PGT_MAPPED (1 << 0)
|
||||
// 内核初始化程序的页
|
||||
|
||||
// 内核初始化程序的页 init-code=1 normal-code/data=0
|
||||
#define PAGE_KERNEL_INIT (1 << 1)
|
||||
// 引用的页
|
||||
#define PAGE_REFERENCED (1 << 2)
|
||||
// 脏页
|
||||
#define PAGE_DIRTY (1 << 3)
|
||||
// 使用中的页
|
||||
#define PAGE_ACTIVE (1 << 4)
|
||||
// 过时的页
|
||||
#define PAGE_UP_TO_DATE (1 << 5)
|
||||
// 设备对应的页
|
||||
#define PAGE_DEVICE (1 << 6)
|
||||
// 内核层页
|
||||
#define PAGE_KERNEL (1 << 7)
|
||||
// 内核共享给用户态程序的页面
|
||||
#define PAGE_K_SHARE_TO_U (1 << 8)
|
||||
// slab内存分配器的页
|
||||
#define PAGE_SLAB (1 << 9)
|
||||
|
||||
// 1=设备寄存器映射的内存 0=物理内存
|
||||
#define PAGE_DEVICE (1 << 2)
|
||||
|
||||
// 内核层页 kernel=1 memory=0
|
||||
#define PAGE_KERNEL (1 << 3)
|
||||
|
||||
// 共享的页 shared=1 single-use=0
|
||||
#define PAGE_SHARED (1<<4)
|
||||
|
||||
|
||||
|
||||
// ===== 错误码定义 ====
|
||||
// 物理页结构体为空
|
||||
#define EPAGE_NULL 1
|
||||
|
||||
/**
|
||||
* @brief 刷新TLB的宏定义
|
||||
@ -169,7 +169,7 @@ extern char _end;
|
||||
|
||||
int ZONE_DMA_INDEX = 0;
|
||||
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;
|
||||
|
||||
@ -181,8 +181,8 @@ void mm_init();
|
||||
*
|
||||
* @param page 内存页结构体
|
||||
* @param flags 标志位
|
||||
* 对于新页面: 初始化struct page
|
||||
* 对于当前页面属性/flags中含有引用属性或共享属性时,则只增加struct page和struct zone的被引用计数。否则就只是添加页表属性,并置位bmp的相应位。
|
||||
* 本函数只负责初始化内存页,允许对同一页面进行多次初始化
|
||||
* 而维护计数器及置位bmp标志位的功能,应当在分配页面的时候手动完成
|
||||
* @return unsigned long
|
||||
*/
|
||||
unsigned long page_init(struct Page *page, ul flags);
|
||||
@ -205,16 +205,16 @@ unsigned long *get_CR3()
|
||||
* @brief 从已初始化的页结构中搜索符合申请条件的、连续num个struct page
|
||||
*
|
||||
* @param zone_select 选择内存区域, 可选项:dma, mapped in pgt(normal), unmapped in pgt
|
||||
* @param num 需要申请的内存页的数量 num<=64
|
||||
* @param num 需要申请的内存页的数量 num<64
|
||||
* @param flags 将页面属性设置成flag
|
||||
* @return struct Page*
|
||||
*/
|
||||
struct Page *alloc_pages(unsigned int zone_select, int num, ul flags);
|
||||
|
||||
/**
|
||||
* @brief 释放内存页
|
||||
* @brief 清除页面的引用计数, 计数为0时清空除页表已映射以外的所有属性
|
||||
*
|
||||
* @param page 内存页结构体
|
||||
* @param p 物理页结构体
|
||||
* @return unsigned long
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @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 内存页表结构体
|
||||
*
|
||||
|
@ -233,7 +233,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
||||
struct process_control_block *tsk = NULL;
|
||||
|
||||
// 获取一个物理页并在这个物理页内初始化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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user