Skip to content

Commit 4638426

Browse files
committed
Merge branch 'feature/add_esp32p4_support' into 'master'
feat(elf_loader): Add ESP32-P4 and ESP32-C6 support Closes AEG-1929 See merge request ae_group/esp-iot-solution!1118
2 parents f5ca5b5 + 424ece8 commit 4638426

26 files changed

+584
-135
lines changed

.gitlab/ci/build.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,10 @@ build_example_elf_loader_elf_loader_example:
14231423
matrix:
14241424
- IMAGE: espressif/idf:release-v4.4
14251425
- IMAGE: espressif/idf:release-v5.0
1426+
- IMAGE: espressif/idf:release-v5.1
1427+
- IMAGE: espressif/idf:release-v5.2
1428+
- IMAGE: espressif/idf:release-v5.3
1429+
- IMAGE: espressif/idf:release-v5.4
14261430
EXAMPLE_CONFIG: "sdkconfig.ci=default"
14271431
variables:
14281432
EXAMPLE_DIR: examples/elf_loader/elf_loader_example
@@ -1435,6 +1439,10 @@ build_example_elf_loader_build_elf_file_example:
14351439
matrix:
14361440
- IMAGE: espressif/idf:release-v4.4
14371441
- IMAGE: espressif/idf:release-v5.0
1442+
- IMAGE: espressif/idf:release-v5.1
1443+
- IMAGE: espressif/idf:release-v5.2
1444+
- IMAGE: espressif/idf:release-v5.3
1445+
- IMAGE: espressif/idf:release-v5.4
14381446
variables:
14391447
EXAMPLE_DIR: examples/elf_loader/build_elf_file_example
14401448

components/elf_loader/CMakeLists.txt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

22
if(CONFIG_ELF_LOADER)
33
set(srcs "src/esp_elf_symbol.c"
4-
"src/esp_elf.c"
5-
"src/esp_elf_adapter.c")
4+
"src/esp_elf.c"
5+
"src/esp_elf_adapter.c")
66

77
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
88
list(APPEND srcs "src/arch/esp_elf_xtensa.c")
@@ -11,14 +11,24 @@ if(CONFIG_ELF_LOADER)
1111
if(CONFIG_IDF_TARGET_ESP32S2 AND (CONFIG_ELF_LOADER_LOAD_PSRAM))
1212
list(APPEND srcs "src/soc/esp_elf_esp32s2.c")
1313
endif()
14+
elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
15+
list(APPEND srcs "src/arch/esp_elf_riscv.c")
1416
endif()
1517

1618
set(include_dirs "include")
19+
set(ldfragments "linker.lf")
20+
endif()
21+
22+
if(CONFIG_IDF_TARGET_ESP32P4)
23+
set(priv_req spi_flash esp_mm)
24+
else()
25+
set(priv_req spi_flash)
1726
endif()
1827

1928
idf_component_register(SRCS ${srcs}
2029
INCLUDE_DIRS ${include_dirs}
21-
PRIV_REQUIRES spi_flash)
30+
PRIV_REQUIRES spi_flash ${priv_req}
31+
LDFRAGMENTS ${ldfragments})
2232

2333
include(package_manager)
2434
if(CONFIG_ELF_LOADER)

