Linux内核学习笔记——4.内核进程初始化与创建

文章详细介绍了Linux系统中的task_struct结构体在进程管理中的作用,包括进程状态的区分,如内核态和用户态,以及进程如何通过fork系统调用进行创建。在进程创建过程中,涉及到了进程的初始化,如0号进程的生成及其职责,以及如何复制父进程的属性到新创建的子进程中,包括堆栈和内存段的拷贝。
摘要由CSDN通过智能技术生成

task_struct

        counter = counter/2 + priority

1.进程的状态

        分时技术进行多进程调度

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

                1.Linux在初始化的过程中会进行0号进程的创建,fork()

                        sched_init();        做了什么事情?

        内核态:不可抢占的

        用户态:可以抢占的

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

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

        进程的初始化:

                在0号进程中:

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

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

                                (1)首先打开了“/etc/rc”文件

                                (2)执行SHELL程序“/bin/sh”

                        3.0号进程不可能结束,他会在没有其他进程调用的时候调用,只会执行

                                        for(;;),pause();

2.进程创建

        fork():

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

        2.创建一个task_struct

        3.设置task_struct

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

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

                对于堆栈的拷贝-当进程做创建的时候要复制原有的堆栈

         1.进程的创建时系统调用:

 sys_fork()调用,用于创建子进程,是system_call 功能2。原形在include/linux/sys.h 中。
// 首先调用C 函数find_empty_process(),取得一个进程号pid。若返回负数则说明目前任务数组
// 已满。然后调用copy_process()复制进程。
align 4
_sys_fork:
	call _find_empty_process ;// 调用find_empty_process()(kernel/fork.c,135)。
	test eax,eax
	js l2
	push gs
	push esi
	push edi
	push ebp
	push eax
	call _copy_process ;// 调用C 函数copy_process()(kernel/fork.c,68)。
	add esp,20 ;// 丢弃这里所有压栈内容。
l2: ret

        (1)给当前要创建的进程分配一个进程号。find_empty_process

        (2)创建一个子进程的task_struct结构体:

struct task_struct *p;
p = (struct task_struct *)get_free_page();

struct task_struct *p;
p = (struct task_struct *)kmalloc(sizeof(task_struct));

        (3)将当前的子进程放入到整体进程链表当中

 task[nr] = p;

        (4)设置创建的task_struct结构体,如果当前进程使用了协处理器,那就设置当前创建进程的协处理器

if (last_task_used_math == current)
    	__asm__ ("frstor %0"::"m" (current->tss.i387));
int copy_mem(int nr, struct task_struct * p)

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

                如果父进程打开了某个文件,那么子进程也同样打开了这个文件,所以将文件的打开计数+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++;
if (current->executable)
    current->executable->i_count++;

                设置进程两个段 并且结合刚拷贝过来的 组装成一个进程

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

                给程序的状态标志为可运行状态

p->state = TASK_RUNNING; /*do this last, just in case*/

                 返回新创建进程的PID

return last_pid;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值