From e620e5e6ed54f6ea3d18b560b6491b86d1ae93fb Mon Sep 17 00:00:00 2001 From: Yourtion Date: Tue, 12 Apr 2016 13:38:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=91=E6=88=98=E5=86=85=E5=AD=98=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 09_day/bootpack.c | 134 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 130 insertions(+), 4 deletions(-) diff --git a/09_day/bootpack.c b/09_day/bootpack.c index 040412f..7204cee 100644 --- a/09_day/bootpack.c +++ b/09_day/bootpack.c @@ -3,14 +3,33 @@ #include "bootpack.h" #include +#define MEMMAN_FREES 4090 /* 大约是32KB*/ + +struct FREEINFO { /* 可用信息 */ + unsigned int addr, size; +}; +struct MEMMAN { /* 内存管理 */ + int frees, maxfrees, lostsize, losts; + struct FREEINFO free[MEMMAN_FREES]; +}; + unsigned int memtest(unsigned int start, unsigned int end); +void memman_init(struct MEMMAN *man); +unsigned int memman_total(struct MEMMAN *man); +unsigned int memman_alloc(struct MEMMAN *man, unsigned int size); +int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size); + +#define MEMMAN_ADDR 0x003c0000 void HariMain(void) { struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; char s[40], mcursor[256], keybuf[32], mousebuf[128]; int mx, my, i; - struct MOUSE_DEC mdec; + struct MOUSE_DEC mdec; + + unsigned int memtotal; + struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; init_gdtidt(); init_pic(); @@ -23,6 +42,10 @@ void HariMain(void) init_keyboard(); enable_mouse(&mdec); + memtotal = memtest(0x00400000, 0xbfffffff); + memman_init(memman); + memman_free(memman, 0x00001000, 0x0009e000); /* 0x00001000 - 0x0009efff */ + memman_free(memman, 0x00400000, memtotal - 0x00400000); init_palette(); init_screen8(binfo->vram, binfo->scrnx, binfo->scrny); @@ -33,8 +56,7 @@ void HariMain(void) sprintf(s, "(%d, %d)", mx, my); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s); - i = memtest(0x00400000, 0xbfffffff) / (1024 * 1024); - sprintf(s, "memory %dMB", i); + sprintf(s, "memory %dMB free : %dKB", memtotal / (1024 * 1024), memman_total(memman) / 1024); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 32, COL8_FFFFFF, s); for (;;) { @@ -52,7 +74,7 @@ void HariMain(void) i = fifo8_get(&mousefifo); io_sti(); if (mouse_decode(&mdec, i) != 0) { - /* 3字节都凑齐了,所以把它们显示出来*/ + /* 3字节都凑齐了,所以把它们显示出来*/ sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y); if ((mdec.btn & 0x01) != 0) { s[1] = 'L'; @@ -128,3 +150,107 @@ unsigned int memtest(unsigned int start, unsigned int end) return i; } + +void memman_init(struct MEMMAN *man){ + man->frees = 0; /* 可用信息数目 */ + man->maxfrees = 0; /* 用于观察可用状况:frees的最大值 */ + man->lostsize = 0; /* 释放失败的内存的大小总和 */ + man->losts = 0; /* 释放失败次数 */ + return; +} + +unsigned int memman_total(struct MEMMAN *man) +/* 报告空余内存大小的合计 */ +{ + unsigned int i, t = 0; + for (i = 0; i < man->frees; i++) { + t += man->free[i].size; + } + return t; +} + +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) { + /* 如果free[i]变成了0,就减掉一条可用信息 */ + man->frees--; + for (; i < man->frees; i++) { + man->free[i] = man->free[i + 1]; /* 代入结构体 */ + } + } + return a; + } + } + return 0; /* 没有可用空间 */ +} + +int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size) +/* 释放 */ +{ + int i, j; + /* 为便于归纳内存,将free[]按照addr的顺序排列 */ + /* 所以,先决定应该放在哪里 */ + for (i = 0; i < man->frees; i++) { + if (man->free[i].addr > addr) { + break; + } + } + /* free[i - 1].addr < addr < free[i].addr */ + 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->free[i]删除 */ + /* free[i]变成0后归纳到前面去 */ + 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) { + /* free[i]之后的,向后移动,腾出一点可用空间 */ + 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; /* 失败 */ +}