您的位置:首页 > 运维架构 > Linux

linux进程创造 - 内核进程初始化及创建

2016-11-27 17:51 459 查看

1. 内核进程初始化

1.1 idle/swapper进程 - (pid:0)

内核的第一个进程叫idle进程或者swapper进程,这是初始化阶段从无到有创建的第一个内核进程,每个cpu都有一个进程0,当内核中没有其他进程运行时,就会调用该进程使得cpu处于idle状态,进程描述符为init_task,如下:

(init/init_task.c)

struct task_struct init_task = INIT_TASK(init_task);


(include/linux/init_task.h)

#define INIT_TASK(tsk)  \
{                                   \
.state      = 0,                        \
.stack      = &init_thread_info,                \
.usage      = ATOMIC_INIT(2),               \
.flags      = PF_KTHREAD,                   \
.prio       = MAX_PRIO-20,                  \
.static_prio    = MAX_PRIO-20,                  \
.normal_prio    = MAX_PRIO-20,                  \
.policy     = SCHED_NORMAL,                 \
.cpus_allowed   = CPU_MASK_ALL,                 \
.nr_cpus_allowed= NR_CPUS,                  \
.mm     = NULL,                     \
.active_mm  = &init_mm,                 \
.restart_block = {                      \
.fn = do_no_restart_syscall,                \
},                              \
.se     = {                     \
.group_node     = LIST_HEAD_INIT(tsk.se.group_node),    \
},                              \
.rt     = {                     \
.run_list   = LIST_HEAD_INIT(tsk.rt.run_list),  \
.time_slice = RR_TIMESLICE,             \
},                              \
.tasks      = LIST_HEAD_INIT(tsk.tasks),            \
INIT_PUSHABLE_TASKS(tsk)                    \
INIT_CGROUP_SCHED(tsk)                      \
.ptraced    = LIST_HEAD_INIT(tsk.ptraced),          \
.ptrace_entry   = LIST_HEAD_INIT(tsk.ptrace_entry),     \
.real_parent    = &tsk,                     \
.parent     = &tsk,                     \
.children   = LIST_HEAD_INIT(tsk.children),         \
.sibling    = LIST_HEAD_INIT(tsk.sibling),          \
.group_leader   = &tsk,                     \
RCU_POINTER_INITIALIZER(real_cred, &init_cred),         \
RCU_POINTER_INITIALIZER(cred, &init_cred),          \
.comm       = INIT_TASK_COMM,               \
.thread     = INIT_THREAD,                  \
.fs     = &init_fs,                 \
.files      = &init_files,                  \
.signal     = &init_signals,                \
.sighand    = &init_sighand,                \
.nsproxy    = &init_nsproxy,                \
.pending    = {                     \
.list = LIST_HEAD_INIT(tsk.pending.list),       \
.signal = {{0}}},                   \
.blocked    = {{0}},                    \
.alloc_lock = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock),     \
.journal_info   = NULL,                     \
.cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers),      \
.pi_lock    = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock),    \
.timer_slack_ns = 50000, /* 50 usec default slack */        \
.pids = {                           \
[PIDTYPE_PID]  = INIT_PID_LINK(PIDTYPE_PID),        \
[PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID),       \
[PIDTYPE_SID]  = INIT_PID_LINK(PIDTYPE_SID),        \
},                              \
.thread_group   = LIST_HEAD_INIT(tsk.thread_group),     \
.thread_node    = LIST_HEAD_INIT(init_signals.thread_head), \
INIT_IDS                            \
INIT_PERF_EVENTS(tsk)                       \
INIT_TRACE_IRQFLAGS                     \
INIT_LOCKDEP                            \
INIT_FTRACE_GRAPH                       \
INIT_TRACE_RECURSION                        \
INIT_TASK_RCU_PREEMPT(tsk)                  \
INIT_TASK_RCU_TASKS(tsk)                    \
INIT_CPUSET_SEQ(tsk)                        \
INIT_RT_MUTEXES(tsk)                        \
INIT_PREV_CPUTIME(tsk)                      \
INIT_VTIME(tsk)                         \
INIT_NUMA_BALANCING(tsk)                    \
INIT_KASAN(tsk)                         \
}


1.2 init进程 - (pid:1)

init进程主要创建和监控其他运行进程的活动,它由进程0创建,并执行系统调用execve()装入可执行程序init。

内核进程init执行的函数为kernel_init

static int __ref kernel_init(void *unused)
{
int ret;

kernel_init_freeable();
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();
free_initmem();
mark_readonly();
system_state = SYSTEM_RUNNING;
numa_default_policy();

flush_delayed_fput();

rcu_end_inkernel_boot();

if (ramdisk_execute_command) {
ret = run_init_process(ramdisk_execute_command);
if (!ret)
return 0;
pr_err("Failed to execute %s (error %d)\n",
ramdisk_execute_command, ret);
}

/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
if (execute_command) {
ret = run_init_process(execute_command);
if (!ret)
return 0;
panic("Requested init %s failed (error %d).",
execute_command, ret);
}
if (!try_to_run_init_process("/sbin/init") ||
!try_to_run_init_process("/etc/init") ||
!try_to_run_init_process("/bin/init") ||
!try_to_run_init_process("/bin/sh"))
return 0;

panic("No working init found.  Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}


1.3 初始化

在init/main.c的start_kernel函数中执行内核进程的初始化



2. 内核进程创建

创建内核进程调用函数kernel_thread

(kernel/fork.c)

pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
return _do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,
(unsigned long)arg, NULL, NULL, 0);
}


change log

datecontentlinux
2016.11.27初创linux4.6.3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: