免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 4206 | 回复: 32
打印 上一主题 下一主题

[内存管理] [73%]正在写一个模拟 Linux 内存管理的系统 [复制链接]

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-03-02 16:53 |只看该作者 |倒序浏览
本帖最后由 Buddy_Zhang1 于 2016-03-24 20:38 编辑

我想写一个关于内存管理的小系统,该系统的内存管理机制完全模拟 Linux 的内存管理机制.

我的想法是在用户空间申请两个大小为 256M 的数组,然后把这两个数组模拟成两块内存块,
我就基于这两块虚拟内存块,在其上面构建一个和 Linux 内存管理机制一样的系统.
这个系统是运行在用户空间的,也就是一个用户程序而已!

这样是否可行?大家提提意见.

写这个系统的目的就是学习 Linux 内存管理从创建到运行管理的整个过程,如果可行,并且写出来,我会开源出来.

谢谢!

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
2 [报告]
发表于 2016-03-03 08:41 |只看该作者
本帖最后由 Buddy_Zhang1 于 2016-03-04 11:47 编辑

经过考虑,我做以下模拟:
1. 硬件模拟支持 MMU 的 ARMv7
2. 使用纯 C 编写.
3. 使用 main() 函数的构造函数作为 Uboot,使用 main() 作为 kernel 空间.
4. 单核 UMA
5. 两块模拟内存块之间存在一定大小 hole.

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
3 [报告]
发表于 2016-03-04 11:45 |只看该作者
Feature Update:
该内存管理系统支持内存分配器如下:
1. Bootmem Allocator
2. Per-CPU Allocator
3. Buddy Allocator
4. PCP Allocator
5. SLUB Allocator
6. VMALLOC Allocator
7. KMAP Allocator

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
4 [报告]
发表于 2016-03-04 18:00 |只看该作者
赞!+U!

PS,为啥需要模拟硬件,哪些逻辑跟arch相关?

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
5 [报告]
发表于 2016-03-04 21:06 |只看该作者
本帖最后由 Buddy_Zhang1 于 2016-03-04 21:08 编辑

回复 4# nswcfd


主要是模拟硬件 MMU 和页表转换过程,其中 setup_arch() 函数中比较多
和 arch 关系最大的当属 Bootmem Allocator 了


   

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
6 [报告]
发表于 2016-03-06 12:04 |只看该作者
本帖最后由 Buddy_Zhang1 于 2016-03-06 12:04 编辑

Feature Update:
核心算法支持:
1. 红黑树
2. 优先查找树
3. 基数树.
4. HASH
5. 伙伴系统算法

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
7 [报告]
发表于 2016-03-07 12:08 |只看该作者
技术问题:
我使用的是 64 位的系统,但我写的系统是一个 32 位的系统,所以在 64 位用户空间模拟 32 位程序是一个难题.

大家有没相应的经验,交流一下.

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
8 [报告]
发表于 2016-03-08 10:42 |只看该作者
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[current_order];
           if(list_empty(&area->free_list[migratetype]))
                      continue;
   
           page = list_entry(area->free_list[migratetype].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[size],lru,
                              &area->free_list[migratetype]);
                set_page_order(&page[size],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[order].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[order].free_list[migratetype]);
                   goto out;
          }
    }
    list_add(&page->lru,
                   &zone->free_area[order].free_list[migratetype]);
out:
    zone->free_area[order].nr_free++;
}

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
9 [报告]
发表于 2016-03-08 20:20 |只看该作者
3. 使用 main() 函数的构造函数作为 Uboot,使用 main() 作为 kernel 空间.

这句话怎么理解?

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
10 [报告]
发表于 2016-03-08 22:07 |只看该作者
本帖最后由 Buddy_Zhang1 于 2016-03-08 22:10 编辑

回复 9# nswcfd


    就是 C 语言中 main() 函数的构造函数,main() 函数有它的构造函数和析构函数,我把构造函数当做 uboot 过程,把析构函数当做关机过程.
    该方法已经实现.


    具体实现方法如下:


/*
* 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__);
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP