深入解析ESP32C3(3)- bootloader启动流程

news2024/12/22 0:11:03

ESP32C3启动流程可以分为如下3 个步骤:

  1. 一级引导程序(PBL):被固化在了ESP32-C3 内部的ROM 中,它会从flash 的0x0 偏移地址处加载二级引导程序至RAM (IRAM & DRAM) 中。
  2. 二级引导程序(SBL):从flash 中加载分区表和主程序镜像至内存中,主程序中包含了RAM 段和通过flash高速缓存映射的只读段。
  3. 应用程序(RTOS):APP启动运行,这时RTOS 的调度器和第二个CPU(多核)启动。

一级引导程序(PBL) 

PBL固化在ESP32C3芯片内部ROM,无法更改。由于官方没有公开PBL的代码,这里直接参考开发向导的功能介绍。
SoC 复位上电后,CPU 会立即跳转至0x4000_0000地址处,开始执行初始化操作。乐鑫提供了ELF格式的内部固件,以下是ELF头信息:

> riscv32-esp-elf-readelf.exe -h G:\Program\Espressif\tools\esp-rom-elfs\20230113\esp32c3_rev3_rom.elf
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           RISC-V
  Version:                           0x1
  Entry point address:               0x40000000
  Start of program headers:          52 (bytes into file)
  Start of section headers:          553332 (bytes into file)
  Flags:                             0x1, RVC, soft-float ABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         28
  Size of section headers:           40 (bytes)
  Number of section headers:         75
  Section header string table index: 74

 PBL开机日志:

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x15 (USB_UART_CHIP_RESET),boot:0xc (SPI_FAST_FLASH_BOOT)
Saved PC:0x4004c634
0x4004c634: uart_rx_readbuff in ROM

SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5820,len:0x1710
load:0x403cc710,len:0x968
load:0x403ce710,len:0x2f9c
entry 0x403cc710
//上面是PBL日志,后面是SBL日志
I (15) boot: ESP-IDF HEAD-HASH-NOTFOUND 2nd stage bootloader
I (15) boot: compile time Jan 23 2024 19:23:22
I (15) boot: chip revision: v0.4

复位向量调用的启动代码会根据GPIO_STRAP_REG 寄存器的值来确定ESP32-C3 的启动模式,该寄存器保存着复位后bootstrap 引脚的电平状态。bootstrap引脚包括:
        • 芯片启动模式– GPIO2、GPIO8 和GPIO9
        • ROM 代码日志打印– GPIO8 (默认开启并从USB Serial打印,GPIO8任意值)

从上表可知,bootstrap引脚决定是否进入下载模式或SPI启动模式。

1)下载模式

用户可通过UART0 或USB 接口将代码下载至flash 中,或将程序加载到SRAM 并在SRAM 中运行程序。
下面几个eFuse 可用于控制启动模式的具体行为:

  • EFUSE_DIS_FORCE_DOWNLOAD
    如果此eFuse 设置为0(默认),软件可通过设置RTC_CNTL_FORCE_DOWNLOAD_BOOT,触发CPU 复位,将芯片启动模式强制从SPI Boot 模式切换至Download Boot 模式;如果此eFuse 设置为1,则禁用RTC_CNTL_FORCE_DOWNLOAD_BOOT。
  • EFUSE_DIS_DOWNLOAD_MODE
    如果此eFuse 设置为1,则禁用Download Boot 模式。
  • EFUSE_ENABLE_SECURITY_DOWNLOAD
    如果此eFuse 设置为1,则在Download Boot 模式下,只允许读取、写入和擦除明文flash,不支持SRAM或寄存器操作。如已禁用Download Boot 模式,请忽略此eFuse。

2)SPI启动模式 

CPU 通过从SPI flash 中读取程序来启动系统。SPI Boot 模式可进一步细分为以下两种启动方式:

  • 常规flash 启动方式:支持安全启动,程序运行在RAM 中
  • 直接启动方式:不支持安全启动,程序直接运行在flash 中。如需使能这一启动方式,请确保下载至flash的bin 文件其前两个字(地址:0x42000000)为0xaedb041d。

SoC复位的原因会被保存于寄存器RTC_CNTL_RESET_CAUSE_PROCPU中,数值定义如下:

CPU在复位后可读取该值,根据不同的复位原因,程序会执行不同的操作: 

(a) 深度睡眠模式复位

深度睡眠模式下,芯片的ROM 和RAM 均将断电,因此在唤醒时SPI 启动(从flash 复制数据)所需时间更长,而RTC 快速内存处于上电状态。因此,为了加速芯片唤醒过程,用户可以将一些代码规模不大(即小于8 KB 的“deep sleep wake stub” )写入RTC 快速内存,并将入口地址写入寄存器RTC_CNTL_STORE6_REG,将RTC 快速内存的CRC 码保存到寄存器RTC_CNTL_STORE7_REG。
当CPU 开启时,开始进行ROM 解包和部分初始化工作。此后,再次计算RTC 快速内存的CRC 码。如果与寄存器RTC_CNTL_STORE7_REG中保存的结果一致,则CPU 跳转至RTC 快速内存的入口地址;否则,运行SoC上电复位的启动流程。

(b) 上电复位、软件SoC 复位、看门狗SoC 复位等

CPU 复位后,PBL引导程序从SPI flash加载SBL引导程序,然后从SBL头部找到程序入口地址并跳转运行,进入SBL引导程序。

IDF系统软件定义了11种复位原因,见代码定义项。

FILE: \components\esp_system\include\esp_system.h
/**
 * @brief Reset reasons
 */
typedef enum {
    ESP_RST_UNKNOWN,    //!< Reset reason can not be determined
    ESP_RST_POWERON,    //!< Reset due to power-on event
    ESP_RST_EXT,        //!< Reset by external pin (not applicable for ESP32)
    ESP_RST_SW,         //!< Software reset via esp_restart
    ESP_RST_PANIC,      //!< Software reset due to exception/panic
    ESP_RST_INT_WDT,    //!< Reset (software or hardware) due to interrupt watchdog
    ESP_RST_TASK_WDT,   //!< Reset due to task watchdog
    ESP_RST_WDT,        //!< Reset due to other watchdogs
    ESP_RST_DEEPSLEEP,  //!< Reset after exiting deep sleep mode
    ESP_RST_BROWNOUT,   //!< Brownout reset (software or hardware)
    ESP_RST_SDIO,       //!< Reset over SDIO
} esp_reset_reason_t;

二级引导程序(SBL)

ESP-IDF的二级引导程序(SBL)主要实现了以下的功能:
   增加flash 分区的灵活性(使用分区表);
   方便实现flash 加密;
   安全引导;
   空中升级(OTA) 。
SBL引导固件被烧录于SPI Flash 的0x0000_0000偏移地址处,默认分区大小限制在32KB(见宏CONFIG_PARTITION_TABLE_OFFSET)。其主要源码在ESP-IDF \ component下的子目录bootloader\、bootloader_support\,还有其他被引用的组件,所涉及到的组件可查看编译日志,或直接查看编译结果的子目录情况:

 SBL程序入口 是call_start_cpu0()函数,而该函数结构清晰,内部的步骤,很直观展示SBL的运行流程,分为3个阶段:

  • 初始化阶段
  • 分区选择阶段
  • 镜像加载阶段

File: components\bootloader\subproject\main\bootloader_start.c 

void __attribute__((noreturn)) call_start_cpu0(void)
{
    // (0. Call the before-init hook, if available)
    if (bootloader_before_init) {
        bootloader_before_init();
    }

    // 1. Hardware initialization
    if (bootloader_init() != ESP_OK) {
        bootloader_reset();
    }

    // (1.1 Call the after-init hook, if available)
    if (bootloader_after_init) {
        bootloader_after_init();
    }

#ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
    // If this boot is a wake up from the deep sleep then go to the short way,
    // try to load the application which worked before deep sleep.
    // It skips a lot of checks due to it was done before (while first boot).
    bootloader_utility_load_boot_image_from_deep_sleep();
    // If it is not successful try to load an application as usual.
#endif

    // 2. Select the number of boot partition
    bootloader_state_t bs = {0};
    int boot_index = select_partition_number(&bs);
    if (boot_index == INVALID_INDEX) {
        bootloader_reset();
    }

    // 3. Load the app image for booting
    bootloader_utility_load_boot_image(&bs, boot_index);
}

1)初始化阶段

--> bootloader_init(void) : // 步骤1. Hardware initialization  
    bootloader_hardware_init();
    bootloader_ana_reset_config();
    bootloader_init_mem();
    bootloader_clear_bss_section();
    bootloader_console_init();
    bootloader_init_spi_flash()
    bootloader_config_wdt();     // config WDT
    bootloader_enable_random();  // enable RNG early entropy source

2)分区选择阶段

-->select_partition_number(&bs)      // 步骤2. Select the number of boot partition
    bootloader_utility_load_partition_table(bs) // (1) Load partition table
    selected_boot_partition(bs)                 // (2) Select the number of boot partition
     -->bootloader_utility_get_selected_boot_partition(bs)
           return FACTORY_INDEX; // 如果未设置OTA分区,则返回FACTORY
           read_otadata()  // 读取ota_info分区,获得OTA分区的配置信息
           bootloader_common_get_active_otadata(otadata)
           write_otadata() //若使能APP回滚机制,OTA机制根据状态来更新ota_info分区的数据
           update_anti_rollback() //若使能防回滚机制,保证固件版本不会回落到低版本

