ARM Linux启动流程是一个涉及硬件初始化、软件加载和系统配置的复杂过程,其设计旨在高效、可靠地将系统从硬件状态引导至可运行的Linux环境,整个过程可划分为上电初始化、Bootloader加载、内核启动、驱动初始化及用户空间启动五个关键阶段,每个阶段环环相扣,共同完成系统的启动任务。

上电初始化与Bootloader加载
系统上电后,CPU首先执行固化在ROM中的固化程序(Boot ROM),该程序负责进行最基本的硬件初始化,如设置CPU核心状态、配置时钟系统、初始化内存控制器等,对于ARM架构,Boot ROM会根据预设的启动模式(如从Nor Flash、SD卡、eMMC或网络启动)查找并加载第一级引导程序(Bootloader)。
Bootloader是硬件与操作系统之间的桥梁,其主要任务是初始化必要的硬件设备(如串口、定时器),加载Linux内核镜像到内存中,并设置启动参数,在ARM平台,常用的Bootloader包括U-Boot、ATF(ARM Trusted Firmware)等,以U-Boot为例,它支持多种启动方式,可通过环境变量配置启动介质和内核加载地址,当Bootloader完成硬件初始化后,会将CPU控制权转移至内核入口点(通常位于内核镜像的start标签处)。
内核解压与启动
Linux内核镜像可能是压缩的(如zImage)或未压缩的(Image),若为压缩镜像,Bootloader会先调用解压代码(如gunzip)将内核解压到内存指定区域(如0x80008000地址),然后跳转到解压后的内核代码执行,内核启动的第一阶段是体系结构相关的初始化,由汇编代码(如arch/arm/kernel/head.S)完成,包括设置CPU模式(从SVC模式切换到内核模式)、关闭中断、初始化页表、启用MMU(内存管理单元)等。
随后,内核调用C语言函数start_kernel(位于init/main.c),这是内核启动的核心函数,start_kernel会依次初始化内核的各个子系统,如调度器(scheduler_init)、内存管理(mm_init)、中断管理(trap_init)、进程管理(init_task)等,此阶段还会解析启动参数,这些参数由Bootloader通过设备树(Device Tree)或ATAGS(传统参数传递方式)传递,包含内存布局、根文件系统位置、启动命令行等信息。

设备树与驱动初始化
设备树(Device Tree, DT)是ARM Linux启动流程中至关重要的组成部分,用于描述硬件设备的拓扑结构和资源信息(如寄存器地址、中断号、时钟频率等),与传统的ATAGS相比,设备树提供了更灵活的硬件描述方式,尤其适用于异构多平台系统。
内核在启动时会解析设备树文件(.dtb),将其转换为内部设备树(device tree)结构,并遍历其中的节点,为每个设备创建platform_device结构,随后,内核通过驱动模型(driver model)匹配设备与驱动:当设备的compatible属性与驱动的of_match_table匹配时,驱动会通过probe函数初始化设备,此阶段会初始化大量驱动程序,如串口驱动(用于终端输出)、存储驱动(如eMMC、NVMe)、网络驱动(如Ethernet、Wi-Fi)等,确保硬件设备可被内核识别和管理。
用户空间启动
当内核完成初始化后,会启动第一个用户空间进程——init进程,标志着系统从内核空间进入用户空间,init进程的PID始终为1,负责后续所有用户空间进程的创建和管理,根据init系统的不同,启动流程可分为两类:
- SysVinit:传统的init系统,通过/etc/inittab配置启动级别,依次执行/etc/rc.d/目录下的启动脚本,挂载文件系统、启动系统服务(如网络、日志)、运行/etc/rc.local中的自定义命令。
- systemd:现代Linux系统广泛使用的init系统,采用并行启动机制,通过单元(unit)文件(.service、.target等)管理服务,依赖关系明确,启动效率更高。
无论采用哪种init系统,最终都会启动登录界面(如控制台登录、图形登录界面)或核心服务(如docker、数据库等),等待用户交互或提供服务,至此,ARM Linux系统完成从上电到可用的全部启动流程。

相关问答FAQs
Q1:为什么ARM Linux启动需要设备树?它解决了什么问题?
A1:设备树是ARM Linux为解决硬件描述灵活性而引入的机制,在传统x86平台,硬件信息由BIOS/UEFI固定提供;而ARM平台硬件多样性高(如不同芯片厂商的SoC外设配置差异大),若将硬件信息硬编码在内核中,会导致内核需要为每个平台单独编译,维护成本极高,设备树通过独立的.dtbf文件描述硬件拓扑,内核可动态解析,实现“单内核多平台”支持,简化了跨平台适配和硬件更新。
Q2:Bootloader与内核命令行参数有什么关系?如何传递参数?
A2:Bootloader负责将内核启动所需的参数(如根文件系统位置、console设备、启动模式等)传递给内核,参数传递方式主要有两种:
- ATAGS:传统方式,通过内存中的特定数据结构(tagged list)传递参数,适用于较老的ARM平台。
- 设备树:现代主流方式,参数通过设备树的chosen节点传递(如/boot/cmdline.txt中的内容会被写入chosen节点的bootargs属性),内核通过解析设备树获取参数。
root=/dev/mmcblk0p2指定根文件系统,console=ttyAMA0,115200指定串口输出。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复