components/elf_loader/Kconfig

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
menu "Espressif ELF Loader Configuration"
2-
visible if (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
2+
visible if (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32P4)
3+
4+
config ELF_LOADER_BUS_ADDRESS_MIRROR
5+
bool
6+
default y if (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
7+
default n if (IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32P4)
38

49
config ELF_LOADER
510
bool "Enable Espressif ELF Loader"
611
default y
7-
depends on (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
12+
depends on (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32P4)
813
help
914
Select this option to enable ELF Loader and show the submenu with ELF Loader configuration choices.
1015

@@ -24,7 +29,7 @@ menu "Espressif ELF Loader Configuration"
2429
config ELF_LOADER_LOAD_PSRAM
2530
bool "Load ELF to PSRAM"
2631
default y
27-
depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3) && SPIRAM
32+
depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4) && SPIRAM
2833
select ELF_LOADER_CACHE_OFFSET if (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
2934
select ELF_LOADER_SET_MMU if IDF_TARGET_ESP32S2
3035
help

components/elf_loader/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ This ELF loader supports following SoCs:
1111
- ESP32
1212
- ESP32-S2, support running ELF in PSRAM
1313
- ESP32-S3, support running ELF in PSRAM
14+
- ESP32-P4, support running ELF in PSRAM
15+
- ESP32-C6
1416

1517
### Usage
1618

components/elf_loader/elf_loader.cmake

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,35 @@ macro(project_elf project_name)
3535
# Remove more unused sections
3636
string(REPLACE "-elf-gcc" "-elf-strip" ${CMAKE_STRIP} ${CMAKE_C_COMPILER})
3737
set(strip_flags --strip-unneeded
38-
--remove-section=.xt.lit
39-
--remove-section=.xt.prop
4038
--remove-section=.comment
41-
--remove-section=.xtensa.info
4239
--remove-section=.got.loc
43-
--remove-section=.got)
40+
--remove-section=.dynamic)
41+
42+
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
43+
list(APPEND strip_flags --remove-section=.xt.lit
44+
--remove-section=.xt.prop
45+
--remove-section=.xtensa.info)
46+
elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
47+
list(APPEND strip_flags --remove-section=.riscv.attributes)
48+
endif()
4449

4550
# Link input list of libraries to ELF
51+
list(APPEND ELF_COMPONENTS "main")
4652
if(ELF_COMPONENTS)
4753
foreach(c "${ELF_COMPONENTS}")
48-
set(elf_libs "${elf_libs}" "esp-idf/${c}/lib${c}.a")
54+
list(APPEND elf_libs "esp-idf/${c}/lib${c}.a")
55+
list(APPEND elf_dependeces "idf::${c}")
4956
endforeach()
5057
endif()
51-
52-
set(elf_libs ${elf_libs} "${ELF_LIBS}" "esp-idf/main/libmain.a")
58+
if (ELF_LIBS)
59+
list(APPEND elf_libs "${ELF_LIBS}")
60+
endif()
5361
spaces2list(elf_libs)
5462

5563
add_custom_command(OUTPUT elf_app
5664
COMMAND ${CMAKE_C_COMPILER} ${cflags} ${elf_libs} -o ${elf_app}
5765
COMMAND ${CMAKE_STRIP} ${strip_flags} ${elf_app}
58-
DEPENDS idf::main
66+
DEPENDS ${elf_dependeces}
5967
COMMENT "Build ELF: ${elf_app}"
6068
)
6169
add_custom_target(elf ALL DEPENDS elf_app)

components/elf_loader/include/esp_elf.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,16 @@ void esp_elf_deinit(esp_elf_t *elf);
6969
*
7070
* @return None
7171
*/
72-
void esp_elf_print_hdr(const uint8_t *pbuf);
72+
void esp_elf_print_ehdr(const uint8_t *pbuf);
73+
74+
/**
75+
* @brief Print program header description information of ELF.
76+
*
77+
* @param pbuf - ELF data buffer
78+
*
79+
* @return None
80+
*/
81+
void esp_elf_print_phdr(const uint8_t *pbuf);
7382

7483
/**
7584
* @brief Print section header description information of ELF.

components/elf_loader/include/private/elf_platform.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,10 @@
1212
extern "C" {
1313
#endif
1414

15-
#ifndef ELF_ALIGN_SIZE
16-
#define ELF_ALIGN_SIZE 4
17-
#endif
15+
/* Notes: align_size needs to be a power of 2 */
1816

19-
#define ELF_ALIGN(_a) (((_a) + (ELF_ALIGN_SIZE - 1)) & \
20-
(~(ELF_ALIGN_SIZE - 1)))
17+
#define ELF_ALIGN(_a, align_size) (((_a) + (align_size - 1)) & \
18+
~(align_size - 1))
2119

2220
/**
2321
* @brief Allocate block of memory.

components/elf_loader/include/private/elf_types.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,29 @@ extern "C" {
1818

1919
#define EI_NIDENT 16 /*!< Magic number and other information length */
2020

