进程切换

来源:互联网 发布:ps大小尺寸怎么调整mac 编辑:程序博客网 时间:2024/04/30 00:22

一个进程的上下文
可以分为三个部分:用户级上下文、寄存器上下文以及系统级上下文。
用户级上下文: 正文、数据、用户堆栈以及共享存储区;
寄存器上下文: 通用寄存器、程序寄存器(IP)、处理器状态寄存器(EFLAGS)、栈指针(ESP,SS);
系统级上下文: 进程控制块task_struct、内存管理信息(mm_struct、vm_area_struct、pgd、pte)、内核栈

发生进程调度时,进行进程切换就是上下文切换(context switch).操作系统必须对上面提到的全部信息进行切换,新调度的进程才能运行。而系统调用进行的是模式切换(mode switch)。模式切换与进程切换比较起来,容易很多,而且节省时间,因为模式切换最主要的任务只是切换进程寄存器上下文的切换。
不需要保存的有:通用寄存器(EAX,EBX….)这些由中断服务例程保存。控制寄存器()CR0,CR3…

对TCB的全面了解和分析。
最终创建一个内核线程,hello world显示。
关键数据结构:
线程控制块 TCB:
struct proc_struct{
int pid;//唯一的ID

//运行管理调度的信息
enum proc_state state;
int runs;
volatile bool need_resched;
uint32_t flags

//内存管理
uintptr_t ksatck; //内核的堆栈
uintptr_t cr3;
strutc mm_struct *mm;//管理线程或者进程的内存空间,缺页异常,检查mm结构判断是否是合法的地址
{
list_entry_t mmap_list;
struct vma_struct * mmap_cache;
pde_t * pgdir;
int map_count;
void * sm_priv;
} //进程需要额合法的内存空间

struct vma_struct {
struct mm_struct * vm_mm;
uintptr_t vm_start
uintptr_t vm_end
uint32_t vm_flags
list_entry_t list_link
}
//与硬件紧密相关
struct context context; //进程运行的上下文
{
uint32_t eip;
uint32_t esp;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
uint32_t esi;
uint32_t edi;
uint32_t ebp;

}//切换上下文,就是切换寄存器的内容,为什么FS,ES,DS不需要保存?:这些值是常量不需要保存,eax同样没有保存,系统调用的返回值存在eax, eax代表返回值。

struct trapframe *tf;{ //中断产生的时候,硬件会把下面的信息放入内核堆栈
//产生中断异常或者系统调用
//硬件保存
uint32_t tf_err;
uintptr_t tf_eip;
uint16_t tf_cs;
uint16_t tf_padding4;
uint32_t tf_eflags;
uintptr_t tf_esp ; 特权级切换,也压入到栈里面
uint16_t tf_ss; 特权级切换,也压入到栈里面,确保可以从ring 0回到ring3
uint16_t tf_padding5;
}
//创建进程时,如果父进程先去世,会把子进程挂在到上一级父进程。
struct proc_struct *parent;父进程的信息
list_entry_t list_link;
list_entry_t hash_link;

}线程控制列表:list_link
环境初始化:
虚拟内存初始化
内核线程初始化
创建内核线程
切换内核线程
initproc 内核线程输出字符串

switch(from,to)//from:idleproc 的context,intiproc的context
movel 4(%esp),%eax //exp+4是 from的context

pushl 0(%eax) //push eip eip是fork rnt的地址
ret //跳转,执行完之后,到了fork的执行点开始执行 forkret
static void forkret(void){
forkrets(current->tf); //在trapentry.s 里面you forkrets的入口地址

//forkret:
movel 4(%esp),%esp
jmp _trapret //恢复被中断的过程

trapret返回后,跳转到kernel_thread_entery:
ebx存储的是fn , fn是函数的名字

}

0 0
原创粉丝点击