在嵌入式开发、操作系统学习和调试中,理解从硬件上电到内核执行的整个启动过程至关重要。本文将详细梳理这一过程,从设备开机的第一刻到 Linux 内核代码的执行,帮助你理解各个阶段的细节,以及每个环节所涉及的技术组件。
1. 开机至引导阶段:硬件初始化
1.1 开机过程(Power-On)
当嵌入式设备或计算机通电时,CPU 的程序计数器(PC)会指向 Boot ROM,这是芯片中内置的启动代码。这个过程被称为硬件复位。Boot ROM 负责执行最基本的硬件初始化工作,例如:
- 配置基本硬件接口(如时钟、内存)。
- 启动 Bootloader 或操作系统的其他引导代码。
在此阶段,设备上的所有硬件都处于一个未初始化的状态,Boot ROM 是确保硬件正确运行并加载后续引导程序的第一个环节。
1.2 引导加载程序(Bootloader)
引导加载程序(如 U-Boot、GRUB、systemd-boot 等)是整个启动过程中至关重要的环节。Bootloader 负责对硬件进行详细的初始化,并加载操作系统内核。
- 硬件初始化:包括内存、I/O 接口、处理器等设备的初始化。
- 启动参数配置:在这个阶段,Bootloader 会准备启动参数(Bootargs),这些参数会传递给内核,告诉内核如何启动。
- 加载操作系统:Bootloader 将操作系统内核(如 Linux 内核)加载到内存中,并跳转到内核的入口点开始执行。
常见的引导加载程序有:
- U-Boot:广泛用于 ARM、MIPS 等架构的嵌入式系统。它提供了强大的硬件初始化和操作系统加载功能。
- GRUB:常用于 x86 架构的 PC 端引导加载。
2. Linux 内核加载
2.1 加载内核镜像
引导加载程序(如 U-Boot)会从存储介质(例如 eMMC、NAND Flash 或 SD 卡)中读取内核镜像。它还会加载 设备树(Device Tree)和其他必要的文件(如根文件系统)。设备树包含了硬件设备的配置信息,内核需要根据这些信息正确地初始化硬件设备。
2.2 内核的入口点
Linux 内核的启动会从 start_kernel()
函数开始,这个函数是内核的第一个执行点。内核的主要初始化工作会在这里开始,包括:
- 内存管理初始化:内核会设置虚拟内存、页表等,管理物理内存的分配和回收。
- CPU 管理:内核会初始化 CPU 调度器,确保各个进程能够有效地运行。
- 硬件初始化:内核通过设备树,初始化硬件设备和驱动程序。
3. 设备树和内核初始化
3.1 设备树(Device Tree)
设备树是一个数据结构,用于描述硬件平台的配置信息,它包括了设备的地址、类型、驱动程序信息等。Linux 内核使用设备树来加载对应的硬件驱动。
- 设备树源文件(.dts):设备树的描述文件,开发者可以根据硬件平台编写或修改设备树文件。
- 设备树二进制文件(.dtb):是设备树的编译版本,由引导加载程序(如 U-Boot)传递给内核,内核使用该文件来初始化硬件。
3.2 内核模块加载
内核启动时,某些驱动程序(如网络驱动、显示驱动、存储驱动等)会以模块的形式加载。内核支持动态加载和卸载模块,能够在不重新启动系统的情况下更新或修改硬件驱动。
4. 内核初始化完成后:系统服务的启动
4.1 init
进程的启动
在内核初始化完毕后,它会启动第一个用户空间进程——init
进程。init
是系统中的第一个用户空间进程,所有用户空间进程都由它派生而来。
init
进程的作用:init
进程负责启动系统中的所有守护进程(如网络服务、文件系统服务等)。它会读取/etc/inittab
或使用systemd
来管理服务的启动。- 挂载根文件系统:在
init
进程启动之前,根文件系统会被挂载。根文件系统包含了操作系统的基本文件和目录结构。
4.2 用户空间服务的启动
init
进程启动后,会初始化和启动更多的系统服务,例如:
systemd
:现代 Linux 系统常用的初始化管理工具,负责启动服务和管理系统状态。- 用户空间应用程序:包括图形界面程序、网络服务、数据库服务等。
5. 总结:从开机到内核执行的完整过程
整个过程可以划分为以下关键阶段:
- 硬件初始化(Boot ROM):芯片开机后,CPU 从 Boot ROM 中读取并执行启动代码。
- 引导加载程序(Bootloader):引导加载程序(如 U-Boot)初始化硬件,加载内核镜像、设备树和启动参数,启动内核。
- Linux 内核加载:内核镜像被加载到内存,内核开始执行
start_kernel()
,完成内存管理、硬件初始化等工作。 - 设备树和内核模块加载:内核使用设备树初始化硬件,加载相应的驱动程序和模块。
- 系统服务启动:内核启动完毕后,
init
进程启动,挂载根文件系统,启动用户空间进程和服务。
这一过程涉及多个技术组件和工作环节,每个环节的顺利执行都确保了系统的稳定启动和硬件的正常运行。理解这一过程,有助于嵌入式开发者、系统管理员及技术支持人员更好地调试和优化 Linux 系统的启动过程。