kernel启动时几个函数的理解

进入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);
}

猜你喜欢

转载自blog.csdn.net/weixin_43836778/article/details/90199838
今日推荐