上QQ阅读APP看书,第一时间看更新
1.3.2 C语言部分
内核初始化的C语言部分入口是函数start_kernel,函数start_kernel首先初始化基础设施,即初始化内核的各个子系统,然后调用函数rest_init。函数rest_init的执行流程如下。
(1)创建1号线程,即init线程,线程函数是kernel_init。
(2)创建2号线程,即kthreadd线程,负责创建内核线程。
(3)0号线程最终变成空闲线程。
init线程继续初始化,执行的主要操作如下。
(1)smp_prepare_cpus():在启动从处理器以前执行准备工作。
(2)do_pre_smp_initcalls():执行必须在初始化SMP系统以前执行的早期初始化,即使用宏early_initcall注册的初始化函数。
(3)smp_init():初始化SMP系统,启动所有从处理器。
(4)do_initcalls():执行级别0~7的初始化。
(5)打开控制台的字符设备文件“/dev/console”,文件描述符0、1和2分别是标准输入、标准输出和标准错误,都是控制台的字符设备文件。
(6)prepare_namespace():挂载根文件系统,后面装载init程序时需要从存储设备上的文件系统中读文件。
(7)free_initmem():释放初始化代码和数据占用的内存。
(8)装载init程序(U-Boot程序可以传递内核参数“init=”以指定init程序),从内核线程转换成用户空间的init进程。
级别0~7的初始化,是指使用以下宏注册的初始化函数:
include/linux/init.h
#define pure_initcall(fn) __define_initcall(fn, 0)
#define core_initcall(fn) __define_initcall(fn, 1)
#define core_initcall_sync(fn) __define_initcall(fn, 1s)
#define postcore_initcall(fn) __define_initcall(fn, 2)
#define postcore_initcall_sync(fn) __define_initcall(fn, 2s)
#define arch_initcall(fn) __define_initcall(fn, 3)
#define arch_initcall_sync(fn) __define_initcall(fn, 3s)
#define subsys_initcall(fn) __define_initcall(fn, 4)
#define subsys_initcall_sync(fn) __define_initcall(fn, 4s)
#define fs_initcall(fn) __define_initcall(fn, 5)
#define fs_initcall_sync(fn) __define_initcall(fn, 5s)
#define rootfs_initcall(fn) __define_initcall(fn, rootfs)
#define device_initcall(fn) __define_initcall(fn, 6)
#define device_initcall_sync(fn) __define_initcall(fn, 6s)
#define late_initcall(fn) __define_initcall(fn, 7)
#define late_initcall_sync(fn) __define_initcall(fn, 7s)