3)镜像加载阶段

-->bootloader_utility_load_boot_image(&bs, boot_index);  // 步骤3. Load the app image for booting
    try_load_partition(&bs->test, &image_data)
     -->bootloader_load_image(partition, data) --> image_load(mode, part, data)
           process_image_header(data, part->offset...)
           process_segments(data, silent...)
           process_checksum(sha_handle, checksum_word...)
           process_appended_hash_and_sig(data, part->offset...)
           verify_secure_boot_signature(sha_handle, data...)
           bootloader_sha256_finish(sha_handle, NULL);
           should_load(load_addr)
    load_image(&image_data);
     -->esp_secure_boot_v2_permanently_enable(image_data);  
           esp_efuse_batch_write_begin();   /* Batch all efuse writes at the end of this function */
           esp_efuse_batch_write_commit();
     -->esp_secure_boot_generate_digest()   
           esp_image_verify_bootloader_data(&bootloader_data);
           secure_boot_generate(image_len)
     -->esp_flash_encrypt_init();
     -->esp_flash_encrypt_contents();
     -->esp_flash_encrypt_enable();
     -->unpack_load_app(image_data); // 加载APP程序的代码、数据段到RAM,配置MMU映射并使能Cache
         set_cache_and_start_app(drom_addr, .......data->image.entry_addr);
          --> mmu_hal_map_region(0, MMU_TARGET_FLASH0, drom_load_addr_aligned....)
          --> mmu_hal_map_region(0, MMU_TARGET_FLASH0, irom_load_addr_aligned....)
          --> cache_ll_l1_enable_bus(0, bus_mask);     //Enable corresponding buses
          --> cache_hal_enable(CACHE_TYPE_ALL);    //Enable Cache
          --> ESP_LOGD(TAG, "start: 0x%08"PRIx32, entry_addr);
          --> entry_t entry = ((entry_t) entry_addr);    // entry_addr = data->image.entry_addr
          --> (*entry)();  //跳转到APP应用程序中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1452425.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2.13:C语言测试题

21.(b) 6 22.(b) cd 23.b) 5 4 1 3 2 栈&#xff1a;先进后出 24. b,c,d:10,12,120 25.2,5 26.越界访问&#xff0c;可能正常输出&#xff0c;可能段错误 27. 0&#xff0c;41 28. a&#xff09;11 b) 320 29. aab; ba-b; aa-b; 30. p150x801005; p250x810…

mysql 2-16

安全等于<> 最大最小LEAST,GREATEST BETWEEN AND 条件一是下限 IN LIKE关键字 转移字符 逻辑运算符 位运算符 排序数据 升序降序&#xff0c;默认升序 二级排序 8.0新特性 小拓展 多表查询 多表查询 别名 多表查询的分类 非等值连接 自连接 内连接与外连接 sql92实现外连…

在JavaScript中的防抖函数 - 通过在React中构建自动完成功能来解释

当你将一个新应用推向生产环境时&#xff0c;你希望确保它用户友好。网站的性能是用户体验的关键部分。每个用户都希望网站及其内容能够快速加载。每一秒都是宝贵的&#xff0c;可能导致用户再也不会访问你的网站。 在本指南中&#xff0c;我们将了解JavaScript中一个非常重要…

17.3.1.3 灰度

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 灰度的算法主要有以下三种&#xff1a; 1、最大值法: 原图像&#xff1a;颜色值color&#xff08;R&#xff0c;G&#xff0c;B&a…

第2讲springsecurity+vue通用权限系统

阿里云 maven阿里云镜像 <?xml version"1.0" encoding"UTF-8"?><!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for addition…

【PyQt】13-对话框

文章目录 前言一、知识储备二、详细展开2.1 通用对话框-QDialog2.1 消息类型对话框-QMessageBox运行结果 2.2 输入对话框 QInputDilog运行结果 2.3 字体对话框-QFontDialog运行结果 2.4 颜色对话框运行结果 2.5 文件对话框运行结果 总结 前言 1、四种形式的对话框。 2、警告框…

如何让Obsidian实现电脑端和安卓端同步

Obsidian是一款知名的笔记软件&#xff0c;支持Markdown语法&#xff0c;它允许用户在多个设备之间同步文件。要在安卓设备上实现同步&#xff0c;可以使用remote save插件&#xff0c;以下是具体操作步骤&#xff1a; 首先是安装电脑端的obsidian&#xff0c;然后依次下载obs…

《Go 简易速速上手小册》第6章:错误处理和测试(2024 最新版)

