📄 fork.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)!=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_call0(int,fork)
system_call1(int,free_process,struct task_struct*,p)
/*
* 在任务数组中获得空的任务结构体的索引
*/
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->context_start =p->pid*TASK_MEM_LIMIT;
p->context_end =(p->context_start+TASK_MEM_LIMIT)-1;
p->cpu_registers.r0 =regs->r0;
p->cpu_registers.r1 =regs->r1;
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 =p->context_end-4;
p->cpu_registers.lr =regs->lr;
p->cpu_registers.pc =p->context_start;
p->cpu_registers.cpsr =regs->cpsr;
p->state =TASK_RUNNING;
}
/*
* 很重要的一个函数,该函数把任务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->context_start;
mva<p->context_start+context_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;
#ifdef _FORK_DEBUG
printk("free task %d details \n",nr);
printk("handle: 0x%08x was freed\n",p);
printk("context mva from 0x%08x to 0x%08x was freed.\n",p->context_start,p->context_end);
printk("task %d was complete freed.\n",nr);
#endif
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -