这本书开发的操作系统,用到了下面的内存分布图:
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;/*失败*/ }