21+
/** @brief Type of segment */
22+
23+
#define PT_NULL 0 /*!< Program header table entry unused */
24+
#define PT_LOAD 1 /*!< Loadable program segment */
25+
#define PT_DYNAMIC 2 /*!< Dynamic linking information */
26+
#define PT_INTERP 3 /*!< Program interpreter */
27+
#define PT_NOTE 4 /*!< Auxiliary information */
28+
#define PT_SHLIB 5 /*!< Reserved */
29+
#define PT_PHDR 6 /*!< Entry for header table itself */
30+
#define PT_TLS 7 /*!< Thread-local storage segment */
31+
#define PT_NUM 8 /*!< Number of defined types */
32+
#define PT_LOOS 0x60000000 /*!< Start of OS-specific */
33+
#define PT_GNU_EH_FRAME 0x6474e550 /*!< GCC .eh_frame_hdr segment */
34+
#define PT_GNU_STACK 0x6474e551 /*!< Indicates stack executability */
35+
#define PT_GNU_RELRO 0x6474e552 /*!< Read-only after relocation */
36+
#define PT_LOSUNW 0x6ffffffa
37+
#define PT_SUNWBSS 0x6ffffffa /*!< Sun Specific segment */
38+
#define PT_SUNWSTACK 0x6ffffffb /*!< Stack segment */
39+
#define PT_HISUNW 0x6fffffff
40+
#define PT_HIOS 0x6fffffff /*!< End of OS-specific */
41+
#define PT_LOPROC 0x70000000 /*!< Start of processor-specific */
42+
#define PT_HIPROC 0x7fffffff /*!< End of processor-specific */
43+
2144
/** @brief Section Type */
2245

