rockbox/tools/echoplayer/openocd.make
Aidan MacDonald d5506dfa22 echoplayer: implement boot from debugger
Add a 'make start' target which starts Rockbox using a
debugger. This only works to load the main binary, but
makes it much faster to test changes that don't affect
plugins/codecs.

Because SDRAM isn't accessible at reset and the main
binary is usually too big to fit in SRAM, the bootloader
must be flashed first before Rockbox can be loaded in
this way.

The boot protocol involves GDB writing a check pattern
to SRAM while the CPU is held in reset. The bootloader
detects the pattern and takes a breakpoint, by which
time SDRAM is accessible; GDB can then upload a binary
ELF image (copied as a raw file, since the ELF will be
loaded using RB's ELF loader) and leave the breakpoint
to continue booting.

From there the bootloader can load the ELF binary from
memory, exactly like a normal SD card boot.

Change-Id: I4eb971b4162ea422e38660455cfa0958cefaa18d
2026-01-26 08:55:01 -05:00

57 lines
1.7 KiB
Makefile

GDB := gdb
OPENOCD := openocd
OPENOCD_CFG := $(ROOTDIR)/tools/echoplayer/openocd.cfg
# GDB boot protocol 'registers' used for communicating with the bootloader
GDBBOOT_REG_BASE := 0x38000000
GDBBOOT_REG_MAGIC1 := ($(GDBBOOT_REG_BASE) + 0x00)
GDBBOOT_REG_MAGIC2 := ($(GDBBOOT_REG_BASE) + 0x04)
GDBBOOT_REG_MAGIC3 := ($(GDBBOOT_REG_BASE) + 0x08)
GDBBOOT_REG_MAGIC4 := ($(GDBBOOT_REG_BASE) + 0x0c)
GDBBOOT_REG_ELFADDR := ($(GDBBOOT_REG_BASE) + 0x10)
GDBBOOT_REG_ELFSIZE := ($(GDBBOOT_REG_BASE) + 0x14)
# Address where the RB binary will be loaded
GDBBOOT_LOAD_ADDR := 0x71e00000
GDBBOOT_LOAD_SIZE := 0x200000
ifneq (,$(findstring bootloader,$(APPSDIR)))
TARGET_ELF := $(BUILDDIR)/bootloader.elf
else
TARGET_ELF := $(BUILDDIR)/rockbox.elf
TARGET_BIN := $(BUILDDIR)/rockbox.echo
endif
# Attach to running process
debug:
$(GDB) $(TARGET_ELF) \
-ex "target extended-remote | openocd -c \"gdb_port pipe\" -f $(OPENOCD_CFG)"
.PHONY: debug
ifneq (,$(findstring bootloader,$(APPSDIR)))
# Flash bootloader
flash: $(TARGET_ELF)
$(OPENOCD) -f $(OPENOCD_CFG) -c "program $< verify reset exit"
.PHONY: flash
else
# Start Rockbox via debugger
start: $(TARGET_BIN)
$(GDB) $(TARGET_ELF) \
-ex "target extended-remote | openocd -c \"gdb_port pipe\" -f $(OPENOCD_CFG)" \
-ex "monitor reset halt" \
-ex "set *$(GDBBOOT_REG_MAGIC1) = 0x726f636b" \
-ex "set *$(GDBBOOT_REG_MAGIC2) = 0x424f4f54" \
-ex "set *$(GDBBOOT_REG_MAGIC3) = 0x6764626c" \
-ex "set *$(GDBBOOT_REG_MAGIC4) = 0x6f616455" \
-ex "continue" \
-ex "restore $(TARGET_BIN) binary $(GDBBOOT_LOAD_ADDR)" \
-ex "set *$(GDBBOOT_REG_ELFADDR) = $(GDBBOOT_LOAD_ADDR)" \
-ex "set *$(GDBBOOT_REG_ELFSIZE) = $(GDBBOOT_LOAD_SIZE)" \
-ex "continue"
.PHONY: start
endif