内核进程初始化和创建

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号进程复制 结构体的复制 把task0对应的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.将当前子进程放入到整体进程链表中

tasknr = 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->filpi)

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;

相关推荐
1024+11 小时前
在 ‌Ubuntu 24.04‌ 上安装 ‌Python 3.8‌
linux·python·ubuntu
ai安歌11 小时前
鸿蒙PC:Linux 搭建 Rust 开发环境并实现计算器项目
linux·rust·harmonyos
fan_music11 小时前
后端学习链接
linux
biter down12 小时前
4:Ubuntu 22.04 安装完成后的收尾与优化
linux·运维·ubuntu
凡人叶枫12 小时前
Effective C++ 条款37:绝不重新定义继承而来的缺省参数值
linux·c++·windows
zhangfeng113312 小时前
国家超算中心 昆山站 异构加速卡1 显存16GB详细配置, 海光 Z100SM HCU
linux·网络·深度学习·c#
悠悠1213812 小时前
Linux 7.1 来了:新 NTFS 驱动、干掉 i486、FRED 默认开启,这次更新有点东西
linux·运维·服务器
用户8055336980312 小时前
Linux 工作队列:把中断里做不了的事推迟到进程上下文
linux·嵌入式
pingglala12 小时前
winscp连接linux失败解决方法
java·linux·服务器
William.csj12 小时前
Linux——普通用户离线源码编译 gcc-9 方法和调用教程
linux·服务器·gcc