imx51 ROM boot code 启动分析

启动模式

mx51支持四种启动模式,这些模式的选择是通过IC package上的焊点来决定的(BOOT_MODE 0/1),在reset后会采样这两个焊点,然后把他们的状态保存到SRC Boot Mode Register(SBMR) 寄存器。焊点连接到地对应logic 0,对于logic 1,freescale推荐使用NVCC_PER3

四种启动模式分别为: internal, reserved, internal boot with fuses 以及通过USB/UART的serial boot

BMOD[1:0]Boot Type
00internal Boot
01Reserved
10internal Boot - ROM Select
11Serial Downloader

Internal Boot (BMODE == 00)

在这种模式下处理器从internal ROM启动,启动代码执行HW初始化,然后跳转到AP image.

在internal Boot模式下,启动流程是由eFUSE设置或者GPIO管脚来控制的,这两个控制的选择是通过GPIO Boot Select(GPIO_BT_SEL)焊点控制的:

1 如果GPIO_BT_SEL被烧写过,所有的启动选项由eFUSE来控制,boot ROM代码通过IIM module读取eFUSEs

2 如果BPIO_BT_SEL没有被动过,那么启动选项是由SBMR寄存器的设置决定的,一些fuse选项可能在这种mode下被覆盖。覆盖是通过GPIO管脚来控制的,如果是YES,那么选项值就通过读取SBMR register 来获取


Internal Boot - ROM Select (BMODE == 10)

这种模式和Internal boot BOOT_MODE[1:0] == 00 的区别是10模式忽略GPIO覆盖,也就是不管GPIO_BT_SEL设置,启动过程使用eFUSE启动设置。这种模式主要用在量产设备上,不需要GPIO的上拉下拉,以及在产品级设备上由于boot pin值不正确导致serial downloader调用

在这种模式下,启动流程如果发现BT_BLANK没有被烧写过(表示ROM还没有被烧写过),那么直接跳转到serial downloader,如果BT_BLANK被烧写过,则正常的启动流程,并且使用eFUSE设置。

在板子第一次使用时,fuses还没有被烧写,如果使用internal boot模式BMOD==00,此时连接到BT GPIO pads上的值被使用,但是这些值可能并不是系统需要的,ROM code错误的使用了这些值,可能会导致这些pads的electrical/logic损坏。internal boot模式BMOD==10可以解决这个问题,如果BT_BLANK fuse没有被烧写过,启动过程跳转到serial downloader,而下一次BT_BLANK被烧写后ROM code则执行正常的启动流程。


Boot eFUSE 描述

mx51 boot eFUSE是启动流程的配置参数,包括

DIR_BT_DIS 直接external memory启动使能

BT_MEM_CTL[1:0] 启动memory类型控制:可支持WEIM,NAND flash以及扩展设备类型,BT_MEM_TYPE[1:0]定义了这些扩展设备设置

BT_PAGE_SIZE[1:0]: 定义NAND flash的page size,这个设置对应BT_MEM_CTL里面的NAND flash 类型

BT_SPARE_SIZE 定义4KByes page大小NAND flash的spare bytes,需要BT_MEM_CTL设置为NAND flash并且BT_PAGE_SIZE为4KB

BT_BUS_WIDTH[1:0] 定义NAND/NOR总线宽度

BT_MEM_TYPE BT_MEM_CTL定义的是大的memory类型,BT_MEM_TYPE对相应的类型又给出了更细的分类

BT_SRC[1:0] 定义了扩展设备类型的来源: eSDHC 1/2/3/4; I2C 1/2, HS-I2C; CSPI, eCSPI1/2

BT_WEIM 选择WEIM muxed模式

BT_UART_SRC 选择serial downloads使用的UART controller

BT_MLC_SEL SLC/MLC NAND 设备选择;或者eMMC fast boot mode 使能

....


GPIO Boot 覆盖

一些fuse设置可以被GPIO覆盖,当GPIO_BT_SEL被设置为0并且BOOTM[1:0] == 00时,GPIO覆盖生效


Serial Downloader(BMOD[1:0] == 11)

当外部flash device没有写入程序,或者在启动过程中碰到了失败,boot过程会调用serial downloader。

以下情况会调用serial downloader:

1 BMOD[1:0] == 11(serial downloader mode)

2 BMOD[1:0] == 10(internal boot with fuses) 并且eFuse_BT_BLANK=0

3 BMOD[1:0] == 10 (internal boot with fuses) 但是fuses没有正确的设置

4 BMOD[1:0] == 00 或者 10(internal or internal boot with fuses),并且Flash device上没有有效image

5 Security hardware failure

6 运行时异常发生

7 在产品模式下HAB函数返回错误


启动总结

从上面可以看出,在系统进入uboot前,imx51实际上要执行一段内部代码ROM boot code,

1. ROM boot code会读取eFUSE以及boot GPIO来获取启动配置参数,这些配置参数决定了uboot代码的存储位置,存储layout,物理位置等等。

2. 在执行uboot代码前,系统已经初始化好了部分系统时钟,内部ram,flash主机控制器,SD卡控制器以便从外部存储读取部分uboot到外部ram中(至于是ROM code初始化的 还是系统上电缺省初始化好的,就不做深究了)

3. iMX51的内部ram只有128KB,是无法装载整个uboot的,所以ROM boot code会把uboot最前面的部分读取出来放到内部ram(对于SD卡,boot ROM会读取SD设备的前2Kbytes数据到iram),并且把指针指向这个内部地址执行uboot的前一部分,这部分代码会初始化外部ram。

4. uboot的前半部分会做基本的初始化,并且把后半部分读入外部ram中,然后跳转到第二部分uboot的地址执行


因此uboot本身必须分为两个部分,前面部分由固化的ROM code装载到内部RAM,后一部分由uboot前一部分负责装载。如何确保前半部分包含必要的初始化代码,可以参考u-boot.lds链接脚本,这个脚本会把必要的代码放在uboot镜像的最前面。


下图是IMX51的internal ROM/RAM map图,internal ROM是用来保存mx51固化的boot code,internal RAM在boot过程中则用来装载uboot的前一部分。



