进入kernel目录后 cd /init/main.c
start_kernel 是kernel函数c语言的其实函数。
kernel启动时有3个总要的线程函数:
Linux下有3个特殊的进程,idle进程(PID = 0), init进程(PID = 1)和kthreadd(PID = 2):
PID=0 系统自动创建、运行在内核态;
PID=1 由0进程创建,完成系统的初始化. 是系统中所有其它用户进程的祖先进程Linux中的所有进程都是有init进程创建并运行的。首先Linux内核启动,然后在用户空间中启动init进程,再启动其他系统进程。在系统启动完成完成后,init将变为守护进程监视系统其他进程;
PID=2 它的任务就是管理和调度其他内核线程kernel_thread, 会循环执行一个kthreadd的函数,该函数的作用就是运行kthread_create_list全局链表中维护的kthread, 当我们调用kernel_thread创建的内核线程会被加入到此链表中,因此所有的内核线程都是直接或者间接的以kthreadd为父进程。
总结:
kthreadd进程由idle通过kernel_thread创建,并始终运行在内核空间, 负责所有内核线程的调度和管理,它的任务就是管理和调度其他内核线程kernel_thread, 会循环执行一个kthreadd的函数,该函数的作用就是运行kthread_create_list全局链表中维护的kthread, 当我们调用kernel_thread创建的内核线程会被加入到此链表中,因此所有的内核线程都是直接或者间接的以kthreadd为父进程我们在内核中通过kernel_create或者其他方式创建一个内核线程, 然后kthreadd内核线程被唤醒, 来执行内核线程创建的真正工作,新的线程将执行kthread函数, 完成创建工作,创建完毕后让出CPU,因此新的内核线程不会立刻运行.需要手工 wake up, 被唤醒后将执行自己的真正工作函数。
任何一个内核线程入口都是 kthread()
通过 kthread_create() 创建的内核线程不会立刻运行.需要手工 wake up.
通过 kthread_create() 创建的内核线程有可能不会执行相应线程函数threadfn而直接退出
kernel_init()
功能:init=1号进程创建、内核驱动模块注册、启动默认控制台/dev/console
kernel_init_freeable()
功能:kernel_init_freeable主要功能是,等待内核线程创建完wait_for_completion(&kthreadd_done)、注册内核驱动模块do_basic_setup()、启动默认控制台/dev/console
do_basic_setup()
功能:初始化cpuset子系统、创建khelper线程队列、内核模块驱动注册
static void __init do_basic_setup(void)
{
cpuset_init_smp(); //初始化内核control group的cpuset子系统
usermodehelper_init();//创建khelper单线程工作队列,用于协助新建和运行用户空间程序
shmem_init(); //初始化共享内存
driver_init(); //驱动模块总线、文件系统注册,包括bus、devtmpfs、platform
init_irq_proc(); //创建/proc/irq目录, 并初始化系统中所有中断对应的子目录
do_ctors(); //执行内核的构造函数
usermodehelper_enable(); //使能usermodehelper
do_initcalls(); //调用level 0到level 7的initcall函数,依次的level名称是"early", "core", "postcore", "arch", "subsys", "fs", "device", “late”,需要注意的kernel在这块的命名有些问题,early_initcall对应的level小于0,pure_initcall对应level才是0
random_int_secret_init(); //初始化随机数生成池
}
void __init driver_init(void)
{
/* These are the core pieces */
devtmpfs_init();
devices_init();
buses_init();
classes_init();
firmware_init();
hypervisor_init();
/* These are also core pieces, but must come after the
* core core pieces.
*/
platform_bus_init(); //见此文分析:http://blog.csdn.net/xichangbao/article/details/52938240
cpu_dev_init();
memory_dev_init();
}
do_initcalls()路径
功能:初始化initcall_levels,完成编译进内核的驱动模块注册
static void __init do_initcalls(void)
{
int level;
for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
do_initcall_level(level);
}