diff --git a/esp32c3/build.mk b/esp32c3/build.mk
index cef040962cc67ee70b13baff87c4c6a83c215929..35da63d97d94e6db26f3c2fd79078de59dd83c55 100644
--- a/esp32c3/build.mk
+++ b/esp32c3/build.mk
@@ -12,7 +12,7 @@ CWD         ?= $(realpath $(CURDIR))
 FLASH_ADDR  ?= 0  # 2nd stage bootloader flash offset
 DOCKER      ?= docker run -it --rm -v $(CWD):$(CWD) -v $(MDK):$(MDK) -w $(CWD) mdashnet/riscv
 TOOLCHAIN   ?= $(DOCKER) riscv-none-elf
-SRCS        ?= $(MDK)/$(ARCH)/boot.c $(SOURCES)
+SRCS        ?= $(MDK)/$(ARCH)/boot.c $(MDK)/$(ARCH)/emulator_workarounds.S $(SOURCES)
 
 build: $(PROG).bin
 
diff --git a/esp32c3/emulator_workarounds.S b/esp32c3/emulator_workarounds.S
new file mode 100644
index 0000000000000000000000000000000000000000..044a84a8e8a6c2d7b1658a1a4d7d5895c9c08125
--- /dev/null
+++ b/esp32c3/emulator_workarounds.S
@@ -0,0 +1,12 @@
+//; In the current state of our emulator, it doesn't run a proper boot ROM.
+//; This function does some minor fixups (setting stack pointer etc.)
+//; and runs the MDK init function.
+.section .text
+.align 2
+.global emulator_workarounds
+emulator_workarounds:
+//; Not sure if this is the best address for the stack
+//; FIXME: This should be set to a range specified in the linker script
+li sp, 0x40384400
+//; Jump to MDK's real setup function
+j _reset
diff --git a/esp32c3/link.ld b/esp32c3/link.ld
index b086c87058e59dead432445a217ffb326b9ba894..9abbd07f5346bc5d9e94f3653aecfae327785188 100644
--- a/esp32c3/link.ld
+++ b/esp32c3/link.ld
@@ -5,7 +5,7 @@ MEMORY {
 }
 
 _eram = ORIGIN(dram) + LENGTH(dram);
-ENTRY(_reset)
+ENTRY(emulator_workarounds)
 
 SECTIONS {
   .text     : { *(.text) *(.text*) } > iram