[Linux服务器] 【Linux内核解析】Linux内核启动过程和入口

14797 0
Honkers 2025-3-28 09:53:43 来自手机 | 显示全部楼层 |阅读模式

内核启动过程

1、内核启动过程是操作系统启动的第一步,也是整个操作系统的基础。在Linux内核中,内核启动的入口是arch/x86/boot/header.S文件中的startup_32函数,该函数是内核的启动代码入口点。

2、在启动过程中,内核首先会执行启动代码,进行一些基本的初始化操作,包括设置中断向量表、初始化全局描述符表(GDT)和中断描述符表(IDT)、建立内核页表等。然后,内核会在arch/x86/kernel/head_32.S文件中的startup_32函数中进行一些硬件初始化操作,如初始化CPU,设置中断处理程序,初始化内存控制器等。

3、接下来,内核会进入C语言代码,执行start_kernel函数,该函数是内核的主函数,负责初始化各个子系统和驱动程序。在start_kernel函数中,内核会完成以下操作:

初始化内核参数和全局变量:

  1. 初始化参数和全局变量:在内核启动过程中,会初始化一些内核参数和全局变量,例如内核命令行参数、系统时间、CPU信息、内存信息等。这些参数和变量的初始化是在内核启动代码中完成的。
复制代码

初始化系统调用和中断处理程序

  1. 初始化系统调用和中断处理程序:在内核启动过程中,会初始化系统调用和中断处理程序。系统调用是用户空间程序和内核之间进行交互的接口,中断处理程序是用于处理硬件中断的代码。系统调用和中断处理程序的初始化是在内核启动代码中完成的。
复制代码

初始化虚拟文件系统(VFS),包括注册文件系统和创建根文件系统

  1. 初始化虚拟文件系统(VFS):在内核启动过程中,会初始化VFS,包括注册文件系统和创建根文件系统。VFS是Linux内核中的一个重要子系统,用于管理文件系统和文件操作。VFS的初始化是在内核启动代码中完成的。
复制代码

初始化进程管理子系统,包括创建init进程和空闲进程

  1. 初始化进程管理子系统:在内核启动过程中,会初始化进程管理子系统,包括创建init进程和空闲进程。进程管理子系统是Linux内核中的一个重要子系统,用于管理进程和线程。进程管理子系统的初始化是在内核启动代码中完成的。
复制代码

初始化内存管理子系统,包括建立内存映射表、初始化物理内存管理器等

  1. 初始化内存管理子系统:在内核启动过程中,会初始化内存管理子系统,包括建立内存映射表、初始化物理内存管理器等。内存管理子系统是Linux内核中的一个重要子系统,用于管理内存。内存管理子系统的初始化是在内核启动代码中完成的。
复制代码

初始化设备驱动子系统,包括注册设备驱动程序、初始化设备等

  1. 初始化设备驱动子系统:在内核启动过程中,会初始化设备驱动子系统,包括注册设备驱动程序、初始化设备等。设备驱动子系统是Linux内核中的一个重要子系统,用于管理设备驱动程序和设备。设备驱动子系统的初始化是在内核启动代码中完成的。
复制代码

初始化网络子系统,包括初始化网络设备、协议栈等

  1. 初始化网络子系统:在内核启动过程中,会初始化网络子系统,包括初始化网络设备、协议栈等。网络子系统是Linux内核中的一个重要子系统,用于管理网络设备和协议栈。网络子系统的初始化是在内核启动代码中完成的
复制代码

启动用户空间进程,如init进程

  1. 启动用户空间进程:在内核启动过程中,会启动用户空间进程,如init进程。init进程是Linux系统中的第一个进程,负责启动其他进程和服务。启动用户空间进程的过程是在进程管理子系统的初始化函数中完成的
复制代码

在完成以上操作后,内核就可以进入正常的运行状态,等待用户的操作。需要注意的是,内核启动过程是一个复杂的过程,其中涉及到很多细节问题和硬件相关的操作,需要有一定的操作系统和计算机体系结构的基础知识才能深入理解。

