根文件系统的启动

mac2024-05-25  33

目录

三个特殊进程

0号进程的产生

内核init进程的产生

内核init进程的作用

用户空间init进程作用


三个特殊进程

Linux下有3个特殊的进程,idle进程(PID = 0), init进程(PID = 1)和kthreadd(PID = 2)

* idle进程由系统自动创建, 运行在内核态          idle进程其pid=0,其前身是系统创建的第一个进程,也是唯一一个没有通过fork或者kernel_thread产生的进程。完成加载系统后,演变为进程调度、交换。

* init进程由idle通过kernel_thread创建,在内核空间完成初始化后, 加载init程序, 并最终用户空间          由0进程创建,完成系统的初始化. 是系统中所有其它用户进程的祖先进程          Linux中的所有进程都是有init进程创建并运行的。首先Linux内核启动,然后在用户空间中启动init进程,再启动其他系统进程。在系统启动完成完成后,init将变为守护进程监视系统其他进程。

* kthreadd进程由idle通过kernel_thread创建,并始终运行在内核空间, 负责所有内核线程的调度和管理          它的任务就是管理和调度其他内核线程kernel_thread, 会循环执行一个kthread的函数,该函数的作用就是运行kthread_create_list全局链表中维护的kthread, 当我们调用kernel_thread创建的内核线程会被加入到此链表中,因此所有的内核线程都是直接或者间接的以kthreadd为父进程 

0号进程的产生

参考网址:Linux下0号进程的前世(init_task进程)今生(idle进程)

         内核中init_task变量就是是进程0使用的进程描述符,也是Linux系统中第一个进程描述符,init_task并不是系统通过kernel_thread的方式(当然更不可能是fork)创建的, 而是由内核黑客静态创建的.

        初始化位置:init/init_task.c

/* Initial task structure */ struct task_struct init_task = INIT_TASK(init_task); EXPORT_SYMBOL(init_task);

内核init进程的产生

参考网址:Linux下0号进程的前世(init_task进程)今生(idle进程)

rest_init      //init/main.c         kernel_thread(kernel_init, NULL, CLONE_FS);         pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);

说明:这个函数其实是由0号进程执行的, 他就是在这个函数中, 创建了init进程和kthreadd进程。

内核init进程的作用

参考网址:Linux下1号进程的前世(kernel_init)今生(init进程)

源码

kernel_init     //init/main.c     ...

    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.ramdisk_execute_command和execute_command     ramdisk_execute_command对应uboot的bootargs的"rdinit=...",execute_command对应uboot的bootargs的"init=..."。     一般不使用这两个。      2.依次查找init     rdinit=..., init=, /sbin/init, /etc/init, /bin/init/, /bin/sh会依次查找,只要有一个执行成功就会返回,下边的都不会执行。     如果上述都没有找到或者一个都没执行成功,则进入Kernel Panic,如下所示:     panic(“No init found. Try passing init= option to kernel. ”“See Linux Documentation/init.txt for guidance.”);

用户空间init进程作用

参考网址:linux启动分析——init进程与app启动

概述

        内核init进程成功执行上边的一个init之后,内核init进程就转化为了用户空间的init进程。         一般情况下,执行的是/sbin/init。         /sbin/init读/etc/inittab文件并运行里边的项,/etc/inittab里边一般有“::sysinit:/etc/init.d/rcS”,这条语句会首先执行。

源码位置

busybox/init/init.c

# ls -l /sbin/init lrwxrwxrwx    1 root     root            14 Aug 27  2019 /sbin/init -> ../bin/busybox

可见最终执行的是busybox。

        busybox的配置项FEATURE_USE_INITTAB决定是否读取/etc/inittab文件,如果没有配置,则不读取,执行默认的操作。    默认情况下FEATURE_USE_INITTAB配置为y

/etc/init.d/rcS的一般套路

挂载proc,sysfs,ramfs文件系统 配置网络 启动app     

最新回复(0)