18.简易内存管理

简介

上一节实现了对内存信息的解析,操作系统的一个重要功能就是提供内存管理,为应用程序提供动态内存分配。一个好的内存管理算法不会使系统内存资源耗尽、内存碎片较少。

目标

实现简易的内存分配、回收管理算法。
1.新建memman.h

//内存管理模块

#define  MEMMAN_FREES  4096

typedef struct _FREEINFO {
    unsigned int *addr, size;
}FREEINFO;

//该结构体空间大小大致为32K 
typedef struct _MEMMAN {
	//frees 表示空闲内存块的数量
	//lostsize 表示丢弃的内存大小
	//losts 表示丢弃的内存次数
    int frees, maxfrees, lostsize, losts;
    struct _FREEINFO free[MEMMAN_FREES];
}MEMMAN;

void memman_init(MEMMAN *man);

unsigned int memman_total(MEMMAN *man);

unsigned int* memman_alloc(MEMMAN *man,unsigned int size);

int memman_free(MEMMAN *man,unsigned int *addr,unsigned int size);

2.新建memman.c

#include"memman.h"

void memman_init(MEMMAN *man){
	man->frees = 0;
	man->maxfrees = 0;
    man->lostsize = 0;
    man->losts = 0;
}


unsigned int memman_total(MEMMAN *man){
    unsigned int t = 0;
    for (int i = 0; i < man->frees; i++) {
        t += man->free[i].size;
    }

    return t;
}


unsigned int* memman_alloc(MEMMAN *man,unsigned int size) {
    unsigned int *a;
    for (int i = 0; i < man->frees; i++) {
        if (man->free[i].size >= size) {
            a = man->free[i].addr;
            man->free[i].size -= size;
			man->free[i].addr = (unsigned int *)(((char *)(man->free[i].addr))+size);
            if (man->free[i].size == 0) {//在索引i 后的内存记录块往前搬移
				for(int j=i+1;j<man->frees;j++){
					man->free[j-1] = man->free[j]; 
				}
                man->frees--;
            }

            return a;
        }
    }

    return (unsigned int*)0;
}


int memman_free(MEMMAN *man,unsigned int *addr,unsigned int size){
	unsigned int *offAddr = (unsigned int*)((char *)addr+size);
	for(int i=0;i<man->frees;i++){
		if((char *)(man->free[i].addr)+man->free[i].size == (char *)addr){//作为高地址合并
			man->free[i].size += size;
			return 1;
		}
		else if(man->free[i].addr == offAddr){//作为低地址合并
			man->free[i].addr = addr;
			man->free[i].size += size;
			return 1;
		}
	}
	//作为新增块
	man->free[man->frees].addr = addr;
	man->free[man->frees].size = size;
	man->frees++;
	return 1;
}

3.os.c init_main函数中添加如下

_memman = (MEMMAN *)0x010000;
memman_init(_memman);
_memman->frees = 1;
_memman->free[0].addr = (unsigned int *)(0x010000+0x8000);
_memman->free[0].size = (0x01fef000-0x8000);

int memToal = memman_total(_memman);
for(int j=0;j<4;j++){
	temp = char2HexStr(((char *)&memToal)[3-j]);
	_tempArr[2+2*j] = ((char *)&temp)[0];
	_tempArr[3+2*j] = ((char *)&temp)[1];
	
}
_charCount += 10;
showString(_tempArr,10,true);

4.编译memman.c
clang -c -m32 memman.c -o memman.o

5.编译os.c

clang -c -m32 os.c -o os.o 

6.链接memman.o 和 os.o

ld -m elf_i386 -r os.o memman.o -o os-mem.o

7.反汇编os-mem.o

  ./objconv -fnasm os-mem.o -o os.s 

并去除global、extern、SECTION 等申明信息

8.加载并运行floppy.img,虚拟机使用的内存为512M。依次按下回车键到os.c 中低4字节内存地址等于0x010000效果如下:
在这里插入图片描述
以上做了一个大致的内存分配显示,os.c 中解析的内存地址和长度都是固定的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值