⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fork.c

📁 os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm
💻 C
字号:
/*
 *	ApOS (Another Project software for s3c2410)
 *	
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License version 2 as
 *	published by the Free Software Foundation.
 *			
 *						Copyright caiyuqing
 *
 */
#include "../include/kernel/sched.h"
#include "../include/kernel/task.h"
#include "../include/mm/mm.h"
#include "../include/s3c2410/cpu.h"
#include "../include/kernel/sys.h"
#define _FORK_DEBUG	1

#define TASK_MEM_LIMIT	(1024*1024*32)
/*
 *	procID 25,25 的虚拟内存地址范围用于物理RAM
 *	procID 36~47  的虚拟内存地址范围用于SFR
 *	procID 127    的虚拟内存地址范围包含中断向量
 *
 */
#define NOT_MASK_TASK_ID(procID) (!(((procID)>=4)&&((procID)<=8))&&(procID)!=24)&&((procID)!=25)&& \
!(((procID)>=36)&&((procID)<=47)) \
&&((procID)!=127)

#define TASK_EMPTY(task) (task)==0

extern struct task_struct* task[NR_TASKS];
extern struct task_struct* current;
extern unsigned int last_pid;
extern int jiffies;


system_call1(int,free_process,struct task_struct*,p)

/*
 *	将父进程task[nr]的内存页面复制给其子进程p,从而实现父子进程
 *	的内存共享
 */
void copy_mem(struct task_struct* p)
{
	unsigned int child_data_base;
	unsigned int father_data_base;
	unsigned int limit;
	
	child_data_base		=p->data_segment_base;
	father_data_base	=current->data_segment_base;
	limit			=current->data_segment_limit-current->data_segment_base;
	
	copy_page_tables(father_data_base,child_data_base,limit);
}

/*
 *	在任务数组中获得空的任务结构体的索引
 */
int find_empty_process()
{
	int i;
	for(i=1;i<NR_TASKS;i++)
	{
		if(TASK_EMPTY(task[i])&&NOT_MASK_TASK_ID(i))
		{
			last_pid=i;
			return last_pid;
		}
	}
	return -1;
}

/*
 *	
 */
void copy_process(int nr,struct cpu_registers *regs)
{
	struct task_struct* p;
	p=(struct task_struct *)get_free_physical_page();
	task[nr]=p;
	
	*p=*current;
	
	p->state		=TASK_UNINTERRUPTIBLE;
	p->counter		=p->priority;
	p->signal		=0;
	p->deal_signal		=0;
	p->blocked		=0;
	p->alarm		=0;
	p->utime		=0;
	p->stime		=0;
	p->cutime		=0;
	p->cstime		=0;
	p->start_time		=jiffies;
	p->pid			=last_pid;
	p->father		=current->pid;

	p->code_segment_base	=nr*TASK_MEM_LIMIT;
	p->code_segment_limit	=nr*TASK_MEM_LIMIT+TASK_MEM_LIMIT;
	p->data_segment_base	=nr*TASK_MEM_LIMIT;
	p->data_segment_limit	=nr*TASK_MEM_LIMIT+TASK_MEM_LIMIT;
	
	p->cpu_registers.r0	=0;		//很重要的一个细节,这是为什么
	p->cpu_registers.r1	=regs->r1;	//fork之后子任务会以0返回的原因
	p->cpu_registers.r2	=regs->r2;     
	p->cpu_registers.r3	=regs->r3;
	p->cpu_registers.r4	=regs->r4;
	p->cpu_registers.r5	=regs->r5;
	p->cpu_registers.r6	=regs->r6;
	p->cpu_registers.r7	=regs->r7;
	p->cpu_registers.r8	=regs->r8;
	p->cpu_registers.r9	=regs->r9;
	p->cpu_registers.r10	=regs->r10;
	p->cpu_registers.r11	=regs->r11;
	p->cpu_registers.r12	=regs->r12;
	p->cpu_registers.sp	=regs->sp+(nr*0x2000000)-4;
	p->cpu_registers.lr	=regs->lr;
	p->cpu_registers.pc	=regs->pc;
	p->cpu_registers.cpsr	=regs->cpsr;
	p->state		=TASK_RUNNING;
	
	copy_mem(p);
	
}




/*
 *	很重要的一个函数,该函数把任务p所涉及到的虚拟内存页释放。
 *	free_virtual_page(unsigned int v_page)用于释放指定的虚拟
 *	页,如果该虚拟内存页存在(有映射到物理空间)则把该页释放,
 *	否则返回-1,free_virtual_page(unsigned int v_page)在memory.c
 *	中实现
 */
void free_process_mem(struct task_struct* p)
{
	unsigned int* mva;
	unsigned int context_limit=TASK_MEM_LIMIT;
	
	/*
	 *	释放任务的虚拟内存
	 */
	for(mva=p->code_segment_base;
		mva<p->code_segment_limit;
		mva+=PAGE_SIZE)
	{
		free_virtual_page(mva);
	}

	/*
	 *	此时p所指向的内存是我们在copy_process()函数中申请的用
	 *	于存放task_struct结构体的内存页,释放它。
	 *	这里可能你会问为什么是使用 free_physical_page()
	 *	而不是free_virtual_page(),这是因为p所指向的内存页是用
	 *	get_free_physical_page()函数申请的,它是一个物理地址。
	 *
	 *	至此一个任务所使用的所有内存资源我们都已释放完毕
	 */
	free_physical_page(p);
}

/*
 *	释放任务
 */
int free_task(struct task_struct* p)
{
	int nr;
	
	for(nr=0;nr<NR_TASKS;nr++)
	{
		if(p==task[nr])
			break;
	}
	
	//若释放的是任务0,报错死机
	if(nr==0)
		panic("error:free_process() task0 shouldn't be freed.");
	//若释放任务是空的,报错死机
	if(task[nr]==0)
		panic("error:free_process() try to free a free process.");
	else
	{
		//释放该任务所使用的内存
		free_process_mem(p);

		//与该任务相关的文件操作
		//deal_files(p); (deal_files()函数还没有实现)
		
		//释放该任务对应任务指针,至此一个task被释放完毕
		task[nr]=0;
	}
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -