自学内容网 自学内容网

Bootloader在CPU硬件系统设计上的应用

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。

老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师:

所有人的看法和评价都是暂时的,只有自己的经历是伴随一生的,几乎所有的担忧和畏惧,都是来源于自己的想象,只有你真的去做了,才会发现有多快乐。人就应该满脑子都是前途,不再在意别人的看法不再害怕别人讨厌自己,不再畏手畏脚忧心忡忡也不会在睡前反回忆白天的行为,是否让对方产生误解用你那精神内耗的态度去搞学习搞事业搞钱,然后用躺平和摆烂的态度对待人际关系,烦恼能消失一大半。
无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事.而不是让内心的烦躁、焦虑、毁掉你本就不多的热情和定力。

时间不知不觉中,快要来到深秋。国庆假期结束,又开始新的忙碌。成年人的我也不知道去哪里渡自己的灵魂,独自敲击一些文字算是对这段时间做一个记录。

对于带操作系统的硬件架构,如何从硬件的角度去理解Bootloader,以及Bootloader在整个产品系统中充当什么样的角色以及会对芯片以及外围有何影响?通过本文从硬件的角度进行阐述理解Bootloader。

在X86或者SoC等平台的硬件产品设计时,往往会用到外挂存储芯片(flash)的方式来存主控芯片的一些底层程序,也就是常说的Bootloader功能,外挂存储芯片(flash)的主要作用是为系统提供启动代码或固件,尤其是在嵌入式系统、CPU、SoC(系统级芯片)等环境中。外挂的Boot Flash通常存储系统的引导程序(Bootloader),系统在上电或复位时首先从Flash中读取并执行引导代码。引导程序的主要功能是初始化硬件、设置系统工作模式,然后从其他存储介质(如内存、存储设备)加载操作系统或应用程序。

在硬件设计过程中,外挂Boot Flash的主要作用是为系统提供启动引导、存储固件、支持固件升级、提升启动速度,并提供容错机制。

Bootloader的主要功能

对于带操作系统的产品来说,从开机上电到操作系统启动需要一个引导过程。嵌入式Linux系统同样离不开引导程序,这个引导程序就叫Bootloader。设备上电或复位后,处理器首先运行Bootloader程序。主要功能为:

初始化硬件

启动时,Bootloader 会对硬件系统(如CPU、内存、I/O设备、时钟等)进行初始化,以确保后续的操作系统能够顺利加载和运行。这包括配置硬件寄存器、设置存储器映射、初始化存储器和外设。典型的硬件初始化工作包括:

CPU 初始化:配置处理器时钟频率、启用缓存、配置内存控制器等。

内存初始化:通常为初始化RAM控制器、设置内存地址映射、检查 RAM的可用性。

外设初始化:如UART(用于串口调试)、网络接口、存储设备(如 eMMC、SD卡等)等的初始化,确保系统能够正确访问外部存储和输入输出设备。

加载操作系统

Bootloader 的核心任务是从外部存储设备(如NAND Flash、NOR Flash、SD卡等)加载操作系统的内核映像(Kernel Image)到RAM,并将控制权交给内核。一旦硬件初始化完成,Bootloader的主要任务是加载操作系统。其过程包括:

选择加载源:Bootloader从特定的存储介质中读取操作系统映像。典型的存储介质包括内嵌Flash、外部Flash、SD卡或网络(通过TFTP等协议)。

校验内核映像:为了确保加载的操作系统映像未损坏,Bootloader通常对其进行校验(如校验和或数字签名验证)。

加载映像到RAM:Bootloader会将操作系统映像(如Linux内核)从存储设备加载到RAM中,以供后续执行。

执行系统启动检查

Bootloader 通常还负责进行一些基本的系统启动自检操作,以确保在引导操作系统之前,硬件状态是可用的。完成内核映像加载后,Bootloader将 CPU的控制权转交给操作系统内核,具体步骤为:

设置启动参数:Bootloader可能需要传递一些启动参数给操作系统内核,如硬件信息、内存布局、命令行参数等。

切换到操作系统模式:在嵌入式系统中,处理器可能从初始的启动模式(如 Boot ROM 模式)切换到操作系统模式,并运行加载的内核。

Kernel Image 是操作系统内核在被加载到内存之前存储在磁盘或其他存储介质上的二进制文件。在操作系统启动时,Bootloader会将Kernel Image加载到内存中,并跳转到内核的入口点,开始操作系统的运行。Kernel Image在linux系统中常见的类型如uImage,uImage是常见的用于ARM 架构的 Linux 内核映像格式,通常由U-Boot Bootloader加载。它在内核镜像的头部添加了一些元数据(如校验和、映像大小、内核加载地址等),便于嵌入式启动器处理。

固件引导操作系统—软件层面

目前常见的国产CPU以及SoC等芯片中,通常使用的是以ARM架构为主的处理器,而对于此类处理器软件引导流程一般都会包含通用固件层,通用固件层是U-Boot等通用型的固件,提供固件层的操作平台,运行在 Non-Secure EL2(非安全状态)。对于ARM架构中的通用固件支持多种操作系统引导介质,包括:Flash、SATA、NVME、网络、USB等。通用固件支持UEFI GPT和传统MBR两种分区格式,支持EXT4、EFI FAT等文件系统。通用固件基于相应的设备驱动,将操作系统内核镜像文件加载到内存,并按镜像的文件格式要求将镜像的各段(section)展开在内存中。通用固件支持bin、ELF、U-Boot头等多种操作系统镜像格式:

Bin:二进制文件,文件的加载地址必须要等于编译地址。