入口代码解读

  1. asmlinkage __visible void __init __no_sanitize_address start_kernel(void)
  2. {
  3. char *command_line;
  4. char *after_dashes;
  5. set_task_stack_end_magic(&init_task);
  6. smp_setup_processor_id();
  7. debug_objects_early_init();
  8. init_vmlinux_build_id();
  9. cgroup_init_early();
  10. local_irq_disable();
  11. early_boot_irqs_disabled = true;
  12. /*
  13. * Interrupts are still disabled. Do necessary setups, then
  14. * enable them.
  15. */
  16. boot_cpu_init();
  17. page_address_init();
  18. pr_notice("%s", linux_banner);
  19. early_security_init();
  20. setup_arch(&command_line);
  21. setup_boot_config();
  22. setup_command_line(command_line);
  23. setup_nr_cpu_ids();
  24. setup_per_cpu_areas();
  25. smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
  26. boot_cpu_hotplug_init();
  27. build_all_zonelists(NULL);
  28. page_alloc_init();
  29. pr_notice("Kernel command line: %s\n", saved_command_line);
  30. /* parameters may set static keys */
  31. jump_label_init();
  32. parse_early_param();
  33. after_dashes = parse_args("Booting kernel",
  34. static_command_line, __start___param,
  35. __stop___param - __start___param,
  36. -1, -1, NULL, &unknown_bootoption);
  37. print_unknown_bootoptions();
  38. if (!IS_ERR_OR_NULL(after_dashes))
  39. parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
  40. NULL, set_init_arg);
  41. if (extra_init_args)
  42. parse_args("Setting extra init args", extra_init_args,
  43. NULL, 0, -1, -1, NULL, set_init_arg);
  44. /*
  45. * These use large bootmem allocations and must precede
  46. * kmem_cache_init()
  47. */
  48. setup_log_buf(0);
  49. vfs_caches_init_early();
  50. sort_main_extable();
  51. trap_init();
  52. mm_init();
  53. ftrace_init();
  54. /* trace_printk can be enabled here */
  55. early_trace_init();
  56. /*
  57. * Set up the scheduler prior starting any interrupts (such as the
  58. * timer interrupt). Full topology setup happens at smp_init()
  59. * time - but meanwhile we still have a functioning scheduler.
  60. */
  61. sched_init();
  62. if (WARN(!irqs_disabled(),
  63. "Interrupts were enabled *very* early, fixing it\n"))
  64. local_irq_disable();
  65. radix_tree_init();
  66. /*
  67. * Set up housekeeping before setting up workqueues to allow the unbound
  68. * workqueue to take non-housekeeping into account.
  69. */
  70. housekeeping_init();
  71. /*
  72. * Allow workqueue creation and work item queueing/cancelling
  73. * early. Work item execution depends on kthreads and starts after
  74. * workqueue_init().
  75. */
  76. workqueue_init_early();
  77. rcu_init();
  78. /* Trace events are available after this */
  79. trace_init();
  80. if (initcall_debug)
  81. initcall_debug_enable();
  82. context_tracking_init();
  83. /* init some links before init_ISA_irqs() */
  84. early_irq_init();
  85. init_IRQ();
  86. tick_init();
  87. rcu_init_nohz();
  88. init_timers();
  89. srcu_init();
  90. hrtimers_init();
  91. softirq_init();
  92. timekeeping_init();
  93. kfence_init();
  94. /*
  95. * For best initial stack canary entropy, prepare it after:
  96. * - setup_arch() for any UEFI RNG entropy and boot cmdline access
  97. * - timekeeping_init() for ktime entropy used in rand_initialize()
  98. * - rand_initialize() to get any arch-specific entropy like RDRAND
  99. * - add_latent_entropy() to get any latent entropy
  100. * - adding command line entropy
  101. */
  102. rand_initialize();
  103. add_latent_entropy();
  104. add_device_randomness(command_line, strlen(command_line));
  105. boot_init_stack_canary();
  106. time_init();
  107. perf_event_init();
  108. profile_init();
  109. call_function_init();
  110. WARN(!irqs_disabled(), "Interrupts were enabled early\n");
  111. early_boot_irqs_disabled = false;
  112. local_irq_enable();
  113. kmem_cache_init_late();
  114. /*
  115. * HACK ALERT! This is early. We're enabling the console before
  116. * we've done PCI setups etc, and console_init() must be aware of
  117. * this. But we do want output early, in case something goes wrong.
  118. */
  119. console_init();
  120. if (panic_later)
  121. panic("Too many boot %s vars at `%s'", panic_later,
  122. panic_param);
  123. lockdep_init();
  124. /*
  125. * Need to run this when irqs are enabled, because it wants
  126. * to self-test [hard/soft]-irqs on/off lock inversion bugs
  127. * too:
  128. */
  129. locking_selftest();
  130. /*
  131. * This needs to be called before any devices perform DMA
  132. * operations that might use the SWIOTLB bounce buffers. It will
  133. * mark the bounce buffers as decrypted so that their usage will
  134. * not cause "plain-text" data to be decrypted when accessed.
  135. */
  136. mem_encrypt_init();
  137. #ifdef CONFIG_BLK_DEV_INITRD
  138. if (initrd_start && !initrd_below_start_ok &&
  139. page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
  140. pr_crit("initrd overwritten (0x%08lx < 0x%08lx) - disabling it.\n",
  141. page_to_pfn(virt_to_page((void *)initrd_start)),
  142. min_low_pfn);
  143. initrd_start = 0;
  144. }
  145. #endif
  146. setup_per_cpu_pageset();
  147. numa_policy_init();
  148. acpi_early_init();
  149. if (late_time_init)
  150. late_time_init();
  151. sched_clock_init();
  152. calibrate_delay();
  153. pid_idr_init();
  154. anon_vma_init();
  155. #ifdef CONFIG_X86
  156. if (efi_enabled(EFI_RUNTIME_SERVICES))
  157. efi_enter_virtual_mode();
  158. #endif
  159. thread_stack_cache_init();
  160. cred_init();
  161. fork_init();
  162. proc_caches_init();
  163. uts_ns_init();
  164. key_init();
  165. security_init();
  166. dbg_late_init();
  167. vfs_caches_init();
  168. pagecache_init();
  169. signals_init();
  170. seq_file_init();
  171. proc_root_init();
  172. nsfs_init();
  173. cpuset_init();
  174. cgroup_init();
  175. taskstats_init_early();
  176. delayacct_init();
  177. poking_init();
  178. check_bugs();
  179. acpi_subsystem_init();
  180. arch_post_acpi_subsys_init();
  181. kcsan_init();
  182. /* Do the rest non-__init'ed, we're now alive */
  183. arch_call_rest_init();
  184. prevent_tail_call_optimization();
  185. }
