读书笔记《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;
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值