Linux on ESP32
Linux on ESP32: Porting MMU Linux to the S31
This project represents an ambitious effort to bring MMU-capable Linux to the ESP32-S31 architecture. The target ISA is defined as .
🛠️ Hardware Specifications
The development and testing were conducted using the following module:
- Module:
ESP32-S31-WROOM-3 E1H16R16V - Board: ESP32-S31 Core Board
📊 Porting Progress & Feature Matrix
The current state of the port is a mix of functional, experimental, and unimplemented features.
System & Connectivity Status
| Feature Category | Component | Status | Notes |
|---|---|---|---|
| General | Buildroot rootfs | 🟡 | Untested |
| Wireless (ESP-Hosted) | 🟡 | Untested | |
| Poweroff/Reboot | 🟡 | Untested | |
| Dual hart SMP | Not Planned (Reserved for FreeRTOS) | ||
| Peripherals | AXI/AHB GDMA | 🟡 | Untested |
| Cache/TRNG/eFuse | 🟡 | Untested | |
| Watchdog/PWM/Analog | 🟡 | Untested | |
| CLIC/CLINT Interrupts | 🟡 | Untested | |
| Flash MTD | 🟡 | Untested | |
| Timers / Clock Tree | 🟠 | Work in Progress | |
| Security Accelerators | 🟠 | Work in Progress | |
| IPC / PMP / APM | 🔴 | Not Implemented | |
| Connectivity | UART0 Console | 🟡 | Untested |
| UART1/2 / Ethernet | 🟡 | Untested | |
| SDMMC / GPIO / Pinctrl | 🟡 | Untested | |
| USB | 🟠 | Work in Progress | |
| I2C / I2S / SPI / RMT | 🔴 | Not Implemented | |
| USB Serial/JTAG | Not Planned (Reserved for FreeRTOS) |
Legend:
- 🟢 Stable: Fully verified.
- 🟡 Untested: Appears functional but lacks rigorous testing.
- 🟠 WIP: Partially implemented.
- 🔴 Not Implemented: No current code.
📝 Pending Verification Task List
- Validate Buildroot rootfs stability.
- Test wireless connectivity via ESP-Hosted.
- Verify system power-down and reboot cycles.
- Complete USB driver implementation.
🧠 Technical Nuances & "S31 Quirks"
Because a formal Technical Reference Manual (TRM) for the S31 was unavailable during development, several implementation details were derived through guesswork and probing.
Interrupt Handling (CLIC)
To achieve a working CLIC, a patch from disdi was utilized. It was discovered that:
- Standard RISC-V interrupt CSRs are non-functional.
- Based on the P4 TRM, CLINT interrupts are routed through the CLIC.
- The
mtvec.MODEregister is hardwired to0x3(forcing CLIC mode).
Supervisor Mode (S-mode)
The S31's implementation of supervisor mode deviates from the standard. Since ESP-IDF does not utilize this mode, the following was discovered via CSR probing:
The S31 utilizes a "Supervisor CLIC" (SCLIC). While
mcliccfg.NMBITSis typically read-only in ESP-IDF, setting it to0b01unlocks theclicintattr[i].MODEfield, thereby enabling S-mode interrupts.
Boot Sequence & Memory Optimization
To conserve the limited of PSRAM, the boot flow was optimized:
- OpenSBI: Modified to use XIP (Execute In Place) within the flash and internal SRAM. This explains the unusual firmware size reported in the banner.
- Kernel: Linux version
6.12was selected specifically because mainline RISC-V XIP support had been removed in newer versions.
📈 Performance & System Logs
CoreMark Benchmark
The following results were obtained using GCC 15.2.0 with -O2 optimization:
CoreMark 1.0 Score:
1058.929422
- Total Ticks:
- Total Time:
- Iterations:
System Information
CPU Details:
# cat /proc/cpuinfo
processor : 0
hart : 0
isa : rv32imafc_zicntr_zicsr_zifencei_zca_zcf_zbb
mmu : sv32
uarch : espressif,esp32s31
Kernel Version:
# uname -a
Linux (none) 6.12.0-00036-gdccf9c1b2c4f-dirty #30 Thu Jul 2 23:48:23 CST 2026 riscv32
Memory Usage:
# free -h
total used free shared buff/cache available
Mem: 15004 1892 12784 0 328 12108
Swap: 0 0 0
Process List:
# ps -aux
PID USER PR NI V SIZE RSW VSZ PSTIME TTY TIME CMD
1 0 0 380 S 0 0 0 00:00 ? 00:00 /bin/sh -i
2 0 0 0 SW 0 0 0 00:00 ? 00:00 [kthreadd]
34 0 0 380 R 0 0 0 00:00 ? 00:00 ps -aux