mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 20:41:14 +00:00
bootloader: override the 2nd stage bootloader
Add the possibility to have user bootloader components. This is performed from an application/project, by creating bootloader components. To do so, it is required to create a `bootloader_component` directory containing the custom modules to be compiled with the bootloader. Thanks to this, two solutions are available to override the bootloader now: - Using hooks within a user bootloader component - Using a user defined `main` bootloader component to totally override the old implementation Please check the two new examples in `examples/custom_bootloader` * Closes https://github.com/espressif/esp-idf/issues/7043
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
# For more information about build system see
|
||||
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
|
||||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(main)
|
9
examples/custom_bootloader/bootloader_hooks/Makefile
Normal file
9
examples/custom_bootloader/bootloader_hooks/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides
|
||||
# in is a project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := bootloader_hooks
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
57
examples/custom_bootloader/bootloader_hooks/README.md
Normal file
57
examples/custom_bootloader/bootloader_hooks/README.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Bootloader hooks
|
||||
|
||||
(See the README.md file in the upper level for more information about bootloader examples.)
|
||||
|
||||
The purpose of this example is to show how to add hooks to the 2nd stage bootloader.
|
||||
|
||||
## Usage of this example:
|
||||
|
||||
Simply compile it:
|
||||
```
|
||||
idf.py build
|
||||
```
|
||||
|
||||
Then flash it and open the monitor with the following command:
|
||||
```
|
||||
idf.py flash monitor
|
||||
```
|
||||
|
||||
If everything went well, the bootloader output should be as followed:
|
||||
```
|
||||
I (24) HOOK: This hook is called BEFORE bootloader initialization
|
||||
I (37) boot: [...]
|
||||
[...]
|
||||
I (60) HOOK: This hook is called AFTER bootloader initialization
|
||||
```
|
||||
|
||||
And finally the application will start and show the message:
|
||||
```
|
||||
User application is loaded and running.
|
||||
```
|
||||
|
||||
## Organisation of this example
|
||||
|
||||
This project contains an application, in the `main` directory that represents a user program.
|
||||
It also contains a `bootloader_components` that, as it name states, contains a component compiled and linked with the bootloader.
|
||||
|
||||
Below is a short explanation of files in the project folder.
|
||||
|
||||
```
|
||||
├── CMakeLists.txt
|
||||
├── main
|
||||
│ ├── CMakeLists.txt
|
||||
│ └── main.c User application
|
||||
├── bootloader_components
|
||||
│ └── my_boot_hooks
|
||||
│ ├── CMakeLists.txt
|
||||
│ └── hooks.c Implementation of the hooks to execute on boot
|
||||
└── README.md This is the file you are currently reading
|
||||
```
|
||||
Bootloader hooks are **not** supported in legacy `make` build system. They are only supported with `CMake` build system.
|
||||
|
||||
## Note about including weak symbols
|
||||
|
||||
The components in ESP-IDF are compiled as static libraries. Moreover, the bootloaders' hooks are declared as `weak`. Thus, when
|
||||
defining hooks for the bootloader, we **must** tell the compiler to always include our library (`my_boot_hooks`) in the link process.
|
||||
To achieve this, we need to define an extra symbol: `bootloader_hooks_include`. In our case, this symbol is a function defined in
|
||||
`bootloader_components/my_boot_hooks/hooks.c`. This will make the linker include all the symbols contained in that file.
|
@@ -0,0 +1,8 @@
|
||||
idf_component_register(SRCS "hooks.c")
|
||||
|
||||
# We need to force GCC to integrate this static library into the
|
||||
# bootloader link. Indeed, by default, as the hooks in the bootloader are weak,
|
||||
# the linker would just ignore the symbols in the extra. (i.e. not strictly
|
||||
# required)
|
||||
# To do so, we need to define the symbol (function) `bootloader_hooks_include`
|
||||
# within hooks.c source file.
|
@@ -0,0 +1,19 @@
|
||||
#include "esp_log.h"
|
||||
|
||||
/* Function used to tell the linker to include this file
|
||||
* with all its symbols.
|
||||
*/
|
||||
void bootloader_hooks_include(void){
|
||||
}
|
||||
|
||||
|
||||
void bootloader_before_init(void) {
|
||||
/* Keep in my mind that a lot of functions cannot be called from here
|
||||
* as system initialization has not been performed yet, including
|
||||
* BSS, SPI flash, or memory protection. */
|
||||
ESP_LOGI("HOOK", "This hook is called BEFORE bootloader initialization");
|
||||
}
|
||||
|
||||
void bootloader_after_init(void) {
|
||||
ESP_LOGI("HOOK", "This hook is called AFTER bootloader initialization");
|
||||
}
|
18
examples/custom_bootloader/bootloader_hooks/example_test.py
Normal file
18
examples/custom_bootloader/bootloader_hooks/example_test.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import ttfw_idf
|
||||
|
||||
|
||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3'])
|
||||
def test_custom_bootloader_hooks_example(env, _): # type: ignore
|
||||
# Test with default build configurations
|
||||
dut = env.get_dut('main', 'examples/custom_bootloader/bootloader_hooks')
|
||||
dut.start_app()
|
||||
|
||||
# Expect to read both hooks messages
|
||||
dut.expect('This hook is called BEFORE bootloader initialization')
|
||||
dut.expect('This hook is called AFTER bootloader initialization')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_custom_bootloader_hooks_example()
|
@@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "bootloader_hooks_example_main.c"
|
||||
INCLUDE_DIRS ".")
|
@@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
/**
|
||||
* Nothing special is done here, everything interesting in this example
|
||||
* is done in the custom bootloader code, located in:
|
||||
* `bootloader_components/my_boot_hooks/hooks.c`
|
||||
*/
|
||||
printf("User application is loaded and running.\n");
|
||||
}
|
@@ -0,0 +1,4 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
Reference in New Issue
Block a user