[73%]正在写一个模拟 Linux 内存管理的系统
本帖最后由 Buddy_Zhang1 于 2016-03-24 20:38 编辑我想写一个关于内存管理的小系统,该系统的内存管理机制完全模拟 Linux 的内存管理机制.
我的想法是在用户空间申请两个大小为 256M 的数组,然后把这两个数组模拟成两块内存块,
我就基于这两块虚拟内存块,在其上面构建一个和 Linux 内存管理机制一样的系统.
这个系统是运行在用户空间的,也就是一个用户程序而已!
这样是否可行?大家提提意见.
写这个系统的目的就是学习 Linux 内存管理从创建到运行管理的整个过程,如果可行,并且写出来,我会开源出来.
谢谢!{:yxh45:} 本帖最后由 Buddy_Zhang1 于 2016-03-04 11:47 编辑
经过考虑,我做以下模拟:
1. 硬件模拟支持 MMU 的 ARMv7
2. 使用纯 C 编写.
3. 使用 main() 函数的构造函数作为 Uboot,使用 main() 作为 kernel 空间.
4. 单核 UMA
5. 两块模拟内存块之间存在一定大小 hole.
{:yxh45:}
Feature Update:
该内存管理系统支持内存分配器如下:
1. Bootmem Allocator
2. Per-CPU Allocator
3. Buddy Allocator
4. PCP Allocator
5. SLUB Allocator
6. VMALLOC Allocator
7. KMAP Allocator
{:yxh45:} 赞!+U!
PS,为啥需要模拟硬件,哪些逻辑跟arch相关? 本帖最后由 Buddy_Zhang1 于 2016-03-04 21:08 编辑
回复 4# nswcfd
主要是模拟硬件 MMU 和页表转换过程,其中 setup_arch() 函数中比较多
和 arch 关系最大的当属 Bootmem Allocator 了
本帖最后由 Buddy_Zhang1 于 2016-03-06 12:04 编辑
Feature Update:
核心算法支持:
1. 红黑树
2. 优先查找树
3. 基数树.
4. HASH
5. 伙伴系统算法
{:yxh45:} 技术问题:
我使用的是 64 位的系统,但我写的系统是一个 32 位的系统,所以在 64 位用户空间模拟 32 位程序是一个难题.
大家有没相应的经验,交流一下.
{:yxh45:} Feature Update:
伙伴系统算法更新:
从伙伴系统中获得一个物理页:
struct TestCase_get_free_page(void)
{
struct pglist_data *pgdat;
struct zonelist *zonelist;
struct zone *zone;
struct free_area *area;
struct page *page;
int migratetype;
int order,current_order;
pgdat = NODE_DATA(0);
zonelist = pgdat->node_zonelists;
first_zones_zonelist(zonelist,0,NULL,&zone);
migratetype = MIGRATE_MOVABLE;
int order = 0;
for(current_order = 0 ; current_order < MAX_ORDER ; current_order++) {
unsigned long size;
area = &zone->free_area;
if(list_empty(&area->free_list))
continue;
page = list_entry(area->free_list.next,
struct page,lru);
list_del(&page->lru);
rmv_page_order(page);
area->nr_free--;
size = 1 << current_order;
while(order < current_order) {
ara--;
current_order--;
size >>= 1;
list_add(&page,lru,
&area->free_list);
set_page_order(&page,current_order);
area->nr_free++;
}
if(!PageBuddy(page))
goto out;
}
printk(KERN_INFO "Can't get free page\n");
return;
out:
printk(KERN_INFO "Get free page\n");
}
释放一个 page 回伙伴系统
void TestCase_free_page(void)
{
struct page *page = /* 已知*/;
struct zone *zone;
struct page *buddy;
unsigned long page_idx,buddy_idx;
unsigned long combine_idx;
int order = 0;
zone = page_zone(page);
migratetype = get_pageblock_migratetype(page);
page_idx = page_to_pfn(page);
while(order < MAX_ORDER-1) {
buddy_idx = __find_buddy_index(page_idx,order);
buddy = page + (buddy_idx - page_idx);
if(!page_is_buddy(page,buddy,order))
break;
list_del(&buddy.lru);
rmv_page_order(buddy);
zone->free_area.nr_free--;
combine_idx = buddy_idx & page_idx;
page = page + (combine_idx - page_idx);
page_idx = combine_idx;
order++;
}
set_page_order(page,order);
if((order < MAX_ORDER - 2) && (pfn_valid_within(page_to_pfn(page)))) {
struct page *higher_page,*higher_buddy;
combine_idx = buddy_idx & page_idx;
higher_page = page + (combine_idx - page_idx);
buddy_idx = __find_buddy_index(combine_idx,order + 1);
higher_buddy = higher_page + (buddy_idx - combine_idx);
if(page_is_buddy(higher_page,higher_buddy,order + 1)) {
list_add_tail(&page->lru,
&zone->free_area.free_list);
goto out;
}
}
list_add(&page->lru,
&zone->free_area.free_list);
out:
zone->free_area.nr_free++;
} 3. 使用 main() 函数的构造函数作为 Uboot,使用 main() 作为 kernel 空间.
这句话怎么理解? 本帖最后由 Buddy_Zhang1 于 2016-03-08 22:10 编辑
回复 9# nswcfd
就是 C 语言中 main() 函数的构造函数,main() 函数有它的构造函数和析构函数,我把构造函数当做 uboot 过程,把析构函数当做关机过程.
该方法已经实现.
{:yxh45:}
具体实现方法如下:
/*
* Simulate U-boot
*/
__attribute__((constructor)) __uboot U_boot(void)
{
mm_debug("[%s]Boot From U_Boot\n",__FUNCTION__);
u_boot_start();
mm_debug("[%s]Uboot finish,start kernel...\n",__FUNCTION__);
start_kernel();
mm_debug("Kernel Running.....\n=====Hello World=====\n");
}
/*
* Simulate power-down.
*/
__attribute__((destructor)) __exit Pown_down(void)
{
mm_debug("=======Goodbye=======\n");
mm_debug("[%s]Pown down......\n",__func__);
}