All uncommitted work from ESP32 GDB stub development session. Includes: - GDB stub (uos_gdbstub.c/.h/_entry.S) - Startup vector table rewrite - ESP32 HAL integration files - Boot chain design docs - AGENTS.md absolute rules (commit before refactor, no unauthorized changes) - All prior deepseek session work This commit prevents further data loss. No claims of correctness.
310 lines
11 KiB
Makefile
310 lines
11 KiB
Makefile
# UniversalisOS Microkernel — Multi-target Makefile
|
|
#
|
|
# Usage:
|
|
# make (default: QEMU lm3s6965evb)
|
|
# make TARGET=stm32f0 (STM32F0 Nucleo boards)
|
|
# make TARGET=stm32g0 (STM32G0 Nucleo boards)
|
|
# make TARGET=stm32l0 (STM32L0 Nucleo/Discovery)
|
|
# make TARGET=nxp_kl (NXP Kinetis KL25Z/KL43Z/KL46Z/KW41Z)
|
|
# make TARGET=nxp_lpc (NXP LPC1114)
|
|
# make TARGET=nuvoton_nano (Nuvoton NANO130)
|
|
# make run (run in QEMU — ARMv6m only)
|
|
# make clean (clean build artifacts)
|
|
|
|
# === Target selection ===
|
|
TARGET ?= lm3s6965evb
|
|
|
|
# Target → port directory mapping
|
|
ifeq ($(TARGET),lm3s6965evb)
|
|
PORT_DIR = ports/armv6m
|
|
CPU = -mcpu=cortex-m0 -mthumb
|
|
QEMU = qemu-system-arm
|
|
QEMU_MACH = lm3s6965evb
|
|
QEMU_CPU = cortex-m3
|
|
QEMU_MEM = 16K
|
|
else ifeq ($(TARGET),stm32f0)
|
|
PORT_DIR = ports/stm32f0
|
|
CPU = -mcpu=cortex-m0 -mthumb
|
|
QEMU = qemu-system-arm
|
|
QEMU_MACH = stm32f072b-discovery
|
|
QEMU_CPU = cortex-m0
|
|
QEMU_MEM = 16K
|
|
else ifeq ($(TARGET),stm32g0)
|
|
PORT_DIR = ports/stm32g0
|
|
CPU = -mcpu=cortex-m0plus -mthumb
|
|
QEMU = qemu-system-arm
|
|
QEMU_MACH = stm32g071b-st
|
|
QEMU_CPU = cortex-m0plus
|
|
QEMU_MEM = 36K
|
|
else ifeq ($(TARGET),stm32l0)
|
|
PORT_DIR = ports/stm32l0
|
|
CPU = -mcpu=cortex-m0plus -mthumb
|
|
QEMU = qemu-system-arm
|
|
QEMU_MACH = stm32l073rz
|
|
QEMU_CPU = cortex-m0plus
|
|
QEMU_MEM = 20K
|
|
else ifeq ($(TARGET),nxp_kl)
|
|
PORT_DIR = ports/nxp_kl
|
|
CPU = -mcpu=cortex-m0plus -mthumb
|
|
QEMU = qemu-system-arm
|
|
QEMU_MACH = frdm-kl25z
|
|
QEMU_CPU = cortex-m0plus
|
|
QEMU_MEM = 16K
|
|
else ifeq ($(TARGET),nxp_lpc)
|
|
PORT_DIR = ports/nxp_lpc
|
|
CPU = -mcpu=cortex-m0 -mthumb
|
|
QEMU = qemu-system-arm
|
|
QEMU_MACH = lpc1114
|
|
QEMU_CPU = cortex-m0
|
|
QEMU_MEM = 4K
|
|
else ifeq ($(TARGET),nuvoton_nano)
|
|
PORT_DIR = ports/nuvoton_nano
|
|
CPU = -mcpu=cortex-m0 -mthumb
|
|
QEMU = qemu-system-arm
|
|
QEMU_MACH = numaker-pfm-nano130
|
|
QEMU_CPU = cortex-m0
|
|
QEMU_MEM = 16K
|
|
else ifeq ($(TARGET),lpc55s69)
|
|
PORT_DIR = ports/lpc55s69
|
|
CPU = -mcpu=cortex-m33 -mthumb -mfloat-abi=hard
|
|
QEMU = echo
|
|
QEMU_MACH = mps2-an505
|
|
QEMU_CPU = cortex-m33
|
|
QEMU_MEM = 256K
|
|
TIER_CFG = -DUOS_TIER=2 -DUOS_HAS_TZ=1 -DUOS_HAS_MPU=1
|
|
else ifeq ($(TARGET),mps2_m4)
|
|
PORT_DIR = ports/mps2_m4
|
|
CPU = -mcpu=cortex-m4 -mthumb
|
|
QEMU = qemu-system-arm
|
|
QEMU_MACH = mps2-an386
|
|
QEMU_CPU = cortex-m4
|
|
QEMU_MEM = 512K
|
|
TIER_CFG = -DUOS_TIER=1 -DUOS_HAS_MPU=1
|
|
CFLAGS_TIER = $(TIER_CFG)
|
|
else ifeq ($(TARGET),nordic_nrf51)
|
|
PORT_DIR = ports/nordic_nrf51
|
|
CPU = -mcpu=cortex-m0 -mthumb
|
|
QEMU = qemu-system-arm
|
|
QEMU_MACH = microbit
|
|
QEMU_CPU = cortex-m0
|
|
QEMU_MEM = 16K
|
|
else ifeq ($(TARGET),silabs_efm32)
|
|
PORT_DIR = ports/silabs_efm32
|
|
CPU = -mcpu=cortex-m3 -mthumb
|
|
QEMU = qemu-system-arm
|
|
QEMU_MACH = lm3s811evb
|
|
QEMU_CPU = cortex-m3
|
|
QEMU_MEM = 32K
|
|
else ifeq ($(TARGET),ambiq_apollo)
|
|
PORT_DIR = ports/ambiq_apollo
|
|
CPU = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard
|
|
QEMU = qemu-system-arm
|
|
QEMU_MACH = ast1030-evb
|
|
QEMU_CPU = cortex-m4
|
|
QEMU_MEM = 256K
|
|
else ifeq ($(TARGET),esp32)
|
|
XTENSA_ROOT = $(HOME)/.espressif/tools/xtensa-esp-elf/esp-14.2.0_20260121/xtensa-esp-elf
|
|
PORT_DIR = ports/esp32
|
|
override CC = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-gcc
|
|
override AS = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-as
|
|
override LD = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-ld
|
|
override OBJCOPY = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-objcopy
|
|
override SIZE = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-size
|
|
CPU = -mlongcalls -mtext-section-literals -mabi=call0
|
|
CFLAGS = $(TIER_CFG) $(CPU) -Iinclude -Iports/esp32 -Iports/common -DUOS_GDBSTUB=1
|
|
LDFLAGS = -T ports/esp32/linker.ld
|
|
QEMU = echo
|
|
QEMU_MACH = esp32
|
|
QEMU_CPU = esp32
|
|
else ifeq ($(TARGET),esp32s3)
|
|
XTENSA_ROOT = $(HOME)/.espressif/tools/xtensa-esp-elf/esp-14.2.0_20260121/xtensa-esp-elf
|
|
PORT_DIR = ports/esp32
|
|
override CC = $(XTENSA_ROOT)/bin/xtensa-esp32s3-elf-gcc
|
|
override AS = $(XTENSA_ROOT)/bin/xtensa-esp32s3-elf-as
|
|
override LD = $(XTENSA_ROOT)/bin/xtensa-esp32s3-elf-ld
|
|
override OBJCOPY = $(XTENSA_ROOT)/bin/xtensa-esp32s3-elf-objcopy
|
|
override SIZE = $(XTENSA_ROOT)/bin/xtensa-esp32s3-elf-size
|
|
CPU = -mlongcalls -mtext-section-literals -mabi=call0
|
|
CFLAGS = $(TIER_CFG) $(CPU) -Iinclude -Iports/esp32 -Iports/common -DUOS_GDBSTUB=1
|
|
LDFLAGS = -T ports/esp32/linker_s3.ld
|
|
QEMU = echo
|
|
QEMU_MACH = esp32s3
|
|
QEMU_CPU = esp32s3
|
|
|
|
else ifeq ($(TARGET),esp32idf)
|
|
XTENSA_ROOT = $(HOME)/.espressif/tools/xtensa-esp-elf/esp-14.2.0_20260121/xtensa-esp-elf
|
|
PORT_DIR = ports/esp32
|
|
override CC = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-gcc
|
|
override AS = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-as
|
|
override LD = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-ld
|
|
override OBJCOPY = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-objcopy
|
|
override SIZE = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-size
|
|
CPU = -mlongcalls -mtext-section-literals -mabi=call0
|
|
CFLAGS = $(TIER_CFG) $(CPU) -Iinclude -Iports/esp32 -Iports/common -DUOS_GDBSTUB=1 -DUOS_FLASH_XIP=1 -DUOS_GDBSTUB=1 -DUOS_SYSTEM_CLOCK=80000000
|
|
LDFLAGS = -T ports/esp32/linker_idf.ld -N
|
|
QEMU = qemu-system-xtensa
|
|
QEMU_MACH = esp32
|
|
QEMU_CPU = esp32
|
|
|
|
else ifeq ($(TARGET),esp32hw)
|
|
XTENSA_ROOT = $(HOME)/.espressif/tools/xtensa-esp-elf/esp-14.2.0_20260121/xtensa-esp-elf
|
|
PORT_DIR = ports/esp32
|
|
override CC = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-gcc
|
|
override AS = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-as
|
|
override LD = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-ld
|
|
override OBJCOPY = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-objcopy
|
|
override SIZE = $(XTENSA_ROOT)/bin/xtensa-esp32-elf-size
|
|
CPU = -mlongcalls -mtext-section-literals -mabi=call0
|
|
HAL_ROOT = $(CURDIR)/../hal/espressif/components
|
|
CFLAGS = $(TIER_CFG) $(CPU) -Iinclude -Iports/esp32 -Iports/common -DUOS_GDBSTUB=1 \
|
|
-I$(CURDIR)/../hal/espressif \
|
|
-I$(HAL_ROOT)/hal/esp32/include \
|
|
-I$(HAL_ROOT)/hal/include \
|
|
-I$(HAL_ROOT)/hal/platform_port/include \
|
|
-I$(HAL_ROOT)/esp_hal_uart/esp32/include \
|
|
-I$(HAL_ROOT)/esp_hal_uart/include \
|
|
-I$(HAL_ROOT)/esp_hal_wdt/esp32/include \
|
|
-I$(HAL_ROOT)/soc/esp32/include \
|
|
-I$(HAL_ROOT)/soc/esp32/register \
|
|
-I$(HAL_ROOT)/xtensa/esp32/include \
|
|
-I$(HAL_ROOT)/xtensa/include \
|
|
-I$(HAL_ROOT)/esp_common/include \
|
|
-I$(HAL_ROOT)/esp_rom/esp32 \
|
|
-DUOS_SYSTEM_CLOCK=80000000 -DUOS_FLASH_XIP=1 -DUOS_GDBSTUB=1
|
|
LDFLAGS = -T ports/esp32/linker_flash.ld -N
|
|
QEMU = qemu-system-xtensa
|
|
QEMU_MACH = esp32
|
|
QEMU_CPU = esp32
|
|
|
|
else
|
|
$(error Unknown target: $(TARGET). Valid: lm3s6965evb stm32f0 stm32g0 stm32l0 nxp_kl nxp_lpc nuvoton_nano)
|
|
endif
|
|
|
|
# === Build configuration ===
|
|
CC = arm-none-eabi-gcc
|
|
AS = arm-none-eabi-gcc
|
|
LD = arm-none-eabi-gcc
|
|
OBJCOPY = arm-none-eabi-objcopy
|
|
SIZE ?= arm-none-eabi-size
|
|
|
|
INCLUDES = -Iinclude -I$(PORT_DIR) -Iports/common
|
|
TIER_CFG ?=
|
|
ifeq ($(filter esp32 esp32s3 esp32hw esp32idf,$(TARGET)),)
|
|
CFLAGS = $(TIER_CFG) $(CPU) -std=c99 -Os -Wall -Wextra -Werror \
|
|
-ffreestanding -fno-builtin -fno-exceptions \
|
|
-ffunction-sections -fdata-sections $(INCLUDES)
|
|
endif
|
|
ASFLAGS = -mabi=call0 $(INCLUDES)
|
|
|
|
LIBGCC = $(shell $(CC) $(CPU) -print-libgcc-file-name)
|
|
ifeq ($(filter esp32 esp32s3 esp32hw esp32idf,$(TARGET)),)
|
|
LDFLAGS = $(CPU) -nostartfiles -Wl,--gc-sections -T $(PORT_DIR)/linker.ld
|
|
endif
|
|
|
|
BUILD_DIR = build/$(TARGET)
|
|
|
|
# === Source files ===
|
|
CORE_DIR = src/core
|
|
PERSONALITY_DIR = src/personality
|
|
TEST_DIR = test
|
|
|
|
# Architecture directory: PikeOS-style, one dir per ISA
|
|
ifeq ($(filter esp32 esp32s3 esp32hw esp32idf,$(TARGET)),)
|
|
ARCH_DIR = arch/arm
|
|
else
|
|
ARCH_DIR = arch/xtensa
|
|
endif
|
|
|
|
CORE_SRC = $(wildcard $(CORE_DIR)/*.c)
|
|
PERSONALITY_SRC = $(wildcard $(PERSONALITY_DIR)/*.c)
|
|
PORT_SRC = $(wildcard $(PORT_DIR)/*.c)
|
|
PORT_ASM = $(wildcard $(PORT_DIR)/*.S)
|
|
ARCH_SRC = $(wildcard $(ARCH_DIR)/src/*.c)
|
|
ARCH_ASM = $(wildcard $(ARCH_DIR)/src/*.S)
|
|
TEST_SRC = test/test_uos_esp32.c
|
|
|
|
CORE_OBJ = $(patsubst $(CORE_DIR)/%.c,$(BUILD_DIR)/core/%.o,$(CORE_SRC))
|
|
PERSONALITY_OBJ = $(patsubst $(PERSONALITY_DIR)/%.c,$(BUILD_DIR)/pers/%.o,$(PERSONALITY_SRC))
|
|
PORT_OBJ = $(patsubst $(PORT_DIR)/%.c,$(BUILD_DIR)/port/%.o,$(PORT_SRC))
|
|
PORT_AOBJ = $(patsubst $(PORT_DIR)/%.S,$(BUILD_DIR)/port/%.o,$(PORT_ASM))
|
|
ARCH_OBJ = $(patsubst $(ARCH_DIR)/src/%.c,$(BUILD_DIR)/arch/%.o,$(ARCH_SRC))
|
|
ARCH_AOBJ = $(patsubst $(ARCH_DIR)/src/%.S,$(BUILD_DIR)/arch/%.o,$(ARCH_ASM))
|
|
TEST_OBJ = $(patsubst $(TEST_DIR)/%.c,$(BUILD_DIR)/test/%.o,$(TEST_SRC))
|
|
|
|
OBJS = $(CORE_OBJ) $(PERSONALITY_OBJ) $(PORT_OBJ) $(PORT_AOBJ) $(ARCH_OBJ) $(ARCH_AOBJ) $(TEST_OBJ)
|
|
TARGET_ELF = $(BUILD_DIR)/universalisos.elf
|
|
TARGET_BIN = $(BUILD_DIR)/universalisos.bin
|
|
|
|
# === Rules ===
|
|
.PHONY: all clean run size
|
|
|
|
all: $(TARGET_ELF) size
|
|
|
|
$(TARGET_ELF): $(OBJS)
|
|
$(LD) $(LDFLAGS) $(OBJS) $(LIBGCC) -o $@
|
|
$(OBJCOPY) -O binary $@ $(TARGET_BIN)
|
|
|
|
$(BUILD_DIR)/core/%.o: $(CORE_DIR)/%.c
|
|
@mkdir -p $(dir $@)
|
|
$(CC) $(CFLAGS) -c $< -o $@
|
|
|
|
$(BUILD_DIR)/port/%.o: $(PORT_DIR)/%.c
|
|
@mkdir -p $(dir $@)
|
|
$(CC) $(CFLAGS) -c $< -o $@
|
|
|
|
$(BUILD_DIR)/pers/%.o: $(PERSONALITY_DIR)/%.c
|
|
@mkdir -p $(dir $@)
|
|
$(CC) $(CFLAGS) -c $< -o $@
|
|
|
|
$(BUILD_DIR)/port/%.o: $(PORT_DIR)/%.S
|
|
@mkdir -p $(dir $@)
|
|
$(CC) $(CFLAGS) -c $< -o $@
|
|
|
|
$(BUILD_DIR)/arch/%.o: $(ARCH_DIR)/src/%.c
|
|
@mkdir -p $(dir $@)
|
|
$(CC) $(CFLAGS) -c $< -o $@
|
|
|
|
$(BUILD_DIR)/arch/%.o: $(ARCH_DIR)/src/%.S
|
|
@mkdir -p $(dir $@)
|
|
$(CC) $(CFLAGS) -c $< -o $@
|
|
|
|
$(BUILD_DIR)/test/%.o: $(TEST_DIR)/%.c
|
|
@mkdir -p $(dir $@)
|
|
$(CC) $(CFLAGS) -c $< -o $@
|
|
|
|
size: $(TARGET_ELF)
|
|
@$(SIZE) $(TARGET_ELF)
|
|
|
|
# esp32hw: generate ESP32 flash image (requires esptool --chip esp32)
|
|
ifeq ($(TARGET),esp32hw)
|
|
flash-hw: $(TARGET_ELF)
|
|
esptool --chip esp32 elf2image --flash-mode dio --flash-size 2MB --flash-freq 40m \
|
|
$(TARGET_ELF) -o $(BUILD_DIR)/uos_hw.bin
|
|
@echo "ESP32 image: $(BUILD_DIR)/uos_hw.bin"
|
|
@echo "Flash: esptool --chip esp32 --port /dev/ttyACM0 --baud 460800 write_flash 0x10000 $(BUILD_DIR)/uos_hw.bin"
|
|
endif
|
|
|
|
# === Debug / GDB ===
|
|
GDB ?= xtensa-esp32-elf-gdb
|
|
GDB_BIN = $(HOME)/.espressif/tools/xtensa-esp-elf-gdb/16.3_20250913/xtensa-esp-elf-gdb/bin/xtensa-esp32-elf-gdb
|
|
|
|
# QEMU with GDB stub (port 1234, halt at startup)
|
|
debug-qemu: $(TARGET_ELF)
|
|
$(QEMU) -M $(QEMU_MACH) -cpu $(QEMU_CPU) -m $(QEMU_MEM) \
|
|
-nographic -s -S -kernel $(TARGET_ELF)
|
|
|
|
# GDB session against running QEMU stub
|
|
debug: $(TARGET_ELF)
|
|
$(GDB_BIN) -ex "target remote :1234" \
|
|
-ex "set confirm off" \
|
|
-ex "file $(TARGET_ELF)" \
|
|
-ex "symbol-file $(TARGET_ELF)" \
|
|
-ex "hb _start" \
|
|
-ex "c" $(TARGET_ELF)
|
|
|
|
run: $(TARGET_ELF)
|
|
$(QEMU) -M $(QEMU_MACH) -cpu $(QEMU_CPU) -m $(QEMU_MEM) \
|
|
-nographic -kernel $(TARGET_ELF)
|
|
|
|
clean:
|
|
rm -rf build
|