<think>好的,我现在需要详细说明U-Boot及其启动流程。首先,我应该先了解U-Boot是什么,它的主要功能和用途。U-Boot,全称是Das U-Boot,是一个开源的引导加载程序,主要用于嵌入式系统。它支持多种架构,如ARM、MIPS、PowerPC等,常用于引导Linux内核。 接下来,我需要理解U-Boot启动流程。用户可能想知道从设备上电到加载内核的整个过程。启动流程通常分为几个阶段,每个阶段的具体任务可能有所不同,但大致可以分为以下几个步骤: 1. **ROM Bootloader**:设备上电后,首先执行的是芯片内部ROM中的引导代码。这部分代码通常是固化在硬件中的,负责初始化最基本的硬件,如时钟、内存控制器,并加载下一阶段的引导程序(如SPL)。 2. **SPL (Secondary Program Loader)**:由于内部ROM空间有限,SPL作为第二阶段引导加载程序,负责进一步初始化硬件(如DRAM),并加载完整的U-Boot到内存中。SPL通常是U-Boot的一部分,经过编译后生成的小型镜像。 3. **U-Boot主程序**:SPL加载完成后,跳转到U-Boot的主程序。U-Boot会进行更全面的硬件初始化,包括串口、网卡、存储设备等,然后读取环境变量,根据配置加载内核镜像、设备树文件(DTB)和根文件系统。 4. **加载内核**:U-Boot将内核镜像、设备树和可能的initramfs加载到内存中的指定地址,然后通过bootm或bootz命令启动内核,传递必要的参数。 在这个过程中,需要考虑到不同硬件平台的差异,比如启动介质(NOR Flash、eMMC、SD卡等)、内存布局、环境变量的存储位置(如EEPROMFlash中的特定分区)等。 另外,U-Boot还支持交互式命令,用户可以在启动过程中打断自动流程,进入命令行界面,手动执行命令进行调试或配置。环境变量在U-Boot中非常重要,它们决定了启动参数和流程,比如bootcmd定义了自动执行的命令序列。 可能还需要解释U-Boot的编译和配置过程,比如通过make menuconfig配置目标板,选择所需的驱动和功能,然后编译生成u-boot.bin等文件。此外,不同开发板的配置文件位于configs目录下,如mx6ullevk_defconfig对应特定的开发板。 在启动流程中,设备树(Device Tree)的作用也很重要,它描述了硬件配置,使得内核无需硬编码硬件信息。U-Boot负责将设备树二进制文件(DTB)加载到内存,并传递给内核。 还要注意U-Boot启动阶段可能涉及多个文件,比如SPL、U-Boot proper,以及如何将它们烧写到存储设备的正确位置。例如,在SD卡启动时,SPL可能需要存放在特定的偏移量位置,以便ROM Bootloader能够找到并加载它。 可能存在的疑问点包括:SPL和U-Boot的关系,如何配置环境变量,如何处理不同的启动介质,U-Boot如何与内核交互,以及如何调试启动问题。需要确保这些点在回答中都有所覆盖,并且结构清晰,步骤明确。 最后,需要验证这些信息是否正确,比如确认U-Boot启动阶段划分是否准确,SPL的作用是否描述正确,以及加载内核的具体命令和流程是否符合实际。如果有不确定的地方,可能需要查阅U-Boot的官方文档或源码进行确认,确保回答的准确性。</think>--- ### **U-Boot详解与启动流程分析** --- #### **1. U-Boot概述** **定义**: U-Boot(Universal Boot Loader)是嵌入式系统领域使用最广泛的开源引导加载程序,支持**ARM、MIPS、PowerPC、RISC-V**等30+处理器架构,兼容**NOR Flash、eMMC、NAND、SD卡**等多种存储介质。 **核心功能**: - 硬件初始化(时钟/DDR/外设) - 多阶段引导加载 - 固件升级(USB DFU/TFTP) - 环境变量管理 - 操作系统映像加载(Linux/FreeRTOS/VxWorks) - 安全启动(Verified Boot) --- #### **2. 典型启动流程** ```mermaid sequenceDiagram participant ROM Code participant SPL participant U-Boot participant Kernel ROM Code->>SPL: 加载SPL到SRAM SPL->>U-Boot: 初始化DRAM,加载U-Boot到内存 U-Boot->>U-Boot: 外设初始化(网卡/USB/存储) U-Boot->>Kernel: 加载内核镜像、设备树、initramfs Kernel->>Kernel: 解压并启动操作系统 ``` --- #### **3. 关键阶段详解** **3.1 ROM Bootloader** - **硬件行为**:芯片上电后自动执行固化在ROM中的代码 - **主要任务**: - 初始化基础时钟(CPU/总线) - 检测启动介质(通过GPIO或OTP配置) - 加载SPL到内部SRAM(典型大小:64-256KB) **示例代码(i.MX6ULL)**: ```c /* arch/arm/mach-imx/imx6ull/lowlevel_init.S */ bl setup_pll // 配置PLL时钟 bl setup_dcdr // DDR控制器初始化 ldr r0, =SPL_LOAD_ADDR bl load_image // 从SD卡加载SPL ``` --- **3.2 SPL阶段** - **二进制文件**:`u-boot-spl.bin` - **内存限制**:通常在SRAM中运行(无DRAM支持) - **核心任务**: 1. 初始化DRAM控制器 2. 设置内存映射表 3. 加载完整U-Boot到DRAM 4. 验证U-Boot镜像签名(安全启动场景) **关键配置选项**: ```makefile # configs/mx6ullevk_defconfig CONFIG_SPL=y CONFIG_SPL_DM=y CONFIG_SPL_LOAD_FIT=y ``` --- **3.3 U-Boot主程序** - **入口函数**:`lib/init/board_init.c`中的`board_init_f()` - **启动阶段划分**: ```c board_init_f() // 初始化全局数据结构(gd_t) ↓ relocate_code() // 重定位到DRAM高端地址 ↓ board_init_r() // 完整外设初始化 ``` **硬件初始化顺序**: 1. 串口调试输出(`DEBUG_PORT`) 2. 内存控制器配置 3. 存储设备初始化(MMC/SATA) 4. 网络接口(PHY初始化) 5. 环境变量加载(`env_relocate()`) --- **3.4 环境变量管理** - **存储位置**:Flash专用分区(如eMMC的ENV分区) - **关键变量**: ```bash bootcmd=mmc dev 0; ext4load mmc 0:1 0x80800000 zImage; \ ext4load mmc 0:1 0x83000000 imx6ull.dtb; \ bootz 0x80800000 - 0x83000000 bootargs=console=ttymxc0,115200 root=/dev/mmcblk0p2 ro ``` **操作命令**: ```bash # 查看环境变量 printenv # 修改并保存 setenv ipaddr 192.168.1.100 saveenv ``` --- #### **4. 内核加载过程** **典型bootm命令流程**: ```c do_bootm() ↓ bootm_start() // 解析镜像头信息 ↓ bootm_load_os() // 加载内核到指定地址 ↓ boot_fn = boot_os[os] // 选择启动方法(Linux/NetBSD等) ↓ do_bootm_linux() // 设置ATAGs/FDT,跳转到内核入口 ``` **ARM平台内存布局示例**: | 地址范围 | 用途 | |------------------|-----------------------| | 0x80000000 | 内核加载地址 | | 0x81000000 | 设备树地址 | | 0x82000000 | initramfs地址 | --- #### **5. 安全启动实现** **数字签名验证流程**: ```mermaid graph LR A[SPL] --> B{验证U-Boot签名} B -->|有效| C[加载U-Boot] B -->|无效| D[进入恢复模式] C --> E[U-Boot验证内核签名] E -->|有效| F[启动内核] E -->|无效| G[终止启动] ``` **关键配置**: ```makefile CONFIG_SPL_FIT_SIGNATURE=y # 启用FIT镜像签名 CONFIG_SPL_CRYPTO_SUPPORT=y # 加密算法支持 CONFIG_SPL_RSA_VERIFY=y # RSA验证 ``` --- #### **6. 调试与优化** **6.1 常用调试手段**: - 串口日志输出(`CONFIG_DEBUG_UART`) - LED指示灯控制(`led_set_state()`) - 内存检测(`mtest`命令) - 启动暂停(`CONFIG_AUTOBOOT_KEYED`) **6.2 性能优化技巧**: ```c /* 加速存储设备访问 */ #define CONFIG_SYS_MMC_ENV_DEV 0 #define CONFIG_SYS_MMC_MAX_BLK_COUNT 1024 // 增大块传输数量 /* 压缩镜像尺寸 */ #define CONFIG_LZMA // 使用LZMA压缩算法 ``` --- #### **7. 典型移植步骤** 1. **创建板级目录**: ```bash board/<vendor>/<board>/ ├── Kconfig ├── Makefile └── <board>.c ``` 2. **配置设备树**: ```dts /dts-v1/; / { model = "Custom Board"; memory@80000000 { reg = <0x80000000 0x20000000>; }; }; ``` 3. **实现关键驱动**: - 串口(`drivers/serial/serial_xxx.c`) - 存储设备(`drivers/mmc/mmc_xxx.c`) - GPIO控制 --- #### **8. 启动时间分析** **典型时间分布(ARM Cortex-A9@1GHz)**: | 阶段 | 耗时(ms) | |----------------|-----------| | ROM Code | 12 | | SPL执行 | 58 | | U-Boot初始化 | 320 | | 内核加载 | 92 | | **总计** | **482** | **优化方向**: - 启用SPL框架(减少初始化步骤) - 预计算CRC32(替代运行时计算) - 并行初始化外设 --- 通过这种层次化的启动架构,U-Boot实现了从硬件初始化到操作系统引导的完整控制流程,其模块化设计和可移植性使其成为嵌入式系统开发的核心组件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值