linux idle 进程(0号进程)的问题

时间:2022-11-20 15:48:40
根据资料,linux idle 进程是不通过folk()产生的系统第一个进程,也就是所谓的 “ 0号进程 ”。

我曾经读过linux0.11版本的内核源代码,在linux0.11中,也是有0号进程的概念,我记得在linux0.11中有个move_to_user_mode()宏,在main()函数中,当系统模块初始化完成后会调用这个宏,模拟中断返回,将整个启动代码放入到0号进程中继续执行。

但我发现在linux高版本的内核源代码中,貌似在启动过程中没有再调用这个move_to_user_mode()宏了,那么它现在是怎么做到切换到0号进程的呢?为什么删掉move_to_user_mode()这个过程呢

6 个解决方案

#1


我顶,求内核专家。。 linux idle 进程(0号进程)的问题

#2


以3.10内核为例,task 0 的进程结构(task_struct init_task)由INIT_TASK宏静态定义。该结构体(init_task)在linux启动时被设置为current_task。当初始化到rest_init函数中时,通过kernel_thread函数启动第一个内核线程kernel_init。kernel_init再通过do_execve启动/sbin/init。这就是我们看到的init进程,进程号为1。初始化的最后linux调用scheule()整个系统就运行起来了。

我感觉这个的task 0并不同于你说的linux 0.11的0号进程,因为它是一个kernel thread,并不包含运行在user space的代码。相反,task 1即init进程类似于你的0号进程,它运行user space代码。

UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  0    1 02:56 ?        00:00:01 /sbin/init
root         2     0     2  0    1 02:56 ?        00:00:00 [kthreadd]

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


static noinline void __init_refok rest_init(void)
{
        int pid;

        rcu_scheduler_starting();
        /*
         * We need to spawn init first so that it obtains pid 1, however
         * the init task will end up wanting to create kthreads, which, if
         * we schedule it before we create kthreadd, will OOPS.
         */
        kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);


static int __ref kernel_init(void *unused)
{
        kernel_init_freeable();
        /* need to finish all async __init code before freeing the memory */
        async_synchronize_full();
        free_initmem();
        mark_rodata_ro();
        system_state = SYSTEM_RUNNING;
        numa_default_policy();

        flush_delayed_fput();

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

        /*
         * 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) {
                if (!run_init_process(execute_command))
                        return 0;
                pr_err("Failed to execute %s.  Attempting defaults...\n",
                        execute_command);
        }
        if (!run_init_process("/sbin/init") ||

#3


平时你所听说的swapper进程,就是0号进程,其是内核的一部分,不执行磁盘上的任何程序。

#4


引用 2 楼 colddown 的回复:
以3.10内核为例,task 0 的进程结构(task_struct init_task)由INIT_TASK宏静态定义。 该结构体(init_task)在linux启动时被设置为current_task


你好!我只找到了任务0静态初始化task_struct的地方,请问具体是在哪里被设置为current_task呢?

#5


应该是定义在arch/x86/kernel/cpu/common.c

/*
 * The following four percpu variables are hot.  Align current_task to
 * cacheline size such that all four fall in the same cacheline.
 */
DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned =
        &init_task;
EXPORT_PER_CPU_SYMBOL(current_task);

#6


引用 5 楼 colddown 的回复:
应该是定义在arch/x86/kernel/cpu/common.c

/*
 * The following four percpu variables are hot.  Align current_task to
 * cacheline size such that all four fall in the same cacheline.
 */
DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned =
        &init_task;
EXPORT_PER_CPU_SYMBOL(current_task);

感谢! 另外想问下你对linux线程模型熟悉吗,我想再开一贴问问关于linux线程模型的问题

#1


我顶,求内核专家。。 linux idle 进程(0号进程)的问题

#2


以3.10内核为例,task 0 的进程结构(task_struct init_task)由INIT_TASK宏静态定义。该结构体(init_task)在linux启动时被设置为current_task。当初始化到rest_init函数中时,通过kernel_thread函数启动第一个内核线程kernel_init。kernel_init再通过do_execve启动/sbin/init。这就是我们看到的init进程,进程号为1。初始化的最后linux调用scheule()整个系统就运行起来了。

我感觉这个的task 0并不同于你说的linux 0.11的0号进程,因为它是一个kernel thread,并不包含运行在user space的代码。相反,task 1即init进程类似于你的0号进程,它运行user space代码。

UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  0    1 02:56 ?        00:00:01 /sbin/init
root         2     0     2  0    1 02:56 ?        00:00:00 [kthreadd]

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


static noinline void __init_refok rest_init(void)
{
        int pid;

        rcu_scheduler_starting();
        /*
         * We need to spawn init first so that it obtains pid 1, however
         * the init task will end up wanting to create kthreads, which, if
         * we schedule it before we create kthreadd, will OOPS.
         */
        kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);


static int __ref kernel_init(void *unused)
{
        kernel_init_freeable();
        /* need to finish all async __init code before freeing the memory */
        async_synchronize_full();
        free_initmem();
        mark_rodata_ro();
        system_state = SYSTEM_RUNNING;
        numa_default_policy();

        flush_delayed_fput();

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

        /*
         * 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) {
                if (!run_init_process(execute_command))
                        return 0;
                pr_err("Failed to execute %s.  Attempting defaults...\n",
                        execute_command);
        }
        if (!run_init_process("/sbin/init") ||

#3


平时你所听说的swapper进程,就是0号进程,其是内核的一部分,不执行磁盘上的任何程序。

#4


引用 2 楼 colddown 的回复:
以3.10内核为例,task 0 的进程结构(task_struct init_task)由INIT_TASK宏静态定义。 该结构体(init_task)在linux启动时被设置为current_task


你好!我只找到了任务0静态初始化task_struct的地方,请问具体是在哪里被设置为current_task呢?

#5


应该是定义在arch/x86/kernel/cpu/common.c

/*
 * The following four percpu variables are hot.  Align current_task to
 * cacheline size such that all four fall in the same cacheline.
 */
DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned =
        &init_task;
EXPORT_PER_CPU_SYMBOL(current_task);

#6


引用 5 楼 colddown 的回复:
应该是定义在arch/x86/kernel/cpu/common.c

/*
 * The following four percpu variables are hot.  Align current_task to
 * cacheline size such that all four fall in the same cacheline.
 */
DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned =
        &init_task;
EXPORT_PER_CPU_SYMBOL(current_task);

感谢! 另外想问下你对linux线程模型熟悉吗,我想再开一贴问问关于linux线程模型的问题