内核进程初始化和创建

task_struct

1.进程的状态

分时技术进行多进程调度

重点:进程的创建是如何的?

linux在初始化的过程中那个会进行0号进程的创建,fork

sched_init(); 做了什么

内核态 不可抢占

用户态 可以抢占

move_to_user_mode(); 把内核状态切换到用户态

在内核初始化的过程中,会手动创建0号进程,0号进程是所有进程的父进程

进程初始化:

在o号进程中:

1.打开标准输入、输出、错误控制台句柄

2.创建1号进程,如果创建成功,则在1号进程中

首先打开"/etc/rc"文件

执行SHELL程序"/bin/sh"

3.0号进程不可能结束,他会在没有其他进程调用时运行,只会执行for(;;) pause();

进程创建:

fork

1.在task链表中找一个空位存放进程

2.创建一个task_struct

3.设置task_struct

进程的创建就是对0号进程或者当前进程的复制

0号进程复制 结构体的复制 把task[0]对应的task_struct复制给新创建的task_struct

对于栈堆的拷贝 当进程创建的时候要复制原有栈堆(复制完清空)

进程的创建是系统调用:

.align 2

_sys_fork:

call _find_empty_process

testl %eax,%eax

js 1f

push %gs

pushl %esi

pushl %edi

pushl %ebp

pushl %eax

call _copy_process

addl $20,%esp

1: ret

1.给当前要创建的进程分配一个进程号:find_empty_process

2.进程创建主体copy_process,为子进程创建一个task_struct结构体

struct task_struct *p;

p = (struct task_struct *) get_free_page();

3.将当前子进程放入到整体进程链表中

task[nr] = p;

4.设置创建的task_struct

复制代码
    p->state = TASK_RUNNING;
	p->pid = last_pid;
	p->father = current->pid;
	p->counter = p->priority;
	p->signal = 0;
	p->alarm = 0;
	p->leader = 0;		/* process leadership doesn't inherit */
	p->utime = p->stime = 0;
	p->cutime = p->cstime = 0;
	p->start_time = jiffies;
	p->tss.back_link = 0;
	p->tss.esp0 = PAGE_SIZE + (long) p;
	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;
	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);
	p->tss.trace_bitmap = 0x80000000;

如果当前进程使用了协处理器,那就设置协处理器

if (last_task_used_math == current)

asm("fnsave %0"::"m" (p->tss.i387));

进行老进程向新进程代码段 数据段(LDT)的拷贝

if (copy_mem(nr,p)) {

free_page((long) p);

return -EAGAIN;

}

如果父进程打开了某个文件,那么子进程也同样打开这个文件,所以讲文件打开计数+1

for (i=0; i<NR_OPEN;i++)

if (f=p->filp[i])

f->f_count++;

将父进程的属性继承

if (current->pwd)

current->pwd->i_count++;

if (current->root)

current->root->i_count++;

设置进程的两个段,并结合上文设置的变量,组合成一个进程

set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss));

set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt));

返回创建的进程id

return last_pid;

相关推荐
维尔切1 小时前
Linux中基于Centos7使用lamp架构搭建个人论坛(wordpress)
linux·运维·架构
tan77º2 小时前
【项目】分布式Json-RPC框架 - 项目介绍与前置知识准备
linux·网络·分布式·网络协议·tcp/ip·rpc·json
正在努力的小河4 小时前
Linux设备树简介
linux·运维·服务器
荣光波比4 小时前
Linux(十一)——LVM磁盘配额整理
linux·运维·云计算
LLLLYYYRRRRRTT5 小时前
WordPress (LNMP 架构) 一键部署 Playbook
linux·架构·ansible·mariadb
轻松Ai享生活5 小时前
crash 进程分析流程图
linux
大路谈数字化6 小时前
Centos中内存CPU硬盘的查询
linux·运维·centos
luoqice7 小时前
linux下查看 UDP Server 端口的启用情况
linux
倔强的石头_8 小时前
【Linux指南】动静态库与链接机制:从原理到实践
linux
赏点剩饭7789 小时前
linux中的hostpath卷、nfs卷以及静态持久卷的区别
linux·运维·服务器