文章目录 6.1 错误处理机制 - Go 语言中的优雅回旋6.1.1 基础知识讲解6.1.2 重点案例&#xff1a;文件读取器功能描述实现代码 6.1.3 拓展案例 1&#xff1a;网络请求处理器功能描述实现代码 6.1.4 拓展案例 2&#xff1a;数据库查询执行器功能描述实现代码 6.2 编写可测试的代…

GPT SOVITS项目 一分钟克隆 (文字输出)

步骤流程&#xff1a;&#xff08;首先使用UVR 提取人声文件&#xff0c;然后按下面步骤进行&#xff09; 注意这里提交的音频是参考的音频

使用EL访问隐式对象

使用EL访问隐式对象 问题陈述 Smart Software Inc.想要开发一款维护雇员数据的Web应用程序。为了实现此目标,该公司决定使用JSP。JSP页面应接受基于雇员姓名、ID、第一语言和第二语言的雇员数据,这些数据由雇员输入。然后,应能在另一个JSP页面上显示这些员工详细信息。另外…

【天衍系列 04】深入理解Flink的ElasticsearchSink组件:实时数据流如何无缝地流向Elasticsearch

文章目录 01 Elasticsearch Sink 基础概念02 Elasticsearch Sink 工作原理03 Elasticsearch Sink 核心组件04 Elasticsearch Sink 配置参数05 Elasticsearch Sink 依赖管理06 Elasticsearch Sink 初阶实战07 Elasticsearch Sink 进阶实战7.1 包结构 & 项目配置项目配置appl…

电商+支付双系统项目------支付系统的构思

本篇文章会讲讲支付的一些相关的名词概念以及怎么去设计支付系统&#xff0c;通过理解支付的这些名词概念和支付系统的架构&#xff0c;为接下来写支付系统的代码做好准备。 目录 支付------支付资质 支付------支付场景 微信 付款码支付 Native支付 支付宝 条码付 扫码…

UE4学习笔记 FPS游戏制作5 动画蒙太奇制作开枪动画

创建一个蒙太奇 选择角色的骨骼&#xff0c;并重命名 编辑蒙太奇 将我们需要的动画拖动到Default下的两个白杠的上边那个里 然后在下方的Sections节点中&#xff0c;点击Preview后的Default&#xff0c;选中后&#xff0c;再点击PreviewAllScetions上百年的长的绿色的Defalut&…

jmeter遇到连接数据库的问题

jmeter连接mysql或者oracle简单&#xff0c;但是连接过inceptor吗&#xff1f; 上货 1、下载驱动inceptor 5.1.2.jar包 2、在添加驱动那里导入 3、在JBC request中的写法 PS:没什么可说的

源聚达科技:抖音店铺2024年卖什么好

随着时代的变迁和科技的进步&#xff0c;消费者的购物习惯与偏好也在不断演变。展望2024年&#xff0c;抖音作为新兴的电商平台&#xff0c;其店铺销售策略需紧跟潮流&#xff0c;才能在激烈的市场竞争中脱颖而出。那么&#xff0c;哪些产品将成为抖音店铺的新宠呢? 首当其冲&…

C#使用迭代器实现文字的动态效果

目录 一、涉及到的知识点 1.GDI 2.Thread类 3.使用IEnumerable()迭代器 二、实例 1.源码 2.生成效果&#xff1a; 一、涉及到的知识点 1.GDI GDI主要用于在窗体上绘制各种图形图像。 GDI的核心是Graphics类&#xff0c;该类表示GDI绘图表面&#xff0c;它提供将对象绘制…

人工智能专题:基础设施行业智能化的基础设施,自智网络双价值分析

今天分享的是人工智能系列深度研究报告&#xff1a;《人工智能专题&#xff1a;基础设施行业智能化的基础设施&#xff0c;自智网络双价值分析》。 &#xff08;报告出品方&#xff1a;埃森哲&#xff09; 报告共计&#xff1a;32页 自智网络驱动的电信产业变革 经过多年的…

mysql-E-R图的组成要素及其画法

一、概念结构设计-E-R图方法 实体关系图&#xff1a; 简记E-R图&#xff0c;是指以实体、关系、属性三个基本概念概括数据的基本结构&#xff0c;从而描述静态数据结构的概念模式。 实体型(Entity)&#xff1a; 具有相同的特征和性质的集合体&#xff0c;用实体名及其属性名来…

SW2000TSN-千兆百兆车载以太网TSN交换机

更多资讯可以进入官网查看或者联系我们http://www.hdn-vdo.com

智慧公厕的主要应用

在现代社会中&#xff0c;随着城市化进程的加速推进&#xff0c;公共卫生设施的建设和管理变得愈加重要。而智慧公厕作为一种新型城市公共设施&#xff0c;正以其智能化、高效化的特点&#xff0c;成为改善城市卫生环境的重要手段。智慧公厕运用物联网、互联网、大数据、云计算…