ELF:ELF文件格式的镜像文件,加载地址与展开地址不能冲突。

U-Boot:U-Boot使用的uImage,加载地址与展开地址不能冲突。

除了操作系统内核镜像,通用固件还负责将设备树、UEFI系统表、内存文件系统(ramfs)等加载到内存中。固件支持FDT、PSCI等多种接口规范,并支持UEFI和U-Boot两种传参规范。

图片

bootloader在ARM体系结构中引导流程

在ARM体系结构中,Bootloader是嵌入式系统中的关键软件组件,负责初始化硬件、设置CPU环境,并引导操作系统启动。它通常被分为多个阶段(如Stage1和Stage2),每个阶段负责不同的初始化任务。以下是 Bootloader 的引导流程详细介绍:

Bootloader 的基本作用

初始化最基本的硬件(如内存、时钟等)。

加载操作系统内核或其他二级Bootloader(在多级Bootloader系统中)。

设置处理器和设备的状态,为操作系统提供稳定的运行环境。

可选:验证操作系统映像的完整性,以确保安全启动。

Bootloader 引导流程的各个阶段

通常Bootloader的引导过程可以分为几个阶段,每个阶段负责不同的功能。具体的引导流程如下:

1. 上电复位(Power-on Reset)

在系统上电或复位时,ARM 处理器进入复位状态,开始执行从预定义的地址(通常是Flash或ROM存储器的起始地址)加载的指令。这些指令通常由Bootloader的第一阶段(Stage1)提供。

复位向量地址:ARM 处理器的启动地址是由硬件配置决定的,通常位于地址 0x00000000 或 0xFFFF0000(取决于具体的ARM版本)。

复位后的状态:在复位后,CPU的状态是最基本的。此时,片内的缓存、内存控制器等外设尚未初始化,系统还处于裸机状态,需通过 Bootloader来完成后续的初始化工作。

2. Stage1 Bootloader

职责:

最小化的硬件初始化:Stage1 Bootloader 的首要任务是初始化必要的硬件,使得系统能够顺利进入Stage2 Bootloader或加载操作系统。它主要包括时钟配置、CPU 缓存、内存控制器(如DRAM)的初始化。

堆栈设置:设置栈指针,因为ARM处理器在复位后,栈指针可能未初始化,导致无法正常执行函数调用等操作。

装载二级Bootloader或操作系统:从非易失性存储器(Flash、eMMC 等)加载二级Bootloader或操作系统镜像到内存中。

具体步骤:

时钟系统初始化:设置系统的时钟频率,以确保各个外设能够以正确的时序工作。

存储器初始化:初始化DRAM或SRAM,使得后续的代码可以顺利加载到RAM中执行,因为初始状态下系统可能仅能访问内部存储器。

跳转到 Stage2 Bootloader或直接进入操作系统内核。

3. Stage 2 Bootloader

职责:

扩展硬件初始化:Stage2 Bootloader的任务是进一步初始化系统的其他硬件设备,例如UART、I/O 接口、SD 卡控制器、USB 控制器等。它还会执行更复杂的系统设置,包括多核处理器的设置等。

加载操作系统内核:从存储介质(如 eMMC、SD 卡、Flash)中加载操作系统内核到内存中。

设备树传递:在加载内核前,Bootloader需要向操作系统传递设备树信息,描述系统硬件的配置。

内核启动后会解析设备树,识别出系统中存在的硬件设备(CPU、内存、总线、I/O 设备),并加载相应的驱动程序。

启动内核:跳转到操作系统内核的入口点,并将控制权交给操作系统。

具体步骤:

硬件设备初始化:如 UART、I/O 接口等设备的初始化。

内核映像加载:从外部存储(如 eMMC、Flash)中读取操作系统内核映像到内存中。

内核启动参数设置:设置启动参数并将其传递给操作系统,如内存大小、启动模式、设备树等。

跳转到操作系统内核:Stage 2 Bootloader最终会跳转到内核入口点,并交出控制权。此时,系统进入操作系统阶段。

4. 内核启动

一旦 Bootloader 完成任务并将控制权交给操作系统内核,内核开始运行并继续初始化剩余的系统资源和服务,最终启动用户态程序。而操作系统内核的启动任务主要分为如下2点:

初始化硬件抽象层(HAL),加载驱动程序,建立系统调用和用户进程管理等。

当操作系统或应用程序需要与硬件进行交互时,通常不会直接控制硬件,而是通过HAL层来操作硬件。例如,在嵌入式系统中,操作系统可能需要控制 GPIO 引脚来与外部设备通信。操作系统会调用HAL提供的GPIO接口,而HAL会将这些接口的调用映射到具体的硬件操作。

启动第一个用户态进程(如 init 进程),完成整个系统的引导。

ARM Bootloader 的安全引导(可选)

在某些系统中,Bootloade还可能包括一个安全启动(Secure Boot)机制,用于防止未经授权的代码运行。典型的安全引导流程包括:

验证 Bootloader:系统首先通过硬件信任根(如ARM TrustZone 或 TPM)验证 Bootloader 的签名,确保它未被篡改。

验证操作系统映像:Bootloader在加载操作系统映像前,也会对操作系统映像进行签名验证,确保其来源合法。

启动操作系统:在所有验证通过后,系统继续启动操作系统。

在这里插入图片描述

小结

本文以笔者硬件开发的角度,尝试去理解bootloader在整个系统中的作用,整个过程中对于软件层面的操作描述可能存在笔误,有不对之处,还望指正。


原文地址:https://blog.csdn.net/Soly_kun/article/details/143169619

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!