• 30天自制操作系统开发笔记——内存管理


    这本书开发的操作系统,用到了下面的内存分布图:

    0x00000000 - 0x000fffff : 启动中多次使用,存放VRAM等内容(1MB)
    0x00100000 - 0x00267fff : 用于保存软盘的内容。(1440KB)
    0x00268000 - 0x0026f7ff : 空(30KB)
    0x0026f800 - 0x0026ffff : IDT(2KB)
    0x00270000 - 0x0027ffff : GDT(64KB)
    0x00280000 - 0x002fffff : bootpack.hrb(512KB)
    0x00300000 - 0x003fffff : 栈及其他(1MB)
    0x00400000 - :空

    根据qemu的设定,整个程序占用的最大内存为32MB

    内存管理的内容主要包括内存分配,内存回收

    内存分配:

    对于这32MB的内存,以4KB为最小单位,用链式的方法去管理,并且遵循每一个未分配的内存块按照地址从小到大排列,每次分配内存时,找到一个不小于要求的大小的内存块分配出去,当一块内存完全分配之后,要把其从链表中删除。

    View Code
    #define EFLAGS_AC_BIT 0x00040000
    #define CR0_CACHE_DISABLE    0x60000000
    #define MEMMAN_FREES     4090
    #define MEMMAN_ADDR     0x003c0000
    
    struct FREEINFO
    {
        unsigned addr,size;
    };
    
    struct MEMMAN
    {
        int frees,maxfrees,lostsize,losts;
        struct FREEINFO free[MEMMAN_FREES];
    };/*要用到的结构体及宏定义*/
    
    void memman_init(struct MEMMAN *man)
    {
        man->frees=0;        /*可用信息数目*/
        man->maxfrees=0;    /*观察可用情况,frees的最大值*/
        man->lostsize=0;    /*释放失败的内存的大小总和*/    
        man->losts=0;        /*释放失败次数*/
    }/*初始化*/
    
    unsigned int memman_alloc(struct MEMMAN *man,unsigned int size)
    {
        unsigned int i,a;
        for(i=0;i<man->frees;i++)
        {
            if(man->free[i].size>=size)
            {
                a=man->free[i].addr;
                man->free[i].addr+=size;
                man->free[i].size-=size;
                if(man->free[i].size==0)
                {
                    man->frees--;
                    for(;i<man->frees;i++)
                    {
                        man->free[i]=man->free[i+1];/*这一段内存被完全占用,删掉记录*/
                    }
                }
                return a;
            }
        }
        return 0;
    }/*内存分配,返回得到内存的起始地址*/

    内存回收:

    回收时要注意回收的内存和可以连接到一起的内存连接起来

    View Code
    int memman_free(struct MEMMAN *man,unsigned int addr,unsigned int size)
    {
        int i,j;
        /*先决定放在什么位置上*/
        for(i=0;i<man->frees;i++)
        {
            if(man->free[i].addr>addr)
                break;
        }
        if(i>0)/*前面有可用内存*/
        {
            if(man->free[i-1].addr+man->free[i-1].size==addr)/*可以和前面的连到一起*/
            {
                man->free[i-1].size+=size;
                if(i<man->frees)/*后面有可用内存*/
                {
                    if(addr+size==man->free[i].addr)
                    {
                        man->free[i-1].size+=man->free[i].size;
                        man->frees--;
                        for(;i<man->frees;i++)
                            man->free[i]=man->free[i+1];
                    }
                }
                return 0;
            }
        }
        if(i<man->frees)/*前面没有可用内存,或者不能跟前面内存连到一起*/
        {
            if(addr+size==man->free[i].addr)/*可以和后面连到一起*/
            {
                man->free[i].addr=addr;
                man->free[i].size+=size;
                return 0;
            }
        }
        if(man->frees<MEMMAN_FREES)
        {
            for(j=man->frees;j>i;j--)
            {
                man->free[j]=man->free[j-1];
            }
            man->frees++;
            if(man->maxfrees<man->frees)
            {
                man->maxfrees=man->frees;
            }
            man->free[i].addr=addr;
            man->free[i].size=size;
            return 0;
        }
        /*不能往后移动的*/
        man->losts++;
        man->lostsize+=size;
        return -1;/*失败*/
    }
  • 相关阅读:
    byvoid
    soa文章摘抄
    也谈设计模式,架构,框架和类库的区别
    GoF设计模式三作者15年后再谈模式
    陈梓涵:我们为什么要学习设计模式
    陈梓涵:关于编程的胡扯
    hung task机制
    iscsi target tgt架构
    iscsi target IET架构
    ISCSI工作流程target和initiator
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2935675.html
Copyright © 2020-2023  润新知