🤣内核初始化(C) - 图1

🎈start_kernel

内核初始化的 C 语言部分入口是函数 start_kernel:

  1. 函数 start_kernel 首先初始化基础设施,即初始化内核的各个子系统
  2. 然后调用函数 rest_init

    🎇rest_init

    rest_init 函数的执行流程如下:

  3. 创建 1 号线程,即 init 线程,线程函数是 kernel_init,该进程在初始化完成后将转为用户态,成为用户态的跟进程

  4. 创建 2 号线程,即 kthreadd 线程,负责创建内核线程
  5. 0 号线程最终变成空闲线程

    ✨init 线程

    init 线程继续初始化,执行的主要操作如下:

  6. smp_prepare_cpus():在启动从处理器以前执行准备工作

  7. do_pre_smp_initcalls():执行必须在初始化 SMP 系统以前执行的早期初始化,即使用宏 early_initcall 注册的初始化函数
  8. smp_init():初始化 SMP 系统,启动所有从处理器
  9. do_initcalls():执行级别 0~7 的初始化
  10. 打开控制台的字符设备文件“/dev/console”,文件描述符 0、1 和 2 分别是标准输入、标准输出和标准错误,都是控制台的字符设备文件
  11. prepare_namespace():挂载根文件系统,后面装载 init 程序时需要从存储设备上的文件系统中读文件
  12. free_initmem():释放初始化代码和数据占用的内存
  13. 装载 init 程序(U-Boot 程序可以传递内核参数“init=”以指定 init 程序),从内核线程转换成用户空间的 init 进程

级别 0~7 的初始化,是指使用以下宏注册的初始化函数:

  1. #define core_initcall(fn) __define_initcall(fn, 1)
  2. #define core_initcall_sync(fn) __define_initcall(fn, 1s)
  3. #define postcore_initcall(fn) __define_initcall(fn, 2)
  4. #define postcore_initcall_sync(fn) __define_initcall(fn, 2s)
  5. #define arch_initcall(fn) __define_initcall(fn, 3)
  6. #define arch_initcall_sync(fn) __define_initcall(fn, 3s)
  7. #define subsys_initcall(fn) __define_initcall(fn, 4)
  8. #define subsys_initcall_sync(fn) __define_initcall(fn, 4s)
  9. #define fs_initcall(fn) __define_initcall(fn, 5)
  10. #define fs_initcall_sync(fn) __define_initcall(fn, 5s)
  11. #define rootfs_initcall(fn) __define_initcall(fn, rootfs)
  12. #define device_initcall(fn) __define_initcall(fn, 6)
  13. #define device_initcall_sync(fn) __define_initcall(fn, 6s)
  14. #define late_initcall(fn) __define_initcall(fn, 7)
  15. #define late_initcall_sync(fn) __define_initcall(fn, 7s)