mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-04-18 17:35:05 +00:00
Updated elf_loader library to latest from GitHub (#234)
This commit is contained in:
parent
6d1d08944b
commit
bd2786b122
@ -1 +0,0 @@
|
|||||||
ec9b5b8881cf5c38113ed7eab28a71ed7bfc9f477d6faef851f7f59f7a07b536
|
|
||||||
@ -1,5 +1,11 @@
|
|||||||
# ChangeLog
|
# ChangeLog
|
||||||
|
|
||||||
|
## v1.0.0 - 2024-12-09
|
||||||
|
|
||||||
|
* Added support for the following RISC-V chips: ESP32-P4 and ESP32-C6
|
||||||
|
* Added support for linking other components to ELF file
|
||||||
|
* Fixed the issue of getting wrong symbol type
|
||||||
|
|
||||||
## v0.1.0 - 2023-08-14
|
## v0.1.0 - 2023-08-14
|
||||||
|
|
||||||
* Add basic ELF loader component
|
* Add basic ELF loader component
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
if(CONFIG_ELF_LOADER)
|
if(CONFIG_ELF_LOADER)
|
||||||
set(srcs "src/esp_elf_symbol.c"
|
set(srcs "src/esp_elf_symbol.c"
|
||||||
"src/esp_elf.c"
|
"src/esp_elf.c"
|
||||||
"src/esp_elf_adapter.c")
|
"src/esp_elf_adapter.c")
|
||||||
|
|
||||||
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
||||||
list(APPEND srcs "src/arch/esp_elf_xtensa.c")
|
list(APPEND srcs "src/arch/esp_elf_xtensa.c")
|
||||||
@ -11,14 +11,24 @@ if(CONFIG_ELF_LOADER)
|
|||||||
if(CONFIG_IDF_TARGET_ESP32S2 AND (CONFIG_ELF_LOADER_LOAD_PSRAM))
|
if(CONFIG_IDF_TARGET_ESP32S2 AND (CONFIG_ELF_LOADER_LOAD_PSRAM))
|
||||||
list(APPEND srcs "src/soc/esp_elf_esp32s2.c")
|
list(APPEND srcs "src/soc/esp_elf_esp32s2.c")
|
||||||
endif()
|
endif()
|
||||||
|
elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
|
||||||
|
list(APPEND srcs "src/arch/esp_elf_riscv.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(include_dirs "include")
|
set(include_dirs "include")
|
||||||
|
set(ldfragments "linker.lf")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_IDF_TARGET_ESP32P4)
|
||||||
|
set(priv_req spi_flash esp_mm)
|
||||||
|
else()
|
||||||
|
set(priv_req spi_flash)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
INCLUDE_DIRS ${include_dirs}
|
INCLUDE_DIRS ${include_dirs}
|
||||||
PRIV_REQUIRES spi_flash)
|
PRIV_REQUIRES spi_flash ${priv_req}
|
||||||
|
LDFRAGMENTS ${ldfragments})
|
||||||
|
|
||||||
include(package_manager)
|
include(package_manager)
|
||||||
if(CONFIG_ELF_LOADER)
|
if(CONFIG_ELF_LOADER)
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
menu "Espressif ELF Loader Configuration"
|
menu "Espressif ELF Loader Configuration"
|
||||||
visible if (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
|
visible if (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32P4)
|
||||||
|
|
||||||
|
config ELF_LOADER_BUS_ADDRESS_MIRROR
|
||||||
|
bool
|
||||||
|
default y if (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
|
||||||
|
default n if (IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32P4)
|
||||||
|
|
||||||
config ELF_LOADER
|
config ELF_LOADER
|
||||||
bool "Enable Espressif ELF Loader"
|
bool "Enable Espressif ELF Loader"
|
||||||
default y
|
default y
|
||||||
depends on (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
|
depends on (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32P4)
|
||||||
help
|
help
|
||||||
Select this option to enable ELF Loader and show the submenu with ELF Loader configuration choices.
|
Select this option to enable ELF Loader and show the submenu with ELF Loader configuration choices.
|
||||||
|
|
||||||
@ -24,7 +29,7 @@ menu "Espressif ELF Loader Configuration"
|
|||||||
config ELF_LOADER_LOAD_PSRAM
|
config ELF_LOADER_LOAD_PSRAM
|
||||||
bool "Load ELF to PSRAM"
|
bool "Load ELF to PSRAM"
|
||||||
default y
|
default y
|
||||||
depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3) && SPIRAM
|
depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4) && SPIRAM
|
||||||
select ELF_LOADER_CACHE_OFFSET if (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
|
select ELF_LOADER_CACHE_OFFSET if (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
|
||||||
select ELF_LOADER_SET_MMU if IDF_TARGET_ESP32S2
|
select ELF_LOADER_SET_MMU if IDF_TARGET_ESP32S2
|
||||||
help
|
help
|
||||||
|
|||||||
@ -11,6 +11,8 @@ This ELF loader supports following SoCs:
|
|||||||
- ESP32
|
- ESP32
|
||||||
- ESP32-S2, support running ELF in PSRAM
|
- ESP32-S2, support running ELF in PSRAM
|
||||||
- ESP32-S3, support running ELF in PSRAM
|
- ESP32-S3, support running ELF in PSRAM
|
||||||
|
- ESP32-P4, support running ELF in PSRAM
|
||||||
|
- ESP32-C6
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
@ -20,7 +22,7 @@ Add a dependency on this component in your component or project's idf_component.
|
|||||||
|
|
||||||
```yml
|
```yml
|
||||||
dependencies:
|
dependencies:
|
||||||
espressif/elf_loader: "0.*"
|
espressif/elf_loader: "1.*"
|
||||||
```
|
```
|
||||||
|
|
||||||
Enable ELF loader in the menuconfig:
|
Enable ELF loader in the menuconfig:
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
# The script is to generate ELF for application
|
# The script is to generate ELF for application
|
||||||
|
|
||||||
# Trick to temporarily redefine project(). When functions are overriden in CMake, the originals can still be accessed
|
# Trick to temporarily redefine project(). When functions are overridden in CMake, the originals can still be accessed
|
||||||
# using an underscore prefixed function of the same name. The following lines make sure that project calls
|
# using an underscore prefixed function of the same name. The following lines make sure that project calls
|
||||||
# the original project(). See https://cmake.org/pipermail/cmake/2015-October/061751.html.
|
# the original project(). See https://cmake.org/pipermail/cmake/2015-October/061751.html.
|
||||||
function(project_elf)
|
function(project_elf)
|
||||||
@ -35,27 +35,35 @@ macro(project_elf project_name)
|
|||||||
# Remove more unused sections
|
# Remove more unused sections
|
||||||
string(REPLACE "-elf-gcc" "-elf-strip" ${CMAKE_STRIP} ${CMAKE_C_COMPILER})
|
string(REPLACE "-elf-gcc" "-elf-strip" ${CMAKE_STRIP} ${CMAKE_C_COMPILER})
|
||||||
set(strip_flags --strip-unneeded
|
set(strip_flags --strip-unneeded
|
||||||
--remove-section=.xt.lit
|
|
||||||
--remove-section=.xt.prop
|
|
||||||
--remove-section=.comment
|
--remove-section=.comment
|
||||||
--remove-section=.xtensa.info
|
|
||||||
--remove-section=.got.loc
|
--remove-section=.got.loc
|
||||||
--remove-section=.got)
|
--remove-section=.dynamic)
|
||||||
|
|
||||||
# Link input list of libraries to ELF
|
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
||||||
if(ELF_COMPONENTS)
|
list(APPEND strip_flags --remove-section=.xt.lit
|
||||||
foreach(c "${ELF_COMPONENTS}")
|
--remove-section=.xt.prop
|
||||||
set(elf_libs "${elf_libs}" "esp-idf/${c}/lib${c}.a")
|
--remove-section=.xtensa.info)
|
||||||
endforeach()
|
elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
|
||||||
|
list(APPEND strip_flags --remove-section=.riscv.attributes)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(elf_libs ${elf_libs} "${ELF_LIBS}" "esp-idf/main/libmain.a")
|
# Link input list of libraries to ELF
|
||||||
|
list(PREPEND ELF_COMPONENTS "main")
|
||||||
|
if(ELF_COMPONENTS)
|
||||||
|
foreach(c ${ELF_COMPONENTS})
|
||||||
|
list(APPEND elf_libs "esp-idf/${c}/lib${c}.a")
|
||||||
|
list(APPEND elf_dependeces "idf::${c}")
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
if (ELF_LIBS)
|
||||||
|
list(APPEND elf_libs "${ELF_LIBS}")
|
||||||
|
endif()
|
||||||
spaces2list(elf_libs)
|
spaces2list(elf_libs)
|
||||||
|
|
||||||
add_custom_command(OUTPUT elf_app
|
add_custom_command(OUTPUT elf_app
|
||||||
COMMAND ${CMAKE_C_COMPILER} ${cflags} ${elf_libs} -o ${elf_app}
|
COMMAND ${CMAKE_C_COMPILER} ${cflags} ${elf_libs} -o ${elf_app}
|
||||||
COMMAND ${CMAKE_STRIP} ${strip_flags} ${elf_app}
|
COMMAND ${CMAKE_STRIP} ${strip_flags} ${elf_app}
|
||||||
DEPENDS idf::main
|
DEPENDS ${elf_dependeces}
|
||||||
COMMENT "Build ELF: ${elf_app}"
|
COMMENT "Build ELF: ${elf_app}"
|
||||||
)
|
)
|
||||||
add_custom_target(elf ALL DEPENDS elf_app)
|
add_custom_target(elf ALL DEPENDS elf_app)
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
# 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(hello_world)
|
|
||||||
|
|
||||||
include(elf_loader)
|
|
||||||
project_elf(hello_world)
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
## Build ELF file Example
|
|
||||||
|
|
||||||
This example shows how to build ELF file.
|
|
||||||
|
|
||||||
## How to Use Example
|
|
||||||
|
|
||||||
Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`.
|
|
||||||
|
|
||||||
* Note: Only ESP32, ESP32-S2 and ESP32-S3 are supported
|
|
||||||
|
|
||||||
### Build and Flash
|
|
||||||
|
|
||||||
Run `idf.py build` to build project, and when compiling is done you can see `hello_world.app.elf` in `build` directory.
|
|
||||||
@ -1 +0,0 @@
|
|||||||
idf_component_register(SRCS "main.c")
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
elf_loader:
|
|
||||||
version: "0.*"
|
|
||||||
override_path: "../../../../components/elf_loader"
|
|
||||||
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
char buffer[] = "hello world %d\n";
|
|
||||||
static int s_cnt;
|
|
||||||
|
|
||||||
int try_test(void)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
printf(buffer, s_cnt++);
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
try_test();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=n
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
# The following 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(elf-loader)
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
## ELF Loader Example
|
|
||||||
|
|
||||||
This example shows how to use ELF loader to run ELF file.
|
|
||||||
|
|
||||||
## How to Use Example
|
|
||||||
|
|
||||||
Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`.
|
|
||||||
|
|
||||||
* Note: Only ESP32, ESP32-S2 and ESP32-S3 are supported
|
|
||||||
|
|
||||||
### Hardware Required
|
|
||||||
|
|
||||||
* A development board based on espressif ESP32/ESP32-S2/ESP32-S3 SoC
|
|
||||||
* A USB cable for power supply and programming
|
|
||||||
|
|
||||||
### Configure the Project
|
|
||||||
|
|
||||||
Open the project configuration menu (`idf.py menuconfig`).
|
|
||||||
|
|
||||||
In the `Example Configuration` menu:
|
|
||||||
|
|
||||||
* Enable ELF input arguments in the `Support arguments for ELF main` option if necessary.
|
|
||||||
* Set the arguments in the `Arguments of ELF main` option.
|
|
||||||
|
|
||||||
### Build and Flash
|
|
||||||
|
|
||||||
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
|
|
||||||
|
|
||||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
|
||||||
|
|
||||||
## Example Output
|
|
||||||
|
|
||||||
As you run the example, you will see the following log:
|
|
||||||
|
|
||||||
```
|
|
||||||
I (0) cpu_start: Starting scheduler on APP CPU.
|
|
||||||
I (382) elf_loader: Start to relocate ELF
|
|
||||||
I (392) elf_loader: Start to run ELF
|
|
||||||
hello world 0
|
|
||||||
hello world 1
|
|
||||||
hello world 2
|
|
||||||
hello world 3
|
|
||||||
hello world 4
|
|
||||||
hello world 5
|
|
||||||
hello world 6
|
|
||||||
hello world 7
|
|
||||||
hello world 8
|
|
||||||
hello world 9
|
|
||||||
I (10392) elf_loader: Success to exit from APP of ELF
|
|
||||||
```
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
idf_component_register(SRCS "elf_loader_example_main.c"
|
|
||||||
INCLUDE_DIRS ""
|
|
||||||
EMBED_TXTFILES "test.elf")
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
menu "ELF Loader Example Configuration"
|
|
||||||
|
|
||||||
config ELF_LOADER_MAIN_ARGS
|
|
||||||
bool "Support arguments for ELF main"
|
|
||||||
default n
|
|
||||||
|
|
||||||
config ELF_LOADER_MAIN_ARGS_STRING
|
|
||||||
string "Arguments of ELF main"
|
|
||||||
default "main"
|
|
||||||
depends on ELF_LOADER_MAIN_ARGS
|
|
||||||
|
|
||||||
endmenu
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/errno.h>
|
|
||||||
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_elf.h"
|
|
||||||
|
|
||||||
static const char *TAG = "elf_loader";
|
|
||||||
|
|
||||||
extern const uint8_t test_elf_start[] asm("_binary_test_elf_start");
|
|
||||||
extern const uint8_t test_elf_end[] asm("_binary_test_elf_end");
|
|
||||||
|
|
||||||
#ifdef CONFIG_ELF_LOADER_MAIN_ARGS
|
|
||||||
static int elf_args_decode(const char *str, int *argc, char ***argv)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
char **argv_buf;
|
|
||||||
char *s;
|
|
||||||
char *pbuf;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
s = (char *)str;
|
|
||||||
n = 1;
|
|
||||||
len = 1;
|
|
||||||
while (*s) {
|
|
||||||
if (*s++ == ' ') {
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
pbuf = malloc(n * sizeof(char *) + len);
|
|
||||||
if (!pbuf) {
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
argv_buf = (char **)pbuf;
|
|
||||||
s = pbuf + n * sizeof(char *);
|
|
||||||
memcpy(s, str, len);
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
argv_buf[i] = s;
|
|
||||||
|
|
||||||
while (*s != ' ' || *s == 0) {
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*s++ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*argc = n;
|
|
||||||
*argv = argv_buf;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int app_main(void)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
esp_elf_t elf;
|
|
||||||
const uint8_t *buffer = test_elf_start;
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Start to relocate ELF file");
|
|
||||||
|
|
||||||
#ifdef CONFIG_ELF_LOADER_MAIN_ARGS
|
|
||||||
if (strlen(CONFIG_ELF_LOADER_MAIN_ARGS_STRING) <= 0) {
|
|
||||||
ESP_LOGE(TAG, "Failed to check arguments %s",
|
|
||||||
CONFIG_ELF_LOADER_MAIN_ARGS_STRING);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = elf_args_decode(CONFIG_ELF_LOADER_MAIN_ARGS_STRING, &argc, &argv);
|
|
||||||
if (ret < 0) {
|
|
||||||
ESP_LOGE(TAG, "Failed to decode arguments %s errno=%d",
|
|
||||||
CONFIG_ELF_LOADER_MAIN_ARGS_STRING, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
argc = 0;
|
|
||||||
argv = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = esp_elf_init(&elf);
|
|
||||||
if (ret < 0) {
|
|
||||||
ESP_LOGE(TAG, "Failed to initialize ELF file errno=%d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = esp_elf_relocate(&elf, buffer);
|
|
||||||
if (ret < 0) {
|
|
||||||
ESP_LOGE(TAG, "Failed to relocate ELF file errno=%d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Start to run ELF file");
|
|
||||||
|
|
||||||
esp_elf_request(&elf, 0, argc, argv);
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Success to exit from ELF file");
|
|
||||||
|
|
||||||
esp_elf_deinit(&elf);
|
|
||||||
|
|
||||||
#ifdef CONFIG_ELF_LOADER_MAIN_ARGS
|
|
||||||
if (argv) {
|
|
||||||
free(argv);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
elf_loader:
|
|
||||||
version: "0.*"
|
|
||||||
override_path: "../../../../components/elf_loader"
|
|
||||||
|
|
||||||
Binary file not shown.
@ -1,2 +0,0 @@
|
|||||||
CONFIG_SPIRAM=y
|
|
||||||
CONFIG_ELF_LOADER_LOAD_PSRAM=y
|
|
||||||
@ -1 +0,0 @@
|
|||||||
CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n
|
|
||||||
@ -1 +0,0 @@
|
|||||||
CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n
|
|
||||||
@ -1,8 +1,12 @@
|
|||||||
dependencies:
|
version: "1.0.0"
|
||||||
espressif/cmake_utilities:
|
|
||||||
version: 0.*
|
|
||||||
idf:
|
|
||||||
version: '>=4.4.3'
|
|
||||||
description: Espressif ELF(Executable and Linkable Format) Loader
|
description: Espressif ELF(Executable and Linkable Format) Loader
|
||||||
url: https://github.com/espressif/esp-iot-solution/tree/master/components/elf_loader
|
url: https://github.com/espressif/esp-iot-solution/tree/master/components/elf_loader
|
||||||
version: 0.1.0
|
dependencies:
|
||||||
|
idf: ">=4.4.3"
|
||||||
|
espressif/cmake_utilities: "0.*"
|
||||||
|
examples:
|
||||||
|
- path: ../../examples/elf_loader/build_elf_file_example
|
||||||
|
- path: ../../examples/elf_loader/elf_loader_example
|
||||||
|
sbom:
|
||||||
|
supplier: 'Organization: Espressif Systems (Shanghai) CO LTD'
|
||||||
|
originator: 'Organization: Espressif Systems (Shanghai) CO LTD'
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -27,7 +27,7 @@ uintptr_t esp_elf_map_sym(esp_elf_t *elf, uintptr_t sym);
|
|||||||
*
|
*
|
||||||
* @param elf - ELF object pointer
|
* @param elf - ELF object pointer
|
||||||
*
|
*
|
||||||
* @return ESP_OK if sucess or other if failed.
|
* @return ESP_OK if success or other if failed.
|
||||||
*/
|
*/
|
||||||
int esp_elf_init(esp_elf_t *elf);
|
int esp_elf_init(esp_elf_t *elf);
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ int esp_elf_init(esp_elf_t *elf);
|
|||||||
* @param elf - ELF object pointer
|
* @param elf - ELF object pointer
|
||||||
* @param pbuf - ELF data buffer
|
* @param pbuf - ELF data buffer
|
||||||
*
|
*
|
||||||
* @return ESP_OK if sucess or other if failed.
|
* @return ESP_OK if success or other if failed.
|
||||||
*/
|
*/
|
||||||
int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf);
|
int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf);
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf);
|
|||||||
* @param argc - Arguments number
|
* @param argc - Arguments number
|
||||||
* @param argv - Arguments value array
|
* @param argv - Arguments value array
|
||||||
*
|
*
|
||||||
* @return ESP_OK if sucess or other if failed.
|
* @return ESP_OK if success or other if failed.
|
||||||
*/
|
*/
|
||||||
int esp_elf_request(esp_elf_t *elf, int opt, int argc, char *argv[]);
|
int esp_elf_request(esp_elf_t *elf, int opt, int argc, char *argv[]);
|
||||||
|
|
||||||
@ -69,7 +69,16 @@ void esp_elf_deinit(esp_elf_t *elf);
|
|||||||
*
|
*
|
||||||
* @return None
|
* @return None
|
||||||
*/
|
*/
|
||||||
void esp_elf_print_hdr(const uint8_t *pbuf);
|
void esp_elf_print_ehdr(const uint8_t *pbuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Print program header description information of ELF.
|
||||||
|
*
|
||||||
|
* @param pbuf - ELF data buffer
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void esp_elf_print_phdr(const uint8_t *pbuf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Print section header description information of ELF.
|
* @brief Print section header description information of ELF.
|
||||||
|
|||||||
@ -12,12 +12,10 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ELF_ALIGN_SIZE
|
/* Notes: align_size needs to be a power of 2 */
|
||||||
#define ELF_ALIGN_SIZE 4
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ELF_ALIGN(_a) (((_a) + (ELF_ALIGN_SIZE - 1)) & \
|
#define ELF_ALIGN(_a, align_size) (((_a) + (align_size - 1)) & \
|
||||||
(~(ELF_ALIGN_SIZE - 1)))
|
~(align_size - 1))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate block of memory.
|
* @brief Allocate block of memory.
|
||||||
@ -46,7 +44,7 @@ void esp_elf_free(void *ptr);
|
|||||||
* @param sym - ELF symbol table
|
* @param sym - ELF symbol table
|
||||||
* @param addr - Jumping target address
|
* @param addr - Jumping target address
|
||||||
*
|
*
|
||||||
* @return ESP_OK if sucess or other if failed.
|
* @return ESP_OK if success or other if failed.
|
||||||
*/
|
*/
|
||||||
int esp_elf_arch_relocate(esp_elf_t *elf, const elf32_rela_t *rela,
|
int esp_elf_arch_relocate(esp_elf_t *elf, const elf32_rela_t *rela,
|
||||||
const elf32_sym_t *sym, uint32_t addr);
|
const elf32_sym_t *sym, uint32_t addr);
|
||||||
|
|||||||
@ -6,14 +6,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "private/elf_types.h"
|
#include <stdint.h>
|
||||||
#include "elf_symbol.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ESP_ELFSYM_EXPORT(_sym) { #_sym, (void*)&_sym }
|
// Tactility custom -->
|
||||||
|
#define ESP_ELFSYM_EXPORT(_sym) { #_sym, (const void*)&_sym }
|
||||||
|
// <-- Tactility custom
|
||||||
#define ESP_ELFSYM_END { NULL, NULL }
|
#define ESP_ELFSYM_END { NULL, NULL }
|
||||||
|
|
||||||
/** @brief Function symbol description */
|
/** @brief Function symbol description */
|
||||||
@ -32,9 +33,9 @@ struct esp_elfsym {
|
|||||||
*/
|
*/
|
||||||
uintptr_t elf_find_sym(const char *sym_name);
|
uintptr_t elf_find_sym(const char *sym_name);
|
||||||
|
|
||||||
#ifdef CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS
|
// Tactility custom -->
|
||||||
void elf_set_custom_symbols(const struct esp_elfsym* symbols);
|
void elf_set_custom_symbols(const struct esp_elfsym* symbols);
|
||||||
#endif
|
// <-- Tactility custom
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
@ -18,6 +18,29 @@ extern "C" {
|
|||||||
|
|
||||||
#define EI_NIDENT 16 /*!< Magic number and other information length */
|
#define EI_NIDENT 16 /*!< Magic number and other information length */
|
||||||
|
|
||||||
|
/** @brief Type of segment */
|
||||||
|
|
||||||
|
#define PT_NULL 0 /*!< Program header table entry unused */
|
||||||
|
#define PT_LOAD 1 /*!< Loadable program segment */
|
||||||
|
#define PT_DYNAMIC 2 /*!< Dynamic linking information */
|
||||||
|
#define PT_INTERP 3 /*!< Program interpreter */
|
||||||
|
#define PT_NOTE 4 /*!< Auxiliary information */
|
||||||
|
#define PT_SHLIB 5 /*!< Reserved */
|
||||||
|
#define PT_PHDR 6 /*!< Entry for header table itself */
|
||||||
|
#define PT_TLS 7 /*!< Thread-local storage segment */
|
||||||
|
#define PT_NUM 8 /*!< Number of defined types */
|
||||||
|
#define PT_LOOS 0x60000000 /*!< Start of OS-specific */
|
||||||
|
#define PT_GNU_EH_FRAME 0x6474e550 /*!< GCC .eh_frame_hdr segment */
|
||||||
|
#define PT_GNU_STACK 0x6474e551 /*!< Indicates stack executability */
|
||||||
|
#define PT_GNU_RELRO 0x6474e552 /*!< Read-only after relocation */
|
||||||
|
#define PT_LOSUNW 0x6ffffffa
|
||||||
|
#define PT_SUNWBSS 0x6ffffffa /*!< Sun Specific segment */
|
||||||
|
#define PT_SUNWSTACK 0x6ffffffb /*!< Stack segment */
|
||||||
|
#define PT_HISUNW 0x6fffffff
|
||||||
|
#define PT_HIOS 0x6fffffff /*!< End of OS-specific */
|
||||||
|
#define PT_LOPROC 0x70000000 /*!< Start of processor-specific */
|
||||||
|
#define PT_HIPROC 0x7fffffff /*!< End of processor-specific */
|
||||||
|
|
||||||
/** @brief Section Type */
|
/** @brief Section Type */
|
||||||
|
|
||||||
#define SHT_NULL 0 /*!< invalid section header */
|
#define SHT_NULL 0 /*!< invalid section header */
|
||||||
@ -82,6 +105,8 @@ extern "C" {
|
|||||||
#define ELF_SYMTAB ".symtab" /*!< symbol table */
|
#define ELF_SYMTAB ".symtab" /*!< symbol table */
|
||||||
#define ELF_TEXT ".text" /*!< code */
|
#define ELF_TEXT ".text" /*!< code */
|
||||||
#define ELF_DATA_REL_RO ".data.rel.ro" /*!< dynamic read-only data */
|
#define ELF_DATA_REL_RO ".data.rel.ro" /*!< dynamic read-only data */
|
||||||
|
#define ELF_PLT ".plt" /*!< procedure linkage table. */
|
||||||
|
#define ELF_GOT_PLT ".got.plt" /*!< a table where resolved addresses from external functions are stored */
|
||||||
|
|
||||||
/** @brief ELF section and symbol operation */
|
/** @brief ELF section and symbol operation */
|
||||||
|
|
||||||
@ -130,6 +155,19 @@ typedef struct elf32_hdr {
|
|||||||
Elf32_Half shstrndx; /*!< section header table's "section header string table" entry offset */
|
Elf32_Half shstrndx; /*!< section header table's "section header string table" entry offset */
|
||||||
} elf32_hdr_t;
|
} elf32_hdr_t;
|
||||||
|
|
||||||
|
/** @brief Program Header */
|
||||||
|
|
||||||
|
typedef struct elf32_phdr {
|
||||||
|
Elf32_Word type; /* segment type */
|
||||||
|
Elf32_Off offset; /* segment offset */
|
||||||
|
Elf32_Addr vaddr; /* virtual address of segment */
|
||||||
|
Elf32_Addr paddr; /* physical address - ignored? */
|
||||||
|
Elf32_Word filesz; /* number of bytes in file for seg. */
|
||||||
|
Elf32_Word memsz; /* number of bytes in mem. for seg. */
|
||||||
|
Elf32_Word flags; /* flags */
|
||||||
|
Elf32_Word align; /* memory alignment */
|
||||||
|
} elf32_phdr_t;
|
||||||
|
|
||||||
/** @brief Section Header */
|
/** @brief Section Header */
|
||||||
|
|
||||||
typedef struct elf32_shdr {
|
typedef struct elf32_shdr {
|
||||||
@ -184,13 +222,17 @@ typedef struct esp_elf_sec {
|
|||||||
/** @brief ELF object */
|
/** @brief ELF object */
|
||||||
|
|
||||||
typedef struct esp_elf {
|
typedef struct esp_elf {
|
||||||
|
unsigned char *psegment; /*!< segment buffer pointer */
|
||||||
|
|
||||||
|
uint32_t svaddr; /*!< start virtual address of segment */
|
||||||
|
|
||||||
unsigned char *ptext; /*!< instruction buffer pointer */
|
unsigned char *ptext; /*!< instruction buffer pointer */
|
||||||
|
|
||||||
unsigned char *pdata; /*!< data buffer pointer */
|
unsigned char *pdata; /*!< data buffer pointer */
|
||||||
|
|
||||||
esp_elf_sec_t sec[ELF_SECS]; /*!< ".bss", "data", "rodata", ".text" */
|
esp_elf_sec_t sec[ELF_SECS]; /*!< ".bss", "data", "rodata", ".text" */
|
||||||
|
|
||||||
int (*entry)(int argc, char *argv[]); /*!< Entry pointer of ELF */
|
int (*entry)(int argc, char *argv[]); /*!< Entry pointer of ELF */
|
||||||
|
|
||||||
#ifdef CONFIG_ELF_LOADER_SET_MMU
|
#ifdef CONFIG_ELF_LOADER_SET_MMU
|
||||||
uint32_t text_off; /* .text symbol offset */
|
uint32_t text_off; /* .text symbol offset */
|
||||||
|
|||||||
14
Libraries/elf_loader/linker.lf
Normal file
14
Libraries/elf_loader/linker.lf
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[sections:elf_loader_got_plt]
|
||||||
|
entries:
|
||||||
|
.got.plt
|
||||||
|
.got
|
||||||
|
|
||||||
|
[scheme:elf_loader_default]
|
||||||
|
entries:
|
||||||
|
elf_loader_got_plt -> flash_rodata
|
||||||
|
|
||||||
|
[mapping:elf_loader]
|
||||||
|
archive: *
|
||||||
|
entries:
|
||||||
|
* (elf_loader_default);
|
||||||
|
elf_loader_got_plt -> flash_rodata KEEP() SURROUND(_esp_elf_loader_got_plt)
|
||||||
112
Libraries/elf_loader/src/arch/esp_elf_riscv.c
Normal file
112
Libraries/elf_loader/src/arch/esp_elf_riscv.c
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include "esp_elf.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "private/elf_platform.h"
|
||||||
|
|
||||||
|
/** @brief RISC-V relocations defined by the ABIs */
|
||||||
|
|
||||||
|
#define R_RISCV_NONE 0
|
||||||
|
#define R_RISCV_32 1
|
||||||
|
#define R_RISCV_64 2
|
||||||
|
#define R_RISCV_RELATIVE 3
|
||||||
|
#define R_RISCV_COPY 4
|
||||||
|
#define R_RISCV_JUMP_SLOT 5
|
||||||
|
#define R_RISCV_TLS_DTPMOD32 6
|
||||||
|
#define R_RISCV_TLS_DTPMOD64 7
|
||||||
|
#define R_RISCV_TLS_DTPREL32 8
|
||||||
|
#define R_RISCV_TLS_DTPREL64 9
|
||||||
|
#define R_RISCV_TLS_TPREL32 10
|
||||||
|
#define R_RISCV_TLS_TPREL64 11
|
||||||
|
#define R_RISCV_TLS_DESC 12
|
||||||
|
#define R_RISCV_BRANCH 16
|
||||||
|
#define R_RISCV_JAL 17
|
||||||
|
#define R_RISCV_CALL 18
|
||||||
|
#define R_RISCV_CALL_PLT 19
|
||||||
|
#define R_RISCV_GOT_HI20 20
|
||||||
|
#define R_RISCV_TLS_GOT_HI20 21
|
||||||
|
#define R_RISCV_TLS_GD_HI20 22
|
||||||
|
#define R_RISCV_PCREL_HI20 23
|
||||||
|
#define R_RISCV_PCREL_LO12_I 24
|
||||||
|
#define R_RISCV_PCREL_LO12_S 25
|
||||||
|
#define R_RISCV_HI20 26
|
||||||
|
#define R_RISCV_LO12_I 27
|
||||||
|
#define R_RISCV_LO12_S 28
|
||||||
|
#define R_RISCV_TPREL_HI20 29
|
||||||
|
#define R_RISCV_TPREL_LO12_I 30
|
||||||
|
#define R_RISCV_TPREL_LO12_S 31
|
||||||
|
#define R_RISCV_TPREL_ADD 32
|
||||||
|
#define R_RISCV_ADD8 33
|
||||||
|
#define R_RISCV_ADD16 34
|
||||||
|
#define R_RISCV_ADD32 35
|
||||||
|
#define R_RISCV_ADD64 36
|
||||||
|
#define R_RISCV_SUB8 37
|
||||||
|
#define R_RISCV_SUB16 38
|
||||||
|
#define R_RISCV_SUB32 39
|
||||||
|
#define R_RISCV_SUB64 40
|
||||||
|
#define R_RISCV_GNU_VTINHERIT 41
|
||||||
|
#define R_RISCV_GNU_VTENTRY 42
|
||||||
|
#define R_RISCV_ALIGN 43
|
||||||
|
#define R_RISCV_RVC_BRANCH 44
|
||||||
|
#define R_RISCV_RVC_JUMP 45
|
||||||
|
#define R_RISCV_RVC_LUI 46
|
||||||
|
#define R_RISCV_RELAX 51
|
||||||
|
#define R_RISCV_SUB6 52
|
||||||
|
#define R_RISCV_SET6 53
|
||||||
|
#define R_RISCV_SET8 54
|
||||||
|
#define R_RISCV_SET16 55
|
||||||
|
#define R_RISCV_SET32 56
|
||||||
|
#define R_RISCV_32_PCREL 57
|
||||||
|
#define R_RISCV_IRELATIVE 58
|
||||||
|
#define R_RISCV_PLT32 59
|
||||||
|
|
||||||
|
static const char *TAG = "elf_arch";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Relocates target architecture symbol of ELF
|
||||||
|
*
|
||||||
|
* @param elf - ELF object pointer
|
||||||
|
* @param rela - Relocated symbol data
|
||||||
|
* @param sym - ELF symbol table
|
||||||
|
* @param addr - Jumping target address
|
||||||
|
*
|
||||||
|
* @return ESP_OK if success or other if failed.
|
||||||
|
*/
|
||||||
|
int esp_elf_arch_relocate(esp_elf_t *elf, const elf32_rela_t *rela,
|
||||||
|
const elf32_sym_t *sym, uint32_t addr)
|
||||||
|
{
|
||||||
|
uint32_t *where;
|
||||||
|
|
||||||
|
assert(elf && rela);
|
||||||
|
|
||||||
|
where = (uint32_t *)((uint8_t *)elf->psegment + rela->offset + elf->svaddr);
|
||||||
|
ESP_LOGD(TAG, "type: %d, where=%p addr=0x%x offset=0x%x",
|
||||||
|
ELF_R_TYPE(rela->info), where, (int)elf->psegment, (int)rela->offset);
|
||||||
|
|
||||||
|
/* Do relocation based on relocation type */
|
||||||
|
|
||||||
|
switch (ELF_R_TYPE(rela->info)) {
|
||||||
|
case R_RISCV_NONE:
|
||||||
|
break;
|
||||||
|
case R_RISCV_32:
|
||||||
|
*where = addr + rela->addend;
|
||||||
|
break;
|
||||||
|
case R_RISCV_RELATIVE:
|
||||||
|
*where = (Elf32_Addr)((uint8_t *)elf->psegment - elf->svaddr + rela->addend);
|
||||||
|
break;
|
||||||
|
case R_RISCV_JUMP_SLOT:
|
||||||
|
*where = addr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ESP_LOGE(TAG, "info=%d is not supported\n", ELF_R_TYPE(rela->info));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -70,7 +70,7 @@ static const char *TAG = "elf_arch";
|
|||||||
* @param sym - ELF symbol table
|
* @param sym - ELF symbol table
|
||||||
* @param addr - Jumping target address
|
* @param addr - Jumping target address
|
||||||
*
|
*
|
||||||
* @return ESP_OK if sucess or other if failed.
|
* @return ESP_OK if success or other if failed.
|
||||||
*/
|
*/
|
||||||
int esp_elf_arch_relocate(esp_elf_t *elf, const elf32_rela_t *rela,
|
int esp_elf_arch_relocate(esp_elf_t *elf, const elf32_rela_t *rela,
|
||||||
const elf32_sym_t *sym, uint32_t addr)
|
const elf32_sym_t *sym, uint32_t addr)
|
||||||
@ -82,7 +82,8 @@ int esp_elf_arch_relocate(esp_elf_t *elf, const elf32_rela_t *rela,
|
|||||||
|
|
||||||
where = (uint32_t *)esp_elf_map_sym(elf, rela->offset);
|
where = (uint32_t *)esp_elf_map_sym(elf, rela->offset);
|
||||||
|
|
||||||
ESP_LOGD(TAG, "where=%p addr=%x offset=%x\n", where, (int)addr, (int)rela->offset);
|
ESP_LOGD(TAG, "type: %d, where=%p addr=0x%x offset=0x%x\n",
|
||||||
|
ELF_R_TYPE(rela->info), where, (int)addr, (int)rela->offset);
|
||||||
|
|
||||||
switch (ELF_R_TYPE(rela->info)) {
|
switch (ELF_R_TYPE(rela->info)) {
|
||||||
case R_XTENSA_RELATIVE:
|
case R_XTENSA_RELATIVE:
|
||||||
|
|||||||
@ -1,149 +1,111 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/errno.h>
|
#include <sys/errno.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
#include "elf_symbol.h"
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
#include "hal/cache_ll.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "private/elf_symbol.h"
|
||||||
#include "private/elf_platform.h"
|
#include "private/elf_platform.h"
|
||||||
|
|
||||||
#define stype(_s, _t) ((_s)->type == (_t))
|
#define stype(_s, _t) ((_s)->type == (_t))
|
||||||
#define sflags(_s, _f) (((_s)->flags & (_f)) == (_f))
|
#define sflags(_s, _f) (((_s)->flags & (_f)) == (_f))
|
||||||
|
#define ADDR_OFFSET (0x400)
|
||||||
|
|
||||||
static const char *TAG = "ELF";
|
static const char *TAG = "ELF";
|
||||||
|
|
||||||
/**
|
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
|
||||||
* @brief Map symbol's address of ELF to physic space.
|
|
||||||
*
|
|
||||||
* @param elf - ELF object pointer
|
|
||||||
* @param sym - ELF symbol address
|
|
||||||
*
|
|
||||||
* @return ESP_OK if sucess or other if failed.
|
|
||||||
*/
|
|
||||||
uintptr_t esp_elf_map_sym(esp_elf_t *elf, uintptr_t sym)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < ELF_SECS; i++) {
|
|
||||||
if ((sym >= elf->sec[i].v_addr) &&
|
|
||||||
(sym < (elf->sec[i].v_addr + elf->sec[i].size))) {
|
|
||||||
return sym - elf->sec[i].v_addr + elf->sec[i].addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize ELF object.
|
* @brief Load ELF section.
|
||||||
*
|
|
||||||
* @param elf - ELF object pointer
|
|
||||||
*
|
|
||||||
* @return ESP_OK if sucess or other if failed.
|
|
||||||
*/
|
|
||||||
int esp_elf_init(esp_elf_t *elf)
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "ELF loader version: %d.%d.%d", ELF_LOADER_VER_MAJOR, ELF_LOADER_VER_MINOR, ELF_LOADER_VER_PATCH);
|
|
||||||
|
|
||||||
if (!elf) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(elf, 0, sizeof(esp_elf_t));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Decode and relocate ELF data.
|
|
||||||
*
|
*
|
||||||
* @param elf - ELF object pointer
|
* @param elf - ELF object pointer
|
||||||
* @param pbuf - ELF data buffer
|
* @param pbuf - ELF data buffer
|
||||||
*
|
*
|
||||||
* @return ESP_OK if sucess or other if failed.
|
* @return ESP_OK if success or other if failed.
|
||||||
*/
|
*/
|
||||||
int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
|
|
||||||
|
static int esp_elf_load_section(esp_elf_t *elf, const uint8_t *pbuf)
|
||||||
{
|
{
|
||||||
uint32_t entry;
|
uint32_t entry;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
|
||||||
const elf32_hdr_t *phdr;
|
const elf32_hdr_t *ehdr = (const elf32_hdr_t *)pbuf;
|
||||||
const elf32_shdr_t *pshdr;
|
const elf32_shdr_t *shdr = (const elf32_shdr_t *)(pbuf + ehdr->shoff);
|
||||||
const char *shstrab;
|
const char *shstrab = (const char *)pbuf + shdr[ehdr->shstrndx].offset;
|
||||||
|
|
||||||
if (!elf || !pbuf) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
phdr = (const elf32_hdr_t *)pbuf;
|
|
||||||
pshdr = (const elf32_shdr_t *)(pbuf + phdr->shoff);
|
|
||||||
shstrab = (const char *)pbuf + pshdr[phdr->shstrndx].offset;
|
|
||||||
|
|
||||||
/* Calculate ELF image size */
|
/* Calculate ELF image size */
|
||||||
|
|
||||||
for (uint32_t i = 0; i < phdr->shnum; i++) {
|
for (uint32_t i = 0; i < ehdr->shnum; i++) {
|
||||||
const char *name = shstrab + pshdr[i].name;
|
const char *name = shstrab + shdr[i].name;
|
||||||
|
|
||||||
if (stype(&pshdr[i], SHT_PROGBITS) && sflags(&pshdr[i], SHF_ALLOC)) {
|
if (stype(&shdr[i], SHT_PROGBITS) && sflags(&shdr[i], SHF_ALLOC)) {
|
||||||
if (sflags(&pshdr[i], SHF_EXECINSTR) && !strcmp(ELF_TEXT, name)) {
|
if (sflags(&shdr[i], SHF_EXECINSTR) && !strcmp(ELF_TEXT, name)) {
|
||||||
ESP_LOGD(TAG, ".text sec addr=0x%08x size=0x%08x offset=0x%08x",
|
ESP_LOGD(TAG, ".text sec addr=0x%08x size=0x%08x offset=0x%08x",
|
||||||
pshdr[i].addr, pshdr[i].size, pshdr[i].offset);
|
shdr[i].addr, shdr[i].size, shdr[i].offset);
|
||||||
|
|
||||||
elf->sec[ELF_SEC_TEXT].v_addr = pshdr[i].addr;
|
elf->sec[ELF_SEC_TEXT].v_addr = shdr[i].addr;
|
||||||
elf->sec[ELF_SEC_TEXT].size = ELF_ALIGN(pshdr[i].size);
|
elf->sec[ELF_SEC_TEXT].size = ELF_ALIGN(shdr[i].size, 4);
|
||||||
elf->sec[ELF_SEC_TEXT].offset = pshdr[i].offset;
|
elf->sec[ELF_SEC_TEXT].offset = shdr[i].offset;
|
||||||
|
|
||||||
ESP_LOGD(TAG, ".text offset is 0x%lx size is 0x%x",
|
ESP_LOGD(TAG, ".text offset is 0x%lx size is 0x%x",
|
||||||
elf->sec[ELF_SEC_TEXT].offset,
|
elf->sec[ELF_SEC_TEXT].offset,
|
||||||
elf->sec[ELF_SEC_TEXT].size);
|
elf->sec[ELF_SEC_TEXT].size);
|
||||||
} else if (sflags(&pshdr[i], SHF_WRITE) && !strcmp(ELF_DATA, name)) {
|
} else if (sflags(&shdr[i], SHF_WRITE) && !strcmp(ELF_DATA, name)) {
|
||||||
ESP_LOGD(TAG, ".data sec addr=0x%08x size=0x%08x offset=0x%08x",
|
ESP_LOGD(TAG, ".data sec addr=0x%08x size=0x%08x offset=0x%08x",
|
||||||
pshdr[i].addr, pshdr[i].size, pshdr[i].offset);
|
shdr[i].addr, shdr[i].size, shdr[i].offset);
|
||||||
|
|
||||||
elf->sec[ELF_SEC_DATA].v_addr = pshdr[i].addr;
|
elf->sec[ELF_SEC_DATA].v_addr = shdr[i].addr;
|
||||||
elf->sec[ELF_SEC_DATA].size = pshdr[i].size;
|
elf->sec[ELF_SEC_DATA].size = shdr[i].size;
|
||||||
elf->sec[ELF_SEC_DATA].offset = pshdr[i].offset;
|
elf->sec[ELF_SEC_DATA].offset = shdr[i].offset;
|
||||||
|
|
||||||
ESP_LOGD(TAG, ".data offset is 0x%lx size is 0x%x",
|
ESP_LOGD(TAG, ".data offset is 0x%lx size is 0x%x",
|
||||||
elf->sec[ELF_SEC_DATA].offset,
|
elf->sec[ELF_SEC_DATA].offset,
|
||||||
elf->sec[ELF_SEC_DATA].size);
|
elf->sec[ELF_SEC_DATA].size);
|
||||||
} else if (!strcmp(ELF_RODATA, name)) {
|
} else if (!strcmp(ELF_RODATA, name)) {
|
||||||
ESP_LOGD(TAG, ".rodata sec addr=0x%08x size=0x%08x offset=0x%08x",
|
ESP_LOGD(TAG, ".rodata sec addr=0x%08x size=0x%08x offset=0x%08x",
|
||||||
pshdr[i].addr, pshdr[i].size, pshdr[i].offset);
|
shdr[i].addr, shdr[i].size, shdr[i].offset);
|
||||||
|
|
||||||
elf->sec[ELF_SEC_RODATA].v_addr = pshdr[i].addr;
|
elf->sec[ELF_SEC_RODATA].v_addr = shdr[i].addr;
|
||||||
elf->sec[ELF_SEC_RODATA].size = pshdr[i].size;
|
elf->sec[ELF_SEC_RODATA].size = shdr[i].size;
|
||||||
elf->sec[ELF_SEC_RODATA].offset = pshdr[i].offset;
|
elf->sec[ELF_SEC_RODATA].offset = shdr[i].offset;
|
||||||
|
|
||||||
ESP_LOGD(TAG, ".rodata offset is 0x%lx size is 0x%x",
|
ESP_LOGD(TAG, ".rodata offset is 0x%lx size is 0x%x",
|
||||||
elf->sec[ELF_SEC_RODATA].offset,
|
elf->sec[ELF_SEC_RODATA].offset,
|
||||||
elf->sec[ELF_SEC_RODATA].size);
|
elf->sec[ELF_SEC_RODATA].size);
|
||||||
} else if (!strcmp(ELF_DATA_REL_RO, name)) {
|
} else if (!strcmp(ELF_DATA_REL_RO, name)) {
|
||||||
ESP_LOGD(TAG, ".data.rel.ro sec addr=0x%08x size=0x%08x offset=0x%08x",
|
ESP_LOGD(TAG, ".data.rel.ro sec addr=0x%08x size=0x%08x offset=0x%08x",
|
||||||
pshdr[i].addr, pshdr[i].size, pshdr[i].offset);
|
shdr[i].addr, shdr[i].size, shdr[i].offset);
|
||||||
|
|
||||||
elf->sec[ELF_SEC_DRLRO].v_addr = pshdr[i].addr;
|
elf->sec[ELF_SEC_DRLRO].v_addr = shdr[i].addr;
|
||||||
elf->sec[ELF_SEC_DRLRO].size = pshdr[i].size;
|
elf->sec[ELF_SEC_DRLRO].size = shdr[i].size;
|
||||||
elf->sec[ELF_SEC_DRLRO].offset = pshdr[i].offset;
|
elf->sec[ELF_SEC_DRLRO].offset = shdr[i].offset;
|
||||||
|
|
||||||
ESP_LOGD(TAG, ".data.rel.ro offset is 0x%lx size is 0x%x",
|
ESP_LOGD(TAG, ".data.rel.ro offset is 0x%lx size is 0x%x",
|
||||||
elf->sec[ELF_SEC_DRLRO].offset,
|
elf->sec[ELF_SEC_DRLRO].offset,
|
||||||
elf->sec[ELF_SEC_DRLRO].size);
|
elf->sec[ELF_SEC_DRLRO].size);
|
||||||
}
|
}
|
||||||
} else if (stype(&pshdr[i], SHT_NOBITS) &&
|
} else if (stype(&shdr[i], SHT_NOBITS) &&
|
||||||
sflags(&pshdr[i], SHF_ALLOC | SHF_WRITE) &&
|
sflags(&shdr[i], SHF_ALLOC | SHF_WRITE) &&
|
||||||
!strcmp(ELF_BSS, name)) {
|
!strcmp(ELF_BSS, name)) {
|
||||||
ESP_LOGD(TAG, ".bss sec addr=0x%08x size=0x%08x offset=0x%08x",
|
ESP_LOGD(TAG, ".bss sec addr=0x%08x size=0x%08x offset=0x%08x",
|
||||||
pshdr[i].addr, pshdr[i].size, pshdr[i].offset);
|
shdr[i].addr, shdr[i].size, shdr[i].offset);
|
||||||
|
|
||||||
elf->sec[ELF_SEC_BSS].v_addr = pshdr[i].addr;
|
elf->sec[ELF_SEC_BSS].v_addr = shdr[i].addr;
|
||||||
elf->sec[ELF_SEC_BSS].size = pshdr[i].size;
|
elf->sec[ELF_SEC_BSS].size = shdr[i].size;
|
||||||
elf->sec[ELF_SEC_BSS].offset = pshdr[i].offset;
|
elf->sec[ELF_SEC_BSS].offset = shdr[i].offset;
|
||||||
|
|
||||||
ESP_LOGD(TAG, ".bss offset is 0x%lx size is 0x%x",
|
ESP_LOGD(TAG, ".bss offset is 0x%lx size is 0x%x",
|
||||||
elf->sec[ELF_SEC_BSS].offset,
|
elf->sec[ELF_SEC_BSS].offset,
|
||||||
@ -174,7 +136,7 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dump ".text" from ELF to excutable space memory */
|
/* Dump ".text" from ELF to executable space memory */
|
||||||
|
|
||||||
elf->sec[ELF_SEC_TEXT].addr = (Elf32_Addr)elf->ptext;
|
elf->sec[ELF_SEC_TEXT].addr = (Elf32_Addr)elf->ptext;
|
||||||
memcpy(elf->ptext, pbuf + elf->sec[ELF_SEC_TEXT].offset,
|
memcpy(elf->ptext, pbuf + elf->sec[ELF_SEC_TEXT].offset,
|
||||||
@ -183,6 +145,7 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
|
|||||||
#ifdef CONFIG_ELF_LOADER_SET_MMU
|
#ifdef CONFIG_ELF_LOADER_SET_MMU
|
||||||
if (esp_elf_arch_init_mmu(elf)) {
|
if (esp_elf_arch_init_mmu(elf)) {
|
||||||
esp_elf_free(elf->ptext);
|
esp_elf_free(elf->ptext);
|
||||||
|
esp_elf_free(elf->pdata);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -231,8 +194,8 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
|
|||||||
|
|
||||||
/* Set ELF entry */
|
/* Set ELF entry */
|
||||||
|
|
||||||
entry = phdr->entry + elf->sec[ELF_SEC_TEXT].addr -
|
entry = ehdr->entry + elf->sec[ELF_SEC_TEXT].addr -
|
||||||
elf->sec[ELF_SEC_TEXT].v_addr;
|
elf->sec[ELF_SEC_TEXT].v_addr;
|
||||||
|
|
||||||
#ifdef CONFIG_ELF_LOADER_CACHE_OFFSET
|
#ifdef CONFIG_ELF_LOADER_CACHE_OFFSET
|
||||||
elf->entry = (void *)elf_remap_text(elf, (uintptr_t)entry);
|
elf->entry = (void *)elf_remap_text(elf, (uintptr_t)entry);
|
||||||
@ -240,21 +203,203 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
|
|||||||
elf->entry = (void *)entry;
|
elf->entry = (void *)entry;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load ELF segment.
|
||||||
|
*
|
||||||
|
* @param elf - ELF object pointer
|
||||||
|
* @param pbuf - ELF data buffer
|
||||||
|
*
|
||||||
|
* @return ESP_OK if success or other if failed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int esp_elf_load_segment(esp_elf_t *elf, const uint8_t *pbuf)
|
||||||
|
{
|
||||||
|
uint32_t size;
|
||||||
|
bool first_segment = false;
|
||||||
|
Elf32_Addr vaddr_s = 0;
|
||||||
|
Elf32_Addr vaddr_e = 0;
|
||||||
|
|
||||||
|
const elf32_hdr_t *ehdr = (const elf32_hdr_t *)pbuf;
|
||||||
|
const elf32_phdr_t *phdr = (const elf32_phdr_t *)(pbuf + ehdr->phoff);
|
||||||
|
|
||||||
|
for (int i = 0; i < ehdr->phnum; i++) {
|
||||||
|
if (phdr[i].type != PT_LOAD) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phdr[i].memsz < phdr[i].filesz) {
|
||||||
|
ESP_LOGE(TAG, "Invalid segment[%d], memsz: %d, filesz: %d",
|
||||||
|
i, phdr[i].memsz, phdr[i].filesz);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first_segment == true) {
|
||||||
|
vaddr_s = phdr[i].vaddr;
|
||||||
|
vaddr_e = phdr[i].vaddr + phdr[i].memsz;
|
||||||
|
first_segment = true;
|
||||||
|
if (vaddr_e < vaddr_s) {
|
||||||
|
ESP_LOGE(TAG, "Invalid segment[%d], vaddr: 0x%x, memsz: %d",
|
||||||
|
i, phdr[i].vaddr, phdr[i].memsz);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (phdr[i].vaddr < vaddr_e) {
|
||||||
|
ESP_LOGE(TAG, "Invalid segment[%d], should not overlap, vaddr: 0x%x, vaddr_e: 0x%x\n",
|
||||||
|
i, phdr[i].vaddr, vaddr_e);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phdr[i].vaddr > vaddr_e + ADDR_OFFSET) {
|
||||||
|
ESP_LOGI(TAG, "Too much padding before segment[%d], padding: %d",
|
||||||
|
i, phdr[i].vaddr - vaddr_e);
|
||||||
|
}
|
||||||
|
|
||||||
|
vaddr_e = phdr[i].vaddr + phdr[i].memsz;
|
||||||
|
if (vaddr_e < phdr[i].vaddr) {
|
||||||
|
ESP_LOGE(TAG, "Invalid segment[%d], address overflow, vaddr: 0x%x, vaddr_e: 0x%x\n",
|
||||||
|
i, phdr[i].vaddr, vaddr_e);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "LOAD segment[%d], vaddr: 0x%x, memsize: 0x%08x",
|
||||||
|
i, phdr[i].vaddr, phdr[i].memsz);
|
||||||
|
}
|
||||||
|
|
||||||
|
size = vaddr_e - vaddr_s;
|
||||||
|
if (size == 0) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
elf->svaddr = vaddr_s;
|
||||||
|
elf->psegment = esp_elf_malloc(size, true);
|
||||||
|
if (!elf->psegment) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(elf->psegment, 0, size);
|
||||||
|
|
||||||
|
/* Dump "PT_LOAD" from ELF to memory space */
|
||||||
|
|
||||||
|
for (int i = 0; i < ehdr->phnum; i++) {
|
||||||
|
if (phdr[i].type == PT_LOAD) {
|
||||||
|
memcpy(elf->psegment + phdr[i].vaddr - vaddr_s,
|
||||||
|
(uint8_t *)pbuf + phdr[i].offset, phdr[i].filesz);
|
||||||
|
ESP_LOGD(TAG, "Copy segment[%d], mem_addr: 0x%x, vaddr: 0x%x, size: 0x%08x",
|
||||||
|
i, (int)((uint8_t *)elf->psegment + phdr[i].vaddr - vaddr_s),
|
||||||
|
phdr[i].vaddr, phdr[i].filesz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
cache_ll_writeback_all(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA, CACHE_LL_ID_ALL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
elf->entry = (void *)((uint8_t *)elf->psegment + ehdr->entry - vaddr_s);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Map symbol's address of ELF to physic space.
|
||||||
|
*
|
||||||
|
* @param elf - ELF object pointer
|
||||||
|
* @param sym - ELF symbol address
|
||||||
|
*
|
||||||
|
* @return ESP_OK if success or other if failed.
|
||||||
|
*/
|
||||||
|
uintptr_t esp_elf_map_sym(esp_elf_t *elf, uintptr_t sym)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ELF_SECS; i++) {
|
||||||
|
if ((sym >= elf->sec[i].v_addr) &&
|
||||||
|
(sym < (elf->sec[i].v_addr + elf->sec[i].size))) {
|
||||||
|
return sym - elf->sec[i].v_addr + elf->sec[i].addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize ELF object.
|
||||||
|
*
|
||||||
|
* @param elf - ELF object pointer
|
||||||
|
*
|
||||||
|
* @return ESP_OK if success or other if failed.
|
||||||
|
*/
|
||||||
|
int esp_elf_init(esp_elf_t *elf)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "ELF loader version: %d.%d.%d", ELF_LOADER_VER_MAJOR, ELF_LOADER_VER_MINOR, ELF_LOADER_VER_PATCH);
|
||||||
|
|
||||||
|
if (!elf) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(elf, 0, sizeof(esp_elf_t));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decode and relocate ELF data.
|
||||||
|
*
|
||||||
|
* @param elf - ELF object pointer
|
||||||
|
* @param pbuf - ELF data buffer
|
||||||
|
*
|
||||||
|
* @return ESP_OK if success or other if failed.
|
||||||
|
*/
|
||||||
|
int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
const elf32_hdr_t *ehdr;
|
||||||
|
const elf32_shdr_t *shdr;
|
||||||
|
const char *shstrab;
|
||||||
|
|
||||||
|
if (!elf || !pbuf) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ehdr = (const elf32_hdr_t *)pbuf;
|
||||||
|
shdr = (const elf32_shdr_t *)(pbuf + ehdr->shoff);
|
||||||
|
shstrab = (const char *)pbuf + shdr[ehdr->shstrndx].offset;
|
||||||
|
|
||||||
|
/* Load section or segment to memory space */
|
||||||
|
|
||||||
|
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
|
||||||
|
ret = esp_elf_load_section(elf, pbuf);
|
||||||
|
#else
|
||||||
|
ret = esp_elf_load_segment(elf, pbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
ESP_LOGE(TAG, "Error to load elf file, ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "elf->entry=%p\n", elf->entry);
|
||||||
|
|
||||||
/* Relocation section data */
|
/* Relocation section data */
|
||||||
|
|
||||||
for (uint32_t i = 0; i < phdr->shnum; i++) {
|
for (uint32_t i = 0; i < ehdr->shnum; i++) {
|
||||||
if (stype(&pshdr[i], SHT_RELA)) {
|
if (stype(&shdr[i], SHT_RELA)) {
|
||||||
uint32_t nr_reloc;
|
uint32_t nr_reloc;
|
||||||
const elf32_rela_t *rela;
|
const elf32_rela_t *rela;
|
||||||
const elf32_sym_t *symtab;
|
const elf32_sym_t *symtab;
|
||||||
const char *strtab;
|
const char *strtab;
|
||||||
|
|
||||||
nr_reloc = pshdr[i].size / sizeof(elf32_rela_t);
|
nr_reloc = shdr[i].size / sizeof(elf32_rela_t);
|
||||||
rela = (const elf32_rela_t *)(pbuf + pshdr[i].offset);
|
rela = (const elf32_rela_t *)(pbuf + shdr[i].offset);
|
||||||
symtab = (const elf32_sym_t *)(pbuf + pshdr[pshdr[i].link].offset);
|
symtab = (const elf32_sym_t *)(pbuf + shdr[shdr[i].link].offset);
|
||||||
strtab = (const char *)(pbuf + pshdr[pshdr[pshdr[i].link].link].offset);
|
strtab = (const char *)(pbuf + shdr[shdr[shdr[i].link].link].offset);
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Section %s has %d symbol tables", shstrab + pshdr[i].name, (int)nr_reloc);
|
ESP_LOGD(TAG, "Section %s has %d symbol tables", shstrab + shdr[i].name, (int)nr_reloc);
|
||||||
|
|
||||||
for (int i = 0; i < nr_reloc; i++) {
|
for (int i = 0; i < nr_reloc; i++) {
|
||||||
int type;
|
int type;
|
||||||
@ -265,8 +410,8 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
|
|||||||
|
|
||||||
const elf32_sym_t *sym = &symtab[ELF_R_SYM(rela_buf.info)];
|
const elf32_sym_t *sym = &symtab[ELF_R_SYM(rela_buf.info)];
|
||||||
|
|
||||||
type = ELF_R_TYPE(rela->info);
|
type = ELF_R_TYPE(rela_buf.info);
|
||||||
if (type == STT_COMMON) {
|
if (type == STT_COMMON || type == STT_OBJECT || type == STT_SECTION) {
|
||||||
const char *comm_name = strtab + sym->name;
|
const char *comm_name = strtab + sym->name;
|
||||||
|
|
||||||
if (comm_name[0]) {
|
if (comm_name[0]) {
|
||||||
@ -274,8 +419,12 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
|
|||||||
|
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
ESP_LOGE(TAG, "Can't find common %s", strtab + sym->name);
|
ESP_LOGE(TAG, "Can't find common %s", strtab + sym->name);
|
||||||
|
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
|
||||||
esp_elf_free(elf->pdata);
|
esp_elf_free(elf->pdata);
|
||||||
esp_elf_free(elf->ptext);
|
esp_elf_free(elf->ptext);
|
||||||
|
#else
|
||||||
|
esp_elf_free(elf->psegment);
|
||||||
|
#endif
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,8 +441,12 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
|
|||||||
|
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
ESP_LOGE(TAG, "Can't find symbol %s", func_name);
|
ESP_LOGE(TAG, "Can't find symbol %s", func_name);
|
||||||
|
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
|
||||||
esp_elf_free(elf->pdata);
|
esp_elf_free(elf->pdata);
|
||||||
esp_elf_free(elf->ptext);
|
esp_elf_free(elf->ptext);
|
||||||
|
#else
|
||||||
|
esp_elf_free(elf->psegment);
|
||||||
|
#endif
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,10 +473,14 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
|
|||||||
* @param argc - Arguments number
|
* @param argc - Arguments number
|
||||||
* @param argv - Arguments value array
|
* @param argv - Arguments value array
|
||||||
*
|
*
|
||||||
* @return ESP_OK if sucess or other if failed.
|
* @return ESP_OK if success or other if failed.
|
||||||
*/
|
*/
|
||||||
int esp_elf_request(esp_elf_t *elf, int opt, int argc, char *argv[])
|
int esp_elf_request(esp_elf_t *elf, int opt, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
if (!elf || !(elf->entry)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
elf->entry(argc, argv);
|
elf->entry(argc, argv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -338,6 +495,7 @@ int esp_elf_request(esp_elf_t *elf, int opt, int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
void esp_elf_deinit(esp_elf_t *elf)
|
void esp_elf_deinit(esp_elf_t *elf)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
|
||||||
if (elf->pdata) {
|
if (elf->pdata) {
|
||||||
esp_elf_free(elf->pdata);
|
esp_elf_free(elf->pdata);
|
||||||
elf->pdata = NULL;
|
elf->pdata = NULL;
|
||||||
@ -347,6 +505,12 @@ void esp_elf_deinit(esp_elf_t *elf)
|
|||||||
esp_elf_free(elf->ptext);
|
esp_elf_free(elf->ptext);
|
||||||
elf->ptext = NULL;
|
elf->ptext = NULL;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (elf->psegment) {
|
||||||
|
esp_elf_free(elf->ptext);
|
||||||
|
elf->ptext = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ELF_LOADER_SET_MMU
|
#ifdef CONFIG_ELF_LOADER_SET_MMU
|
||||||
esp_elf_arch_deinit_mmu(elf);
|
esp_elf_arch_deinit_mmu(elf);
|
||||||
@ -360,7 +524,7 @@ void esp_elf_deinit(esp_elf_t *elf)
|
|||||||
*
|
*
|
||||||
* @return None
|
* @return None
|
||||||
*/
|
*/
|
||||||
void esp_elf_print_hdr(const uint8_t *pbuf)
|
void esp_elf_print_ehdr(const uint8_t *pbuf)
|
||||||
{
|
{
|
||||||
const char *s_bits, *s_endian;
|
const char *s_bits, *s_endian;
|
||||||
const elf32_hdr_t *hdr = (const elf32_hdr_t *)pbuf;
|
const elf32_hdr_t *hdr = (const elf32_hdr_t *)pbuf;
|
||||||
@ -411,6 +575,32 @@ void esp_elf_print_hdr(const uint8_t *pbuf)
|
|||||||
ESP_LOGI(TAG, "%-40s %d", "Section header string table i:", hdr->shstrndx);
|
ESP_LOGI(TAG, "%-40s %d", "Section header string table i:", hdr->shstrndx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Print program header description information of ELF.
|
||||||
|
*
|
||||||
|
* @param pbuf - ELF data buffer
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void esp_elf_print_phdr(const uint8_t *pbuf)
|
||||||
|
{
|
||||||
|
const elf32_hdr_t *ehdr = (const elf32_hdr_t *)pbuf;
|
||||||
|
const elf32_phdr_t *phdr = (const elf32_phdr_t *)((size_t)pbuf + ehdr->phoff);
|
||||||
|
|
||||||
|
for (int i = 0; i < ehdr->phnum; i++) {
|
||||||
|
ESP_LOGI(TAG, "%-40s %d", "type:", phdr->type);
|
||||||
|
ESP_LOGI(TAG, "%-40s 0x%x", "offset:", phdr->offset);
|
||||||
|
ESP_LOGI(TAG, "%-40s 0x%x", "vaddr", phdr->vaddr);
|
||||||
|
ESP_LOGI(TAG, "%-40s 0x%x", "paddr:", phdr->paddr);
|
||||||
|
ESP_LOGI(TAG, "%-40s %d", "filesz", phdr->filesz);
|
||||||
|
ESP_LOGI(TAG, "%-40s %d", "memsz", phdr->memsz);
|
||||||
|
ESP_LOGI(TAG, "%-40s %d", "flags", phdr->flags);
|
||||||
|
ESP_LOGI(TAG, "%-40s 0x%x", "align", phdr->align);
|
||||||
|
|
||||||
|
phdr = (const elf32_phdr_t *)((size_t)phdr + sizeof(elf32_phdr_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Print section header description information of ELF.
|
* @brief Print section header description information of ELF.
|
||||||
*
|
*
|
||||||
@ -420,21 +610,21 @@ void esp_elf_print_hdr(const uint8_t *pbuf)
|
|||||||
*/
|
*/
|
||||||
void esp_elf_print_shdr(const uint8_t *pbuf)
|
void esp_elf_print_shdr(const uint8_t *pbuf)
|
||||||
{
|
{
|
||||||
const elf32_hdr_t *phdr = (const elf32_hdr_t *)pbuf;
|
const elf32_hdr_t *ehdr = (const elf32_hdr_t *)pbuf;
|
||||||
const elf32_shdr_t *pshdr = (const elf32_shdr_t *)((size_t)pbuf + phdr->shoff);
|
const elf32_shdr_t *shdr = (const elf32_shdr_t *)((size_t)pbuf + ehdr->shoff);
|
||||||
|
|
||||||
for (int i = 0; i < phdr->shnum; i++) {
|
for (int i = 0; i < ehdr->shnum; i++) {
|
||||||
ESP_LOGI(TAG, "%-40s %d", "name:", pshdr->name);
|
ESP_LOGI(TAG, "%-40s %d", "name:", shdr->name);
|
||||||
ESP_LOGI(TAG, "%-40s %d", "type:", pshdr->type);
|
ESP_LOGI(TAG, "%-40s %d", "type:", shdr->type);
|
||||||
ESP_LOGI(TAG, "%-40s 0x%x", "flags:", pshdr->flags);
|
ESP_LOGI(TAG, "%-40s 0x%x", "flags:", shdr->flags);
|
||||||
ESP_LOGI(TAG, "%-40s %x", "addr", pshdr->addr);
|
ESP_LOGI(TAG, "%-40s %x", "addr", shdr->addr);
|
||||||
ESP_LOGI(TAG, "%-40s %x", "offset:", pshdr->offset);
|
ESP_LOGI(TAG, "%-40s %x", "offset:", shdr->offset);
|
||||||
ESP_LOGI(TAG, "%-40s %d", "size", pshdr->size);
|
ESP_LOGI(TAG, "%-40s %d", "size", shdr->size);
|
||||||
ESP_LOGI(TAG, "%-40s 0x%x", "link", pshdr->link);
|
ESP_LOGI(TAG, "%-40s 0x%x", "link", shdr->link);
|
||||||
ESP_LOGI(TAG, "%-40s %d", "addralign", pshdr->addralign);
|
ESP_LOGI(TAG, "%-40s %d", "addralign", shdr->addralign);
|
||||||
ESP_LOGI(TAG, "%-40s %d", "entsize", pshdr->entsize);
|
ESP_LOGI(TAG, "%-40s %d", "entsize", shdr->entsize);
|
||||||
|
|
||||||
pshdr = (const elf32_shdr_t *)((size_t)pshdr + sizeof(elf32_shdr_t));
|
shdr = (const elf32_shdr_t *)((size_t)shdr + sizeof(elf32_shdr_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,10 +28,23 @@
|
|||||||
*/
|
*/
|
||||||
void *esp_elf_malloc(uint32_t n, bool exec)
|
void *esp_elf_malloc(uint32_t n, bool exec)
|
||||||
{
|
{
|
||||||
|
uint32_t caps;
|
||||||
|
|
||||||
|
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
|
||||||
#ifdef CONFIG_ELF_LOADER_LOAD_PSRAM
|
#ifdef CONFIG_ELF_LOADER_LOAD_PSRAM
|
||||||
uint32_t caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT;
|
caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT;
|
||||||
#else
|
#else
|
||||||
uint32_t caps = exec ? MALLOC_CAP_EXEC : MALLOC_CAP_8BIT;
|
caps = exec ? MALLOC_CAP_EXEC : MALLOC_CAP_8BIT;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef CONFIG_ELF_LOADER_LOAD_PSRAM
|
||||||
|
caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT;
|
||||||
|
#else
|
||||||
|
caps = MALLOC_CAP_8BIT;
|
||||||
|
#endif
|
||||||
|
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
|
||||||
|
caps |= MALLOC_CAP_CACHE_ALIGNED;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return heap_caps_malloc(n, caps);
|
return heap_caps_malloc(n, caps);
|
||||||
@ -64,7 +77,7 @@ uintptr_t elf_remap_text(esp_elf_t *elf, uintptr_t sym)
|
|||||||
esp_elf_sec_t *sec = &elf->sec[ELF_SEC_TEXT];
|
esp_elf_sec_t *sec = &elf->sec[ELF_SEC_TEXT];
|
||||||
|
|
||||||
if ((sym >= sec->addr) &&
|
if ((sym >= sec->addr) &&
|
||||||
(sym < (sec->addr + sec->size))) {
|
(sym < (sec->addr + sec->size))) {
|
||||||
#ifdef CONFIG_ELF_LOADER_SET_MMU
|
#ifdef CONFIG_ELF_LOADER_SET_MMU
|
||||||
mapped_sym = sym + elf->text_off;
|
mapped_sym = sym + elf->text_off;
|
||||||
#else
|
#else
|
||||||
@ -105,4 +118,3 @@ void IRAM_ATTR esp_elf_arch_flush(void)
|
|||||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -19,14 +19,20 @@
|
|||||||
|
|
||||||
#include "rom/ets_sys.h"
|
#include "rom/ets_sys.h"
|
||||||
|
|
||||||
#include "elf_symbol.h"
|
#include "private/elf_symbol.h"
|
||||||
|
|
||||||
|
extern int __ltdf2(double a, double b);
|
||||||
|
extern unsigned int __fixunsdfsi(double a);
|
||||||
|
extern int __gtdf2(double a, double b);
|
||||||
|
extern double __floatunsidf(unsigned int i);
|
||||||
|
extern double __divdf3(double a, double b);
|
||||||
|
|
||||||
extern int __ltdf2 (double a, double b);
|
// Tactility custom -->
|
||||||
extern unsigned int __fixunsdfsi (double a);
|
static const struct esp_elfsym* custom_symbols = NULL;
|
||||||
extern int __gtdf2 (double a, double b);
|
void elf_set_custom_symbols(const struct esp_elfsym* symbols) {
|
||||||
extern double __floatunsidf (unsigned int i);
|
custom_symbols = symbols;
|
||||||
extern double __divdf3 (double a, double b);
|
}
|
||||||
|
// <-- Tactility custom
|
||||||
|
|
||||||
/** @brief Libc public functions symbols look-up table */
|
/** @brief Libc public functions symbols look-up table */
|
||||||
|
|
||||||
@ -150,14 +156,6 @@ static const struct esp_elfsym g_esp_espidf_elfsyms[] = {
|
|||||||
ESP_ELFSYM_END
|
ESP_ELFSYM_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS
|
|
||||||
static const struct esp_elfsym* custom_symbols = NULL;
|
|
||||||
void elf_set_custom_symbols(const struct esp_elfsym* symbols) {
|
|
||||||
custom_symbols = symbols;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Find symbol address by name.
|
* @brief Find symbol address by name.
|
||||||
*
|
*
|
||||||
@ -198,19 +196,28 @@ uintptr_t elf_find_sym(const char *sym_name)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS
|
#ifdef CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS
|
||||||
syms = custom_symbols;
|
extern const struct esp_elfsym g_customer_elfsyms[];
|
||||||
if (syms != NULL) {
|
|
||||||
while (syms->name) {
|
|
||||||
if (!strcmp(syms->name, sym_name)) {
|
|
||||||
return (uintptr_t)syms->sym;
|
|
||||||
}
|
|
||||||
|
|
||||||
syms++;
|
syms = g_customer_elfsyms;
|
||||||
|
while (syms->name) {
|
||||||
|
if (!strcmp(syms->name, sym_name)) {
|
||||||
|
return (uintptr_t)syms->sym;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
syms++;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Tactility custom -->
|
||||||
|
syms = custom_symbols;
|
||||||
|
while (syms->name) {
|
||||||
|
if (!strcmp(syms->name, sym_name)) {
|
||||||
|
return (uintptr_t)syms->sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
syms++;
|
||||||
|
}
|
||||||
|
// <-- Tactility custom
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,12 @@
|
|||||||
#define MMU_UNIT_SIZE 0x10000
|
#define MMU_UNIT_SIZE 0x10000
|
||||||
#define MMU_REG ((volatile uint32_t *)DR_REG_MMU_TABLE)
|
#define MMU_REG ((volatile uint32_t *)DR_REG_MMU_TABLE)
|
||||||
|
|
||||||
|
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
|
||||||
|
#define IRAM0_ADDRESS_LOW SOC_IRAM0_ADDRESS_LOW
|
||||||
|
#define IRAM0_ADDRESS_HIGH SOC_IRAM0_ADDRESS_HIGH
|
||||||
|
#define MMU_ACCESS_SPIRAM SOC_MMU_ACCESS_SPIRAM
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ESP_MMU_IBUS_BASE IRAM0_ADDRESS_LOW
|
#define ESP_MMU_IBUS_BASE IRAM0_ADDRESS_LOW
|
||||||
#define ESP_MMU_IBUS_MAX ((IRAM0_ADDRESS_HIGH - IRAM0_ADDRESS_LOW) / \
|
#define ESP_MMU_IBUS_MAX ((IRAM0_ADDRESS_HIGH - IRAM0_ADDRESS_LOW) / \
|
||||||
MMU_UNIT_SIZE)
|
MMU_UNIT_SIZE)
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
|
|
||||||
#include "elf_symbol.h"
|
|
||||||
|
|
||||||
#include "tt_app.h"
|
#include "tt_app.h"
|
||||||
#include "tt_app_alertdialog.h"
|
#include "tt_app_alertdialog.h"
|
||||||
#include "tt_app_manifest.h"
|
#include "tt_app_manifest.h"
|
||||||
@ -16,6 +14,8 @@
|
|||||||
#include "tt_thread.h"
|
#include "tt_thread.h"
|
||||||
#include "tt_timer.h"
|
#include "tt_timer.h"
|
||||||
|
|
||||||
|
#include <private/elf_symbol.h>
|
||||||
|
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@ -24,7 +24,6 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS=y
|
|
||||||
CONFIG_FATFS_LFN_HEAP=y
|
CONFIG_FATFS_LFN_HEAP=y
|
||||||
CONFIG_FATFS_VOLUME_COUNT=3
|
CONFIG_FATFS_VOLUME_COUNT=3
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS=y
|
|
||||||
CONFIG_FATFS_LFN_HEAP=y
|
CONFIG_FATFS_LFN_HEAP=y
|
||||||
CONFIG_FATFS_VOLUME_COUNT=3
|
CONFIG_FATFS_VOLUME_COUNT=3
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS=y
|
|
||||||
CONFIG_FATFS_LFN_HEAP=y
|
CONFIG_FATFS_LFN_HEAP=y
|
||||||
CONFIG_FATFS_VOLUME_COUNT=3
|
CONFIG_FATFS_VOLUME_COUNT=3
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS=y
|
|
||||||
CONFIG_FATFS_LFN_HEAP=y
|
CONFIG_FATFS_LFN_HEAP=y
|
||||||
CONFIG_FATFS_VOLUME_COUNT=3
|
CONFIG_FATFS_VOLUME_COUNT=3
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS=y
|
|
||||||
CONFIG_FATFS_LFN_HEAP=y
|
CONFIG_FATFS_LFN_HEAP=y
|
||||||
CONFIG_FATFS_VOLUME_COUNT=3
|
CONFIG_FATFS_VOLUME_COUNT=3
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS=y
|
|
||||||
CONFIG_FATFS_LFN_HEAP=y
|
CONFIG_FATFS_LFN_HEAP=y
|
||||||
CONFIG_FATFS_VOLUME_COUNT=3
|
CONFIG_FATFS_VOLUME_COUNT=3
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS=y
|
|
||||||
CONFIG_FATFS_LFN_HEAP=y
|
CONFIG_FATFS_LFN_HEAP=y
|
||||||
CONFIG_FATFS_VOLUME_COUNT=3
|
CONFIG_FATFS_VOLUME_COUNT=3
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS=y
|
|
||||||
CONFIG_FATFS_LFN_HEAP=y
|
CONFIG_FATFS_LFN_HEAP=y
|
||||||
CONFIG_FATFS_VOLUME_COUNT=3
|
CONFIG_FATFS_VOLUME_COUNT=3
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS=y
|
|
||||||
CONFIG_FATFS_LFN_HEAP=y
|
CONFIG_FATFS_LFN_HEAP=y
|
||||||
CONFIG_FATFS_VOLUME_COUNT=3
|
CONFIG_FATFS_VOLUME_COUNT=3
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS=y
|
|
||||||
CONFIG_FATFS_LFN_HEAP=y
|
CONFIG_FATFS_LFN_HEAP=y
|
||||||
CONFIG_FATFS_VOLUME_COUNT=3
|
CONFIG_FATFS_VOLUME_COUNT=3
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user