Linux系统中,所有进程都是进程PID为0的init进程的后代,内核在系统启动的最后阶段启动init进程。系统中每个进程必须有一个父进程,每个进程可以有零个或多个子进程。
1. 进程0是所有其他进程的祖先, 也称作idle进程或swapper进程。
2. 进程0是在系统初始化时由kernel自身从无到有创建。(过程集中在start_kernel函数内)
3. 进程0的数据成员大部分是静态定义的,即由预先定义好的(如上)INIT_TASK, INIT_MM等宏初始化。
进程0的描述符init_task定义在arch/arm/kernel/init_task.c,由INIT_TASK宏初始化。 init_mm等结构体定义在include/linux/init_task.h内,为init_task成员的初始值,分别由对应的初始化宏如INIT_MM等初始化(引用自:http://blog.csdn.net/hsly_support/article/details/8496575 )
这与OSE系统不同,OSE启动从执行start_OSE(启动OSE操作系统)函数,然后在odo_init_os函数中首先创建idle进程(PID为0),OSE系统中进程都是独立的,不是0进程的后代,OSE启动后,APP或中断进程才开始创建。但每个CPU上运行的所有进程(PCB+栈的内存)都是从同一个systemPool中分配。
<span style="font-size:14px;">\arch\i386\kernel\Init_task.c:
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/fs.h>
#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/desc.h>
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
/**
* init进程使用的内存结构
*/
struct mm_struct init_mm = INIT_MM(init_mm);
EXPORT_SYMBOL(init_mm);
/*
* Initial thread structure.
*
* We need to make sure that this is THREAD_SIZE aligned due to the
* way process stacks are handled. This is done by having a special
* "init_task" linker map entry..
*/
union thread_union init_thread_union
__attribute__((__section__(".data.init_task"))) =
{ <em>INIT_THREAD_INFO(init_task)</em> }; /*初始化init进程的thread_info*/
/*
* Initial task structure.
*
* All other task structs will be allocated on slabs in fork.c
*/
/**
* init进程的task_struct,INIT_TASK用于初始化init进程描述符。由内核静态创建,不通过fork
*/
struct task_struct init_task = INIT_TASK(init_task);</span>
INIT_THREAD_INFO(init_task)宏的作用是初始化init进程的thread_info,并将其放到.data.init_task数据段。
INIT_TASK(init_task):
</pre><pre name="code" class="cpp">/*
* INIT_TASK is used to set up the first task table, touch at
* your own risk!. Base=0, limit=0x1fffff (=2MB)
*/
/*
* INIT_TASK 用于设置第1 个任务表,若想修改,责任自负?!
* 基址Base = 0,段长limit = 0x1fffff(=2MB)。
*/
/**
* 初始化进程0的任务描述符。
*/
#define INIT_TASK(tsk) \
{ \
.state = 0, \
.thread_info = &init_thread_info, \
.stack = &init_thread_info, \
.usage = ATOMIC_INIT(2), \
.flags = 0, \
.lock_depth = -1, \
.prio = MAX_PRIO-20, \
.static_prio = MAX_PRIO-20, \
.policy = SCHED_NORMAL, \
.cpus_allowed = CPU_MASK_ALL, \
.mm = NULL, \
.active_mm = &init_mm, \
.run_list = LIST_HEAD_INIT(tsk.run_list), \
.time_slice = HZ, \
.tasks = LIST_HEAD_INIT(tsk.tasks), \
.ptrace_children= LIST_HEAD_INIT(tsk.ptrace_children), \
.ptrace_list = LIST_HEAD_INIT(tsk.ptrace_list), \
.real_parent = &tsk, \
.parent = &tsk, \
.children = LIST_HEAD_INIT(tsk.children), \
.sibling = LIST_HEAD_INIT(tsk.sibling), \
.group_leader = &tsk, \
.real_timer = { \
.function = it_real_fn \
}, \
.group_info = &init_groups, \
.cap_effective = CAP_INIT_EFF_SET, \
.cap_inheritable = CAP_INIT_INH_SET, \
.cap_permitted = CAP_FULL_SET, \
.keep_capabilities = 0, \
.user = INIT_USER, \
.comm = "swapper", \
.thread = INIT_THREAD, \
.fs = &init_fs, \
.files = &init_files, \
.signal = &init_signals, \
.sighand = &init_sighand, \
.pending = { \
.list = LIST_HEAD_INIT(tsk.pending.list), \
.signal = {{0}}}, \
.blocked = {{0}}, \
.alloc_lock = SPIN_LOCK_UNLOCKED, \
.proc_lock = SPIN_LOCK_UNLOCKED, \
.switch_lock = SPIN_LOCK_UNLOCKED, \
.journal_info = NULL, \
}