内核进程初始化和创建

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;

相关推荐
虾..6 小时前
Linux 软硬链接和动静态库
linux·运维·服务器
Evan芙6 小时前
Linux常见的日志服务管理的常见日志服务
linux·运维·服务器
hkhkhkhkh1238 小时前
Linux设备节点基础知识
linux·服务器·驱动开发
HZero.chen9 小时前
Linux字符串处理
linux·string
张童瑶9 小时前
Linux SSH隧道代理转发及多层转发
linux·运维·ssh
汪汪队立大功1239 小时前
什么是SELinux
linux
石小千10 小时前
Linux安装OpenProject
linux·运维
柏木乃一10 小时前
进程(2)进程概念与基本操作
linux·服务器·开发语言·性能优化·shell·进程
Lime-309010 小时前
制作Ubuntu 24.04-GPU服务器测试系统盘
linux·运维·ubuntu
百年渔翁_肯肯10 小时前
Linux 与 Unix 的核心区别(清晰对比版)
linux·运维·unix