讀書筆記《30天自制操作系統》day09

0.不同BIOS判斷內存多大不盡相同,可以自己編寫一個程序判斷機器內存多大,主要方法就是寫完後讀出來比較就知道了。

1. 寄存器EFLAGS第18位AC標誌表示CPU是否爲486以上,486以上CPU有緩存,自己編寫程序判斷內存有多大時應關閉緩存。

2. 對CR0寄存器標誌位進行改寫實現關閉緩存功能

#define CR0_CACHE_DISABLE
/*...*/
cr0=load_cr0();
cr0 |= CR0_CACHE_DISABLE;
store_cr0(cr0);

3. 內存管理(1)位圖法:用一個標誌位表示一部分內存是使用還是空閒(2)列表管理方法:將從xxx到yyy地址空間已經分配了這樣的信息保存在表中。

這部分是對計算機物理內存進行管理的方法,動態分配和釋放,不用在obj文件中分配了!

#define MEMMAN_FREES		4090	/*零碎的保存free內存塊*/
#define MEMMAN_ADDR			0x003c0000

struct FREEINFO {	/* free可用信息 */
	unsigned int addr, size;
};

struct MEMMAN {		/*內存管理結構體*/
	int frees, maxfrees, lostsize, losts;
	struct FREEINFO free[MEMMAN_FREES];
};

void memman_init(struct MEMMAN *man)
{
	man->frees = 0;			/* 可用free塊 */
	man->maxfrees = 0;		/* frees的最大值 */
	man->lostsize = 0;		/* 釋放失敗的內存大小 */
	man->losts = 0;			/* 釋放失敗次數 */
	return;
}
/* 現在free內存大小 */
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) {
			/* find free space */
			a = man->free[i].addr;
			man->free[i].addr += size;
			man->free[i].size -= size;
			if (man->free[i].size == 0) {
				/* 當前free塊正好被全部分配了 */
				man->frees--;
				for (; i < man->frees; i++) {
					man->free[i] = man->free[i + 1]; /* 把後面的free塊信息向前移動 */
				}
			}
			return a;
		}
	}
	return 0; /* not found */
}

int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size)
{
	int i, j;
	/* free[]中信息按照地址空間的順序排序 */
	/* 找到這個釋放的空間放在哪裏 */
	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) {
		/* 前面有與要釋放的內存連續的free內存 */
		if (man->free[i - 1].addr + man->free[i - 1].size == addr) {
			/* 與前面的free內存信息合併到一起 */
			man->free[i - 1].size += size;
			if (i < man->frees) {
				/* 後面也有與要釋放的內存連續的free內存 */
				if (addr + size == man->free[i].addr) {
					/* 可以與後面的free內存信息合併到一起 */
					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; /* ok */
		}
	}
	/* 不能與前面的可用空間合併到一起 */
	if (i < man->frees) {
		/* 後面也有與要釋放的內存連續的free內存 */
		if (addr + size == man->free[i].addr) {
			/* 可以與後面的free內存信息合併到一起 */
			man->free[i].addr = addr;
			man->free[i].size += size;
			return 0; /* ok */
		}
	}
	/* 前後都不能合併 */
	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; /* ok */
	}
	/* 不能向後移動 */
	man->losts++;
	man->lostsize += size;
	return -1; /* 失敗 */
}

3. 以4k大小爲單位的內存分配和釋放


 

unsigned int memman_alloc_4k(struct MEMMAN *man, unsigned int size)
{
	unsigned int a;
	size = (size + 0xfff) & 0xfffff000;
	a = memman_alloc(man, size);
	return a;
}

int memman_free_4k(struct MEMMAN *man, unsigned int addr, unsigned int size)
{
	int i;
	size = (size + 0xfff) & 0xfffff000;
	i = memman_free(man, addr, size);
	return i;
}


 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章