当前位置: 技术问答>linux和unix
进程复制函数中的任务状态段TSS的作用?
来源: 互联网 发布时间:2016-10-15
本文导语: 求高手帮忙,在下面的进程复制的程序中,TSS是怎么定义的结构体,它的作用是什么,为什么复制这些内容,多谢。 int copy_process(int nr,long ebp,long edi,long esi,long gs,long none,long ebx,long ecx,long edx,long fs,long es,long d...
求高手帮忙,在下面的进程复制的程序中,TSS是怎么定义的结构体,它的作用是什么,为什么复制这些内容,多谢。
int copy_process(int nr,long ebp,long edi,long esi,long gs,long none,long ebx,long ecx,long edx,long fs,long es,long ds,long eip,long cs,long eflags,long esp,long ss)
{
struct task_struct *p;
int i;
struct file *f;
p=(task_struct *)get_free_page();
if(!p)//如果申请失败的话
return -EAGAIN;
task[nr]=p;
*p=*current;//这个只会复制当前进程的内容
p->state=TASK_UNINTERRUPTIBLE;//先将进程设置为不可中断状态
p->pid=last_pid;//这个由下面一个函数会得到的。
p->father=current->pid;//设置父亲就什当前的进程
p->counter=p->priority;
p->signal=0;
p->leader=0;
p->alarm=0;
p->utime=p->stime=0;//初始化用户态和核心态的时间为0
p->cutime=p->cstime=0;//初始化子进程的用户态和核心态的时间
p->start_time=jiffies;//当前滴答数时间
// 以下设置任务状态段 TSS 所需的数据
p->tss.back_link = 0;
p->tss.esp0 = PAGE_SIZE + (long) p; // 堆栈指针(由于是给任务结构 p 分配了 1 页
// 新内存,所以此时 esp0 正好指向该页顶端)。
p->tss.ss0 = 0x10;
// 堆栈段选择符(内核数据段)[??]。
p->tss.eip = eip;
// 指令代码指针。
p->tss.eflags = eflags;
// 标志寄存器。
p->tss.eax = 0;
p->tss.ecx = ecx;
p->tss.edx = edx;
p->tss.ebx = ebx;
p->tss.esp = esp;
p->tss.ebp = ebp;
p->tss.esi = esi;
p->tss.edi = edi;
p->tss.es = es & 0xffff;
// 段寄存器仅 16 位有效。
p->tss.cs = cs & 0xffff;
p->tss.ss = ss & 0xffff;
p->tss.ds = ds & 0xffff;
p->tss.fs = fs & 0xffff;
p->tss.gs = gs & 0xffff;
p->tss.ldt = _LDT(nr); // 该新任务 nr 的局部描述符表选择符(LDT 的描述符在 GDT 中)。
p->tss.trace_bitmap = 0x80000000; (高 16 位有效)。
if(last_task_used_math==current)//如果当前任务使用了协处理器,就保存其上下文。
__asm__("clts ; fnsave %0"::"m" (p->tss.i387));
if(copy_mem(nr,p))
{
task[nr]=NULL;//如果复制失败的话
free_page((long)p);
return -EAGAIN;
}
//如果父进程有文件打开的,则将对应的文件次数加1
for(i=0;if_count++;
}
//将当前进程(父进程)的 pwd, root 和 executable 引用次数均增 1。
if (current->pwd)
current->pwd->i_count++;
if (current->root)
current->root->i_count++;
if (current->executable)
current->executable->i_count++;
//设置新任务的 TSS 和 LDT 描述符项(在 GDT 中),数据从 task 结构中取。在任务切换时,任务寄存器 tr 由 CPU 自动加载。局部描述符表寄存器 ldtr 已在 task0 时加载。
set_tss_desc(gdt+(nr