x86进行进程切换

简单的进程切换方法,

1、为每个进程设计一个独立的页目录

2、所有进程共用高2G的线性内存,每个进程独享低2G线性内存(暂时保留前4M)

3、每个进程主线程一个栈

4、在普通函数中调用进程切换函数,

好处,只需切换CR3 和栈,超简单。

主线程检测进程时间片,主动切换。

 

void create_Process(DWORD entry)
{
	DWORD page_sys,page_pyh,page_line,page_stack;
	
	//查找空余进程空余位置
	
	
	//DWORD * processptelist=(DWORD *)(PTE_BASE+(PROCESS_PDE_LIST>>22<<12)+(PROCESS_PDE_LIST<<10>>22<<2));
	int i;
	//资源用完
	if (process_count_proc>=1024)   return;

	//每一个进程分配一页物理地址,用作页目录,
	//同时该页目录还映射至0x80000000(2G)以上线性地址,
	//方便每一个进程都能访问所有页目录(是否须要?节省线性地址)	
	//申请一页物理内存作为新进程的页目录,
	page_pyh=(DWORD)getFreedPagePhysicsMemory();
	//申请一页线性地址
	page_line=(DWORD)getFreePageVirtual(1);
	//将页表映射至线性地址,方面读写,
	MapMem(page_pyh,page_line,1);
	


	//所有进程物理前4M地址与线性地址相等(可以减少)
	page_sys=PDE_BASE;
	((DWORD*)page_line)[0]=((DWORD*)page_sys)[0];
	//所有进程物理2G以上地址相同(可以减少)
	copymem((char * )(page_line+4*512),(char * )(page_sys+4*512),4*512);
	//第0x300项指向自身,从而0xc0000000 可以访问各自的页目录
	((DWORD*)page_line)[0x300]=page_pyh;

	//为每个进程申请页栈,栈是逆序后入先出,
	page_stack=(DWORD)getFreePageVirtual(1)+0x1000-4;	
	
	//申请进程信息表
	PProcessInfo pi=xos_malloc(sizeof(ProcessInfo));
	//进程切换主要是Cr3和栈的切换,其他的代码先保留。
	pi->tss.cr3=(DWORD) page_pyh;
	pi->regs.cs	= (0 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
	pi->regs.ds	= (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
	pi->regs.es	= (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
	pi->regs.fs	= (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
	pi->regs.ss	= (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
	pi->regs.gs	= (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK;
	pi->regs.eip= (DWORD)entry;
#define offset 20
	//设计新进程主线程的栈
	pi->regs.ebp=pi->regs.esp= (DWORD)page_stack-offset-8;
	//对应swith_process,返回时
	//
	*(DWORD*)(page_stack-offset-8)=page_stack-12;
	*(DWORD*)(page_stack-offset-4)=(DWORD)entry;

	//下面数据用不上,先保留	
	*(DWORD*)(page_stack-12)=page_stack-8;
	*(DWORD*)(page_stack-8)= 0x8;	//code
	*(DWORD*)(page_stack-4)= 0x202;	//eflags
	*(DWORD*)(page_stack-0)=entry;	
	//pi->regs.eflags = 0x202;	// IF=1, IOPL=1, bit 2 is always 1.
#undef offset	
	//进程运行时间片
	pi->current_tick=TIMER_COUNT;		
	pi->elapsed_ticks=0;
	//加入进程运行列表
	add_process(pi);
	
}
void main_thread(char * file)
{

	//当前进程,下一个运行的进程
	PProcessInfo next_pi,pi=getCurrentProcess();
	do{
		
		if (pi->current_tick>=0)
		{
			//时间片没用完,继续
			pi->current_tick--;
		}
		else
		{
			//时间片用完,切换进程
			pi->current_tick=TIMER_COUNT;	
			next_pi=get_next_process(pi);
			if (pi==next_pi)
			{
				//仅一个进程无需切换
			}
			else
			{
				//测试函数
				TestC(file);	
				swith_process(pi,next_pi);
			}
		}

	}while(true);
}
void swith_process(PProcessInfo prv_pi,PProcessInfo next_pi)
{
	//常规函数调用只需要保存CR3 和esp ebp ,
	//如果是中断中切换,可能需要保存所有寄存器(待试验)
	//最后两条指令 leave  ret(编译后可能有变化)
	//等价于:movl %ebp %esp    popl %ebp       pop %eip
	asm("mov %%esp,%0\n\t "\
		"mov %1,%%cr3\n\t "\
		"mov %2,%%esp\n\t "\
		:"=m"(prv_pi->regs.esp)		//输出
		:"r"(next_pi->tss.cr3),"m"(next_pi->regs.esp)
		);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

麻雀123

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

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

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

打赏作者

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

抵扣说明:

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

余额充值