我试图了解
linux内核中的init进程,这是第一个进程,并使用INIT_TASK宏进行静态初始化.
161 #define INIT_TASK(tsk) \
162 { \
163 .state = 0,\
164 .stack = &init_thread_info,\
165 .usage = ATOMIC_INIT(2),\
166 .flags = PF_KTHREAD,\
167 .prio = MAX_PRIO-20,\
168 .static_prio = MAX_PRIO-20,\
169 .normal_prio = MAX_PRIO-20,\
170 .policy = SCHED_NORMAL,\
171 .cpus_allowed = CPU_MASK_ALL,\
172 .nr_cpus_allowed= NR_CPUS,\
173 .mm = NULL,\
174 .active_mm = &init_mm,\
175 .se = { \
176 .group_node = LIST_HEAD_INIT(tsk.se.group_node),\
177 },\
178 .rt = { \
179 .run_list = LIST_HEAD_INIT(tsk.rt.run_list),\
180 .time_slice = RR_TIMESLICE,\
181 },\
182 .tasks = LIST_HEAD_INIT(tsk.tasks),\
183 INIT_PUSHABLE_TASKS(tsk) \
184 INIT_CGROUP_SCHED(tsk) \
185 .ptraced = LIST_HEAD_INIT(tsk.ptraced),\
186 .ptrace_entry = LIST_HEAD_INIT(tsk.ptrace_entry),\
187 .real_parent = &tsk,\
188 .parent = &tsk,\
189 .children = LIST_HEAD_INIT(tsk.children),\
190 .sibling = LIST_HEAD_INIT(tsk.sibling),\
191 .group_leader = &tsk,\
192 RCU_POINTER_INITIALIZER(real_cred,&init_cred),\
193 RCU_POINTER_INITIALIZER(cred,\
194 .comm = INIT_TASK_COMM,\
195 .thread = INIT_THREAD,\
196 .fs = &init_fs,\
197 .files = &init_files,\
198 .signal = &init_signals,\
199 .sighand = &init_sighand,\
200 .nsproxy = &init_nsproxy,\
201 .pending = { \
202 .list = LIST_HEAD_INIT(tsk.pending.list),\
203 .signal = {{0}}},\
204 .blocked = {{0}},\
205 .alloc_lock = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock),\
206 .journal_info = NULL,\
207 .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers),\
208 .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock),\
209 .timer_slack_ns = 50000,/* 50 usec default slack */ \
210 .pids = { \
211 [PIDTYPE_PID] = INIT_PID_LINK(PIDTYPE_PID),\
212 [PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID),\
213 [PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID),\
214 },\
215 .thread_group = LIST_HEAD_INIT(tsk.thread_group),\
216 INIT_IDS \
217 INIT_PERF_EVENTS(tsk) \
218 INIT_TRACE_IRQFLAGS \
219 INIT_LOCKDEP \
220 INIT_FTRACE_GRAPH \
221 INIT_TRACE_RECURSION \
222 INIT_TASK_RCU_PREEMPT(tsk) \
223 INIT_CPUSET_SEQ \
224 INIT_VTIME(tsk) \
225 }
但我无法弄明白
>它将如何执行?
>预定的地点和
>当我们说我们已经安排了这个init_task任务时,linux内核中的哪些代码行会立即开始执行?它有什么功能吗?
解决方法
内核调用“init”作为内核初始化过程中最后的事情之一. init / main.c中的函数
kernel_init()具有逻辑.
您会注意到内核尝试了四种不同的init组合,并期望其中一种成功.您还会注意到,您可以通过提供内核命令行参数“init”来覆盖内核在启动时执行的操作.因此,您可以在内核命令行中说出init = / bin / mystartup,并启动您自己的自定义应用程序而不是默认的/ sbin / init.另请注意,在大多数现代系统中,即使是嵌入式系统,/ sbin / init也是指向真实可执行文件的软链接.
为了更一般地回答你的问题,研究这个源文件(main.c)你可以看到几乎所有Linux内核初始化的细节,在低级程序集和平台初始化之后,这超出了教育价值,你不应该’不得不接触或关心.
主要机制是用fixed arguments of argv_init and envp_init调用do_execve().解析elf文件并根据文件设置初始程序计数器(PC).所有内存管理(mm)页面都映射到磁盘后备存储.代码设置为运行.在计划的初始PC提取时,会生成页面错误,将第一个代码页读入内存.这与任何其他execve()调用相同.
