自制操作系统——脉络梳理

文件编译流程

在这里插入图片描述

GDT表

在这里插入图片描述

多任务结构

在这里插入图片描述

内存释放的3种情况

在这里插入图片描述

内核API

这些是应用程序可以调用的OS提供的函数,OS自身其实也会调用这些函数

void api_putchar(int c);
void api_putstr0(char *s);
void api_putstr1(char *s, int l);
void api_end(void);
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
void api_putstrwin(int win, int x, int y, int col, int len, char *str);
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
void api_initmalloc(void);
char *api_malloc(int size);
void api_free(char *addr, int size);
void api_point(int win, int x, int y, int col);
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
void api_closewin(int win);
int api_getkey(int mode);
int api_alloctimer(void);
void api_inittimer(int timer, int data);
void api_settimer(int timer, int time);
void api_freetimer(int timer);
void api_beep(int tone);

回收内存的函数(解释都在注释里)

  • 内存回收的原理:用一个数组记录空闲段的位置、大小,根据要回收的内存和空闲内存的位置关系,采取不同的方法,本质就是内存地址空间的合并
int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size)
/* 释放*/
{
	int i, j;
    /* 为便于归纳内存,将free[]按照addr的顺序排列 */
    /* 即需要找到要释放的内存的前后空闲free的地址,因为后面肯定会合并的 */
	for (i = 0; i < man->frees; i++) {
		if (man->free[i].addr > addr) {
			break;/* addr在这个区间: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) {//这里感觉有点问题,i的初始值如果为0???
				/* 后面也有 */
				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; /* 成功 */
		}
	}
	/* 以下是i==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空间
		/*  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; /* 成功 */
	}
	/* 不能往后移动 ,没有free空间,空间管理信息用完*/
	man->losts++;
	man->lostsize += size;
	return -1; /* 失敗 */
}

内存管理结构体

#define MEMMAN_FREES		4090	//允许4090个空闲段
#define MEMMAN_ADDR			0x003c0000
struct FREEINFO {	/* 可用信息 */
	unsigned int addr, size;
};
struct MEMMAN {		/* 内存管理 */
	int frees, maxfrees, lostsize, losts;
	struct FREEINFO free[MEMMAN_FREES];/* 約32KB */
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值