深圳网站seo优化,网站预订系统建设,大连哪里做网站,公司网络组建工作方案一、参考
linux — 0号进程#xff0c;1号进程#xff0c;2号进程 - 流水灯 - 博客园 (cnblogs.com)
Linux0号进程#xff0c;1号进程#xff0c;2号进程_0号进程和1号进程-CSDN博客
二、idle进程的创建流程
start_kernel -- arch_call_rest_init -- rest_init…一、参考
linux — 0号进程1号进程2号进程 - 流水灯 - 博客园 (cnblogs.com)
Linux0号进程1号进程2号进程_0号进程和1号进程-CSDN博客
二、idle进程的创建流程
start_kernel -- arch_call_rest_init -- rest_init-- cpu_startup_entry -- while(1) { do_idle(); }start_kernel 函数在完成系统初始化后会进入死循环调用 do_idle 函数相当于 start_kernel 函数完成初始化后会退化成 idle 进程。
三、idle 进程控制块
idle 进程控制块是 init_taskinit_task 是一个全局静态变量定义在 init/init_task.c 文件中。
/** Set up the first task table, touch at your own risk!. Base0,* limit0x1fffff (2MB)*/
struct task_struct init_task
#ifdef CONFIG_ARCH_TASK_STRUCT_ON_STACK__init_task_data
#endif__aligned(L1_CACHE_BYTES){
#ifdef CONFIG_THREAD_INFO_IN_TASK.thread_info INIT_THREAD_INFO(init_task),.stack_refcount REFCOUNT_INIT(1),
#endif.__state 0,.stack init_stack, // init_stack 值定义在链接脚本中init_stack是内核栈的静态的定义.usage REFCOUNT_INIT(2),.flags PF_KTHREAD,.prio MAX_PRIO - 20,.static_prio MAX_PRIO - 20,.normal_prio MAX_PRIO - 20,.policy SCHED_NORMAL,.cpus_ptr init_task.cpus_mask,.user_cpus_ptr NULL,.cpus_mask 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(init_task.se.group_node),},.rt {.run_list LIST_HEAD_INIT(init_task.rt.run_list),.time_slice RR_TIMESLICE,},.tasks LIST_HEAD_INIT(init_task.tasks),
#ifdef CONFIG_SMP.pushable_tasks PLIST_NODE_INIT(init_task.pushable_tasks, MAX_PRIO),
#endif
#ifdef CONFIG_CGROUP_SCHED.sched_task_group root_task_group,
#endif.ptraced LIST_HEAD_INIT(init_task.ptraced),.ptrace_entry LIST_HEAD_INIT(init_task.ptrace_entry),.real_parent init_task,.parent init_task,.children LIST_HEAD_INIT(init_task.children),.sibling LIST_HEAD_INIT(init_task.sibling),.group_leader init_task,RCU_POINTER_INITIALIZER(real_cred, init_cred),RCU_POINTER_INITIALIZER(cred, init_cred),.comm INIT_TASK_COMM, // #define INIT_TASK_COMM swapper - 0号进程的名称.thread INIT_THREAD,.fs init_fs,.files init_files,
#ifdef CONFIG_IO_URING.io_uring NULL,
#endif.signal init_signals,.sighand init_sighand,.nsproxy init_nsproxy,.pending {.list LIST_HEAD_INIT(init_task.pending.list),.signal {{0}}},.blocked {{0}},.alloc_lock __SPIN_LOCK_UNLOCKED(init_task.alloc_lock),.journal_info NULL,INIT_CPU_TIMERS(init_task).pi_lock __RAW_SPIN_LOCK_UNLOCKED(init_task.pi_lock),.timer_slack_ns 50000, /* 50 usec default slack */.thread_pid init_struct_pid,.thread_group LIST_HEAD_INIT(init_task.thread_group),.thread_node LIST_HEAD_INIT(init_signals.thread_head),
#ifdef CONFIG_AUDIT.loginuid INVALID_UID,.sessionid AUDIT_SID_UNSET,
#endif
#ifdef CONFIG_PERF_EVENTS.perf_event_mutex __MUTEX_INITIALIZER(init_task.perf_event_mutex),.perf_event_list LIST_HEAD_INIT(init_task.perf_event_list),
#endif
#ifdef CONFIG_PREEMPT_RCU.rcu_read_lock_nesting 0,.rcu_read_unlock_special.s 0,.rcu_node_entry LIST_HEAD_INIT(init_task.rcu_node_entry),.rcu_blocked_node NULL,
#endif
#ifdef CONFIG_TASKS_RCU.rcu_tasks_holdout false,.rcu_tasks_holdout_list LIST_HEAD_INIT(init_task.rcu_tasks_holdout_list),.rcu_tasks_idle_cpu -1,
#endif
#ifdef CONFIG_TASKS_TRACE_RCU.trc_reader_nesting 0,.trc_reader_special.s 0,.trc_holdout_list LIST_HEAD_INIT(init_task.trc_holdout_list),.trc_blkd_node LIST_HEAD_INIT(init_task.trc_blkd_node),
#endif
#ifdef CONFIG_CPUSETS.mems_allowed_seq SEQCNT_SPINLOCK_ZERO(init_task.mems_allowed_seq,init_task.alloc_lock),
#endif
#ifdef CONFIG_RT_MUTEXES.pi_waiters RB_ROOT_CACHED,.pi_top_task NULL,
#endifINIT_PREV_CPUTIME(init_task)
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN.vtime.seqcount SEQCNT_ZERO(init_task.vtime_seqcount),.vtime.starttime 0,.vtime.state VTIME_SYS,
#endif
#ifdef CONFIG_NUMA_BALANCING.numa_preferred_nid NUMA_NO_NODE,.numa_group NULL,.numa_faults NULL,
#endif
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS).kasan_depth 1,
#endif
#ifdef CONFIG_KCSAN.kcsan_ctx {.scoped_accesses {LIST_POISON1, NULL},},
#endif
#ifdef CONFIG_TRACE_IRQFLAGS.softirqs_enabled 1,
#endif
#ifdef CONFIG_LOCKDEP.lockdep_depth 0, /* no locks held yet */.curr_chain_key INITIAL_CHAIN_KEY,.lockdep_recursion 0,
#endif
#ifdef CONFIG_FUNCTION_GRAPH_TRACER.ret_stack NULL,.tracing_graph_pause ATOMIC_INIT(0),
#endif
#if defined(CONFIG_TRACING) defined(CONFIG_PREEMPTION).trace_recursion 0,
#endif
#ifdef CONFIG_LIVEPATCH.patch_state KLP_UNDEFINED,
#endif
#ifdef CONFIG_SECURITY.security NULL,
#endif
#ifdef CONFIG_SECCOMP_FILTER.seccomp { .filter_count ATOMIC_INIT(0) },
#endif
};
EXPORT_SYMBOL(init_task);四、源码分析
1、设置0号进程PCB
/* 代码位置: /arch/arm64/kernel/head.S *//** Initialize CPU registers with task-specific and cpu-specific context.** Create a final frame record at task_pt_regs(current)-stackframe, so* that the unwinder can identify the final frame record of any task by* its location in the task stack. We reserve the entire pt_regs space* for consistency with user tasks and kthreads.*/.macro init_cpu_task tsk, tmp1, tmp2msr sp_el0, \tskldr \tmp1, [\tsk, #TSK_STACK]add sp, \tmp1, #THREAD_SIZEsub sp, sp, #PT_REGS_SIZEstp xzr, xzr, [sp, #S_STACKFRAME]add x29, sp, #S_STACKFRAMEscs_load_currentadr_l \tmp1, __per_cpu_offsetldr w\tmp2, [\tsk, #TSK_TI_CPU]ldr \tmp1, [\tmp1, \tmp2, lsl #3]set_this_cpu_offset \tmp1.endm/** The following fragment of code is executed with the MMU enabled.** x0 __pa(KERNEL_START)*/
SYM_FUNC_START_LOCAL(__primary_switched)adr_l x4, init_taskinit_cpu_task x4, x5, x6……bl start_kernelASM_BUG()
SYM_FUNC_END(__primary_switched)在 __primary_switched 函数中将 init_task 值保存到 sp_el0 寄存器中然后调用 start_kernel 函数。至此成功将 init_task 设置成 0 号进程的进程控制块并成功运行 0 号进程。
2、设置栈底魔数
置栈底魔数用于栈溢出检查。
/* 函数定义在 /init/main.c 中 */asmlinkage __visible void __init __no_sanitize_address __noreturn start_kernel(void)
{char *command_line;char *after_dashes;set_task_stack_end_magic(init_task);……
}3、其他配置
详细配置见 Linux 源码。
五、获取当前PCB
/* 函数定义在 arch/arm64/include/asm/current.h 文件中 *//** We dont use read_sysreg() as we want the compiler to cache the value where* possible.*/
static __always_inline struct task_struct *get_current(void)
{unsigned long sp_el0;asm (mrs %0, sp_el0 : r (sp_el0));return (struct task_struct *)sp_el0;
}#define current get_current()