微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在Linux内核中启动init进程?

我试图了解 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()调用相同.

原文地址:https://www.jb51.cc/linux/393267.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