我曾经读过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
我顶,求内核专家。。
#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]
我感觉这个的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
你好!我只找到了任务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
感谢! 另外想问下你对linux线程模型熟悉吗,我想再开一贴问问关于linux线程模型的问题
#1
我顶,求内核专家。。
#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]
我感觉这个的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
你好!我只找到了任务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
感谢! 另外想问下你对linux线程模型熟悉吗,我想再开一贴问问关于linux线程模型的问题