Programming the esp32s2 RiscV coprocessor.
On the espressif esp32s2 they have two coprocessors. One of them is a RV32IMC RiscV core. Here I will look at how to program it and what is added by the esp-idf
You need to install esp-idf and the risc-v toolchain.
$ idf_tools.py install riscv-none-embed-gcc
What does the name RV32IMC reveal
RISCV Is a opensource Instruction Set Architecture (ISA) spec
It includes base and extensions specifications. In this case,
RV32I is Base Integer Instruction Set, 32-bit
- M-Multiply and divide
- C-Compressed instructions
Building the app
First I forgot to set target as s2. The esp32 does not have a riscV coprocessor so first do
idf.py set-target esp32s2
error: ulp_riscv/ulp_riscv.h: No such file or directory
#include “ulp_riscv/ulp_riscv.h”
idf.py build
The CMAKE_ASM_COMPILER:
riscv-none-embed-gcc
is not a full path and was not found in the PATH.
Path had to be added manually
export PATH=$PATH:~/.espressif/tools/riscv-none-embed-gcc/riscv-none-embed-gcc-8.2.0/xPacks/riscv-none-embed-gcc/8.2.0-3.1/bin
Then finally we ended up with a binary in build/esp-idf/main/ulp_main/ulp_main
This is a an elf file and can be loaded whith ghidra.
Reset vector
//
// .text
00000000 09 a8 c.j __start undefined __start(void)
irq_vector and __start
undefined __stdcall irq_vector(void)
undefined a0:1 <RETURN>
irq_vector XREF[1]: Entry Point(*)
00000010 82 80 ret
The _start function is added by the esp-idf
void __start(void){
ulp_riscv_rescue_from_monitor();
main();
ulp_riscv_shutdown();
do {
/* WARNING: Do nothing block loop */
} while( true );
}
Assembly listing
**************************************************************
* FUNCTION *
**************************************************************
undefined __stdcall __start(void)
undefined a0:1 <RETURN>
__start XREF[1]: 00000000(c)
00000012 17 11 00 00 auipc sp,0x1
00000016 13 01 e1 fe addi sp,sp,-0x12
0000001a 3d 28 c.jal ulp_riscv_rescue_from_monitor
0000001c 09 28 c.jal main
0000001e a9 28 c.jal ulp_riscv_shutdown
loop XREF[1]: 00000020(j)
00000020 01 a0 c.j loop
You can read more about the riscV ISA here.
The complete source code for this example is available in, https://github.com/Ebiroll/esp32s2_kaluga/tree/master/examples/ulp_riscv