2346
#define SHT_NULL 0 /*!< invalid section header */
@@ -82,6 +105,8 @@ extern "C" {
82105
#define ELF_SYMTAB ".symtab" /*!< symbol table */
83106
#define ELF_TEXT ".text" /*!< code */
84107
#define ELF_DATA_REL_RO ".data.rel.ro" /*!< dynamic read-only data */
108+
#define ELF_PLT ".plt" /*!< procedure linkage table. */
109+
#define ELF_GOT_PLT ".got.plt" /*!< a table where resolved addresses from external functions are stored */
85110

86111
/** @brief ELF section and symbol operation */
87112

@@ -130,6 +155,19 @@ typedef struct elf32_hdr {
130155
Elf32_Half shstrndx; /*!< section header table's "section header string table" entry offset */
131156
} elf32_hdr_t;
132157

158+
/** @brief Program Header */
159+
160+
typedef struct elf32_phdr {
161+
Elf32_Word type; /* segment type */
162+
Elf32_Off offset; /* segment offset */
163+
Elf32_Addr vaddr; /* virtual address of segment */
164+
Elf32_Addr paddr; /* physical address - ignored? */
165+
Elf32_Word filesz; /* number of bytes in file for seg. */
166+
Elf32_Word memsz; /* number of bytes in mem. for seg. */
167+
Elf32_Word flags; /* flags */
168+
Elf32_Word align; /* memory alignment */
169+
} elf32_phdr_t;
170+
133171
/** @brief Section Header */
134172

135173
typedef struct elf32_shdr {
@@ -184,6 +222,10 @@ typedef struct esp_elf_sec {
184222
/** @brief ELF object */
185223

186224
typedef struct esp_elf {
225+
unsigned char *psegment; /*!< segment buffer pointer */
226+
227+
uint32_t svaddr; /*!< start virtual address of segment */
228+
187229
unsigned char *ptext; /*!< instruction buffer pointer */
188230

189231
unsigned char *pdata; /*!< data buffer pointer */

components/elf_loader/linker.lf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[sections:elf_loader_got_plt]
2+
entries:
3+
.got.plt
4+
.got
5+
6+
[scheme:elf_loader_default]
7+
entries:
8+
elf_loader_got_plt -> flash_rodata
9+
10+
[mapping:elf_loader]
11+
archive: *
12+
entries:
13+
* (elf_loader_default);
14+
elf_loader_got_plt -> flash_rodata KEEP() SURROUND(_esp_elf_loader_got_plt)
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <assert.h>
8+
#include <sys/errno.h>
9+
#include "esp_elf.h"
10+
#include "esp_log.h"
11+
#include "private/elf_platform.h"
12+
13+
/** @brief RISC-V relocations defined by the ABIs */
14+
15+
#define R_RISCV_NONE 0
16+
#define R_RISCV_32 1
17+
#define R_RISCV_64 2
18+
#define R_RISCV_RELATIVE 3
19+
#define R_RISCV_COPY 4
20+
#define R_RISCV_JUMP_SLOT 5
21+
#define R_RISCV_TLS_DTPMOD32 6
22+
#define R_RISCV_TLS_DTPMOD64 7
23+
#define R_RISCV_TLS_DTPREL32 8
24+
#define R_RISCV_TLS_DTPREL64 9
25+
#define R_RISCV_TLS_TPREL32 10
26+
#define R_RISCV_TLS_TPREL64 11
27+
#define R_RISCV_TLS_DESC 12
28+
#define R_RISCV_BRANCH 16
29+
#define R_RISCV_JAL 17
30+
#define R_RISCV_CALL 18
31+
#define R_RISCV_CALL_PLT 19
32+
#define R_RISCV_GOT_HI20 20
33+
#define R_RISCV_TLS_GOT_HI20 21
34+
#define R_RISCV_TLS_GD_HI20 22
35+
#define R_RISCV_PCREL_HI20 23
36+
#define R_RISCV_PCREL_LO12_I 24
37+
#define R_RISCV_PCREL_LO12_S 25
38+
#define R_RISCV_HI20 26
39+
#define R_RISCV_LO12_I 27
40+
#define R_RISCV_LO12_S 28
41+
#define R_RISCV_TPREL_HI20 29
42+
#define R_RISCV_TPREL_LO12_I 30
43+
#define R_RISCV_TPREL_LO12_S 31
44+
#define R_RISCV_TPREL_ADD 32
45+
#define R_RISCV_ADD8 33
46+
#define R_RISCV_ADD16 34
47+
#define R_RISCV_ADD32 35
48+
#define R_RISCV_ADD64 36
49+
#define R_RISCV_SUB8 37
50+
#define R_RISCV_SUB16 38
51+
#define R_RISCV_SUB32 39
52+
#define R_RISCV_SUB64 40
53+
#define R_RISCV_GNU_VTINHERIT 41
54+
#define R_RISCV_GNU_VTENTRY 42
55+
#define R_RISCV_ALIGN 43
56+
#define R_RISCV_RVC_BRANCH 44
57+
#define R_RISCV_RVC_JUMP 45
58+
#define R_RISCV_RVC_LUI 46
59+
#define R_RISCV_RELAX 51
60+
#define R_RISCV_SUB6 52
61+
#define R_RISCV_SET6 53
62+
#define R_RISCV_SET8 54
63+
#define R_RISCV_SET16 55
64+
#define R_RISCV_SET32 56
65+
#define R_RISCV_32_PCREL 57
66+
#define R_RISCV_IRELATIVE 58
67+
#define R_RISCV_PLT32 59
68+
69+
static const char *TAG = "elf_arch";
70+
71+
/**
72+
* @brief Relocates target architecture symbol of ELF
73+
*
74+
* @param elf - ELF object pointer
75+
* @param rela - Relocated symbol data
76+
* @param sym - ELF symbol table
77+
* @param addr - Jumping target address
78+
*
79+
* @return ESP_OK if success or other if failed.
80+
*/
81+
int esp_elf_arch_relocate(esp_elf_t *elf, const elf32_rela_t *rela,
82+
const elf32_sym_t *sym, uint32_t addr)
83+
{
84+
uint32_t *where;
85+
86+
assert(elf && rela);
87+
88+
where = (uint32_t *)((uint8_t *)elf->psegment + rela->offset + elf->svaddr);
89+
ESP_LOGD(TAG, "where=%p addr=0x%x offset=0x%x",
90+
where, (int)elf->psegment, (int)rela->offset);
91+
92+
/* Do relocation based on relocation type */
93+
94+
switch (ELF_R_TYPE(rela->info)) {
95+
case R_RISCV_NONE:
96+
break;
97+
case R_RISCV_32:
98+
*where = addr + rela->addend;
99+
break;
100+
case R_RISCV_RELATIVE:
101+
*where = (Elf32_Addr)((uint8_t *)elf->psegment - elf->svaddr + rela->addend);
102+
break;
103+
case R_RISCV_JUMP_SLOT:
104+
*where = addr;
105+
break;
106+
default:
107+
ESP_LOGE(TAG, "info=%d is not supported\n", ELF_R_TYPE(rela->info));
108+
return -EINVAL;
109+
}
110+
111+
return 0;
112+
}

0 commit comments

Comments
 (0)