复制代码
  1. 1. `set_task_stack_end_magic(&init_task)`:设置任务栈结束的魔数。
  2. 2. `smp_setup_processor_id()`:设置处理器ID。
  3. 3. `debug_objects_early_init()`:初始化调试对象,用于调试内核代码。
  4. 4. `init_vmlinux_build_id()`:初始化内核版本号。
  5. 5. `cgroup_init_early()`:初始化控制组子系统。
  6. 6. `local_irq_disable()`:禁止本地中断。
  7. 7. `early_boot_irqs_disabled = true`:设置早期启动中断为禁用状态。
  8. 8. `boot_cpu_init()`:初始化启动CPU。
  9. 9. `page_address_init()`:初始化页面地址。
  10. 10. `pr_notice("%s", linux_banner)`:打印内核版本信息。
  11. 11. `early_security_init()`:初始化安全子系统。
  12. 12. `setup_arch(&command_line)`:设置架构。
  13. 13. `setup_boot_config()`:设置引导配置。
  14. 14. `setup_command_line(command_line)`:设置命令行参数。
  15. 15. `setup_nr_cpu_ids()`:设置CPU数量。
  16. 16. `setup_per_cpu_areas()`:设置每个CPU的私有数据。
  17. 17. `smp_prepare_boot_cpu()`:为启动CPU准备SMP。
  18. 18. `boot_cpu_hotplug_init()`:初始化热插拔CPU。
  19. 19. `build_all_zonelists(NULL)`:构建内存区域列表。
  20. 20. `page_alloc_init()`:初始化页面分配器。
  21. 21. `pr_notice("Kernel command line: %s\n", saved_command_line)`:打印内核命令行。
  22. 22. `jump_label_init()`:初始化跳转标签。
  23. 23. `parse_early_param()`:解析早期参数。
  24. 24. `after_dashes = parse_args("Booting kernel", static_command_line, __start___param, __stop___param - __start___param, -1, -1, NULL, &unknown_bootoption)`:解析命令行参数。
  25. 25. `print_unknown_bootoptions()`:打印未知的引导选项。
  26. 26. `parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, NULL, set_init_arg)`:解析命令行参数。
  27. 27. `parse_args("Setting extra init args", extra_init_args, NULL, 0, -1, -1, NULL, set_init_arg)`:解析额外的命令行参数。
  28. 28. `setup_log_buf(0)`:设置日志缓冲区。
  29. 29. `vfs_caches_init_early()`:初始化VFS缓存。
  30. 30. `sort_main_extable()`:排序异常表格。
  31. 31. `trap_init()`:初始化陷阱处理程序。
  32. 32. `mm_init()`:初始化内存管理器。
  33. 33. `ftrace_init()`:初始化函数跟踪。
  34. 34. `early_trace_init()`:初始化跟踪日志。
  35. 35. `sched_init()`:初始化调度器。
  36. 36. `radix_tree_init()`:初始化基数树。
  37. 37. `housekeeping_init()`:初始化系统维护。
  38. 38. `workqueue_init_early()`:初始化工作队列。
  39. 39. `rcu_init()`:初始化RCU。
  40. 40. `trace_init()`:初始化跟踪事件。
  41. 41. `initcall_debug_enable()`:启用初始化调试。
  42. 42. `context_tracking_init()`:初始化上下文跟踪。
  43. 43. `early_irq_init()`:初始化早期中断。
  44. 44. `init_IRQ()`:初始化中断处理程序。
  45. 45. `tick_init()`:初始化定时器中断。
  46. 46. `rcu_init_nohz()`:初始化RCU中的无中断模式。
  47. 47. `init_timers()`:初始化定时器。
  48. 48. `srcu_init()`:初始化SRCU。
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2026 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行