内存管理——物理内存

本文详细描述了Bochs中的物理内存管理和线性内存管理方法,包括物理内存的分段、映射方式(如Map和分块链接表),以及内存分配和释放的过程,特别关注了0x00000000到0xfffc0000的内存区域划分。
摘要由CSDN通过智能技术生成

内存管理分为物理内存管理,线性内存管理。物理内存用Map方式管理,线性内内用分块链接表方式管理。

以bochs为例,其物理内存分段情况:

开始地址大小类型说明
0x00000000 0x0009f0001可供操作系统使用中断向量表
0x0009f000 0x000010002正在由系统使用或保留
0x000e8000 0x000180002正在由系统使用或保留
0x00100000 0x01ef0000 1可供操作系统使用
0x01ff0000 0x00010000   3其他未定义
0xfffc0000 0x00040000 2正在由系统使用或保留

一、物理内存管理

在线性内存空间里建立一个内存块(这个位置固定在系统映像+系统栈之后8K,都是4K对齐),以映像(map)的方式管理,将线性地址按4K一块,映像中每个字节表示一个物理内存块的状态,8KB可以标注32M线性内存,当前块使用一次则增加1,释放则减1,如果该数字为0表示为空闲块。

前1M:物理内存地址=线性内存地址,该空间先不使用,全部置1。从0x100000开始,页目录(4K)、页表(?)、系统映映像(?)、系统栈(16K)、内存map(8K)、空闲(?)、特殊用途(?)。?表示根据实际需要计算大小。

需要申请空内存块时可以遍历map映像找到一个空块或者从大块中分割出小块。

释放时,检查下前块及后块是否是空闲的,如果空闲则合并。

PBYTE lpPhysicsMap; 			//物理内存管理map
//增加该变量可以节省搜索时间
DWORD lpPhysicsMapSearchPos; //map 初始化时记录第一个未使用的物理内存,在分配时记录搜索过的地址,释放时记录最小地址
DWORD dwPhysicsFreeCount;//空物理内存数
DWORD dwPhysicsCount;	//总物理内存

void set_physics_4k(DWORD addr,DWORD size,DWORD type)
{
 if(addr<4096*4096*2)
	memset(lpPhysicsMap+addr/4096,type,size/4096);
}

void init_Physics()
{//lb 0x080405158
	//物理内存按4K一块占1字节,做成一个MAP,32M 需要 8K;
	//此处还无法使用mem_virtual_alloc函数,因此让osloader.asm预留8K.
	//
	//数据在osloader.asm里通过int 15h查询
	PE820MAP pm=0x7F00;
	//物理内存列表
	DWORD size,UsedMem;//x
	//0x80400000 为内核加载地址,即文件头
	//内核占用内存
	size=((PIMAGE_DOS_HEADER)0x80400000)->e_lfanew+0x80400000;
	size=((PIMAGE_NT_HEADERS)size)->OptionalHeader.SizeOfImage;
	print_farmat_msg("oskrnl. size  :%x\n",size);
	//已经使用的线性空间,内核+栈(4页)+map(2页)=0x14000+0x4000+0x2000
	size+=0x6000;
	lpPhysicsMap=size+0x80400000-0x2000;
	//全部设置为不可用
	 dwPhysicsFreeCount=0;
	 dwPhysicsCount=0;
	for (int i=0;i<pm->nr_map;i++)
	{
		dwPhysicsCount+=pm->map[i].size;
		print_farmat_msg("%8x\t,%8x\t,%x\n",pm->map[i].addr,pm->map[i].size,pm->map[i].type);
		//type:	1 AddressRangeMemory 此运行是可供操作系统使用的可用 RAM 。
		//     	2 AddressRangeReserved 该地址段正在由系统使用或保留,并且不得由操作系统使用。
		//其他未定义  未定义 - 保留供将来使用。
		//可用内存,1M以前的内存暂时保留不用
		if(pm->map[i].addr<0x100000)
		{
			//前1M设置为不可用
			continue;
		}
		if(pm->map[i].type==1)
		{
			set_physics_4k(pm->map[i].addr,pm->map[i].size,0);
			dwPhysicsFreeCount+=pm->map[i].size;
		}
		else
		{
			set_physics_4k(pm->map[i].addr,pm->map[i].size,1);
			//2 "ARR" is AddressRangeReserved.
			//
		}

	}
	//最后一个已经被使用的物理页  1M+页目录+页表+内核+栈+map
	UsedMem=*(DWORD *)MiGetPteAddress(size+0x80400000-4)&0xFFFFF000;
	UsedMem+=0x1000;	//指向第一个可用空闲地址,
	print_farmat_msg(" next free Physics mem  :%x\n",UsedMem);
	//前1M 、已经使用的物理内存全部置1
	set_physics_4k(0,UsedMem,1);
	//搜索开始位置
	lpPhysicsMapSearchPos=UsedMem;

}

//每次一页4K
DWORD get_freed_Physics()
{
	DWORD p=0;
	 //lpPhysicsMapCurrent记录以前查找过的块
	 DWORD m=lpPhysicsMapSearchPos;
	 //没有超过边界,遍历map
	 while(m<dwPhysicsCount)
	 {
		 if(lpPhysicsMap[m/4096]==0)
		 {
			 //当前位置map置1
			 lpPhysicsMap[m/4096]=1;
			 //记录当前位置
			 lpPhysicsMapSearchPos=m;
			 //返回实际物理地址;
			 p=m;

			 break;
		 }
		m++;
	 }
	 return p;
}
void free_Physics(DWORD page)
{
	//先
	if(--lpPhysicsMap[page/4096]<=0)
	{
		//当前块减少映射后为空闲块,
		lpPhysicsMap[page/4096]=0; //正常情况下,当前傎应当不会小于0
		//如果搜索指在前面,则后至当前位置
		if(lpPhysicsMapSearchPos>page)
		{
			lpPhysicsMapSearchPos=page;
		}
	}
	else
	{

	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麻雀123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值