-
Notifications
You must be signed in to change notification settings - Fork 47
fix(esp32c3): use newlib startup and merge init_array to rodata for println support #1435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
765ab4b
e6e40e5
10ce1ea
32f0f9f
878cab7
021a390
0f559dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| #!/bin/bash | ||
|
|
||
| # ESP32-C3 Startup Regression Test | ||
| # Verify that _start uses newlib's __libc_init_array (not TinyGo's start.S) | ||
|
|
||
| set -e | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| TEMP_DIR=$(mktemp -d) | ||
| TEST_GO="$TEMP_DIR/main.go" | ||
| TEST_ELF="$TEMP_DIR/test.elf" | ||
|
|
||
| cleanup() { | ||
| rm -rf "$TEMP_DIR" | ||
| } | ||
| trap cleanup EXIT | ||
|
|
||
| echo "==> Creating minimal test program..." | ||
| cat > "$TEST_GO" << 'EOF' | ||
| package main | ||
|
|
||
| func main() {} | ||
| EOF | ||
|
|
||
| echo "==> Building for ESP32-C3 target..." | ||
| cd "$TEMP_DIR" | ||
| llgo build -target=esp32c3 -o "$TEST_ELF" "$TEST_GO" | ||
|
|
||
| if [ ! -f "$TEST_ELF" ]; then | ||
| echo "✗ FAIL: Build failed, $TEST_ELF not found" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "==> Checking for __libc_init_array call in _start..." | ||
|
|
||
| # Disassemble _start and check for __libc_init_array call | ||
| if llvm-objdump -d "$TEST_ELF" | grep -A30 "<_start>:" | grep "__libc_init_array" > /dev/null; then | ||
| echo "✓ PASS: _start calls __libc_init_array" | ||
| echo " This confirms ESP32-C3 uses newlib's standard startup" | ||
| echo " (crt0-riscv32-unknown-none, not TinyGo's start.S)" | ||
| exit 0 | ||
| else | ||
| echo "✗ FAIL: _start does NOT call __libc_init_array" | ||
| echo " ESP32-C3 should use newlib's startup flow" | ||
| echo " Check targets/esp32c3.json inheritance chain" | ||
| echo "" | ||
| echo "Expected: esp32c3 → riscv32-llgo → riscv-llgo → riscv-basic" | ||
| echo "Current _start disassembly:" | ||
| llvm-objdump -d "$TEST_ELF" | grep -A30 "<_start>:" || true | ||
| exit 1 | ||
| fi | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,39 +28,37 @@ SECTIONS | |
| *(.rodata1) | ||
| *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) | ||
| *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) | ||
| . = ALIGN(4); | ||
| __cpu_frequency = .; | ||
| LONG(CPU_FREQUENCY); | ||
| __uart0_clkdiv_reg = .; | ||
| LONG(UART0_CLKDIV_REG); | ||
| __uart0_clkdiv_val = .; | ||
| LONG(UART0_CLKDIV_VAL); | ||
| __uart0_tx_addr = .; | ||
| LONG(UART0_TX_ADDR); | ||
| __uart0_status = .; | ||
| LONG(UART0_STATUS); | ||
| } > iram_seg | ||
|
|
||
| .preinit_array : | ||
| { | ||
| . = ALIGN(4); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documentation note: These sections now reside within |
||
| PROVIDE_HIDDEN (__preinit_array_start = .); | ||
| KEEP (*(.preinit_array)) | ||
| PROVIDE_HIDDEN (__preinit_array_end = .); | ||
| } > iram_seg | ||
| .init_array : | ||
| { | ||
|
|
||
| . = ALIGN(4); | ||
| PROVIDE_HIDDEN (__init_array_start = .); | ||
| KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) | ||
| KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) | ||
| PROVIDE_HIDDEN (__init_array_end = .); | ||
| } > iram_seg | ||
| .fini_array : | ||
| { | ||
|
|
||
| . = ALIGN(4); | ||
| PROVIDE_HIDDEN (__fini_array_start = .); | ||
| KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) | ||
| KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) | ||
| PROVIDE_HIDDEN (__fini_array_end = .); | ||
|
|
||
| . = ALIGN(4); | ||
| __cpu_frequency = .; | ||
| LONG(CPU_FREQUENCY); | ||
| __uart0_clkdiv_reg = .; | ||
| LONG(UART0_CLKDIV_REG); | ||
| __uart0_clkdiv_val = .; | ||
| LONG(UART0_CLKDIV_VAL); | ||
| __uart0_tx_addr = .; | ||
| LONG(UART0_TX_ADDR); | ||
| __uart0_status = .; | ||
| LONG(UART0_STATUS); | ||
| } > iram_seg | ||
|
|
||
| .ctors : | ||
| { | ||
| /* gcc uses crtbegin.o to find the start of | ||
|
|
@@ -94,6 +92,7 @@ SECTIONS | |
|
|
||
| .stack (NOLOAD) : | ||
| { | ||
| . = ALIGN(16); | ||
| . += 16K; | ||
| __stack = .; | ||
| } > dram_seg | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "goos": "linux", | ||
| "goarch": "arm", | ||
| "build-tags": ["tinygo.riscv", "baremetal", "linux", "arm"], | ||
luoliwoshang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "gc": "conservative", | ||
| "linker": "ld.lld", | ||
| "rtlib": "compiler-rt", | ||
| "libc": "picolibc", | ||
| "cflags": [ | ||
| "-Werror", | ||
| "-mno-relax", | ||
| "-fno-exceptions", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables", | ||
| "-ffunction-sections", "-fdata-sections" | ||
| ], | ||
| "ldflags": [ | ||
| "--gc-sections" | ||
| ], | ||
| "gdb": ["riscv64-unknown-elf-gdb"] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "inherits": ["riscv-basic"], | ||
| "build-tags": ["target_llgo"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "inherits": ["riscv-llgo"], | ||
| "llvm-target": "riscv32-unknown-none", | ||
| "cpu": "generic-rv32", | ||
| "target-abi": "ilp32", | ||
| "build-tags": ["tinygo.riscv32"], | ||
| "scheduler": "tasks", | ||
| "default-stack-size": 2048, | ||
| "cflags": [ | ||
| "-march=rv32imac" | ||
| ], | ||
| "ldflags": [ | ||
| "-melf32lriscv" | ||
| ], | ||
| "gdb": [ | ||
| "gdb-multiarch", | ||
| "gdb" | ||
| ] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider increasing
-A30to-A50for additional safety margin. While 30 lines is reasonable for most_startimplementations, using a larger value provides extra headroom if the function grows in the future.