diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-07-10 11:31:46 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-07-10 11:31:46 +0800 |
| commit | e90b72ec3082588b296956730bd2930cf8d5d671 (patch) | |
| tree | 36ff6916af9b4176ea5a9662219d11e721f0b691 /Makefile | |
| parent | 1767d390fbf3d0c65389de46caf0b6d43ef3b6ad (diff) | |
| download | lume-e90b72ec3082588b296956730bd2930cf8d5d671.tar.gz lume-e90b72ec3082588b296956730bd2930cf8d5d671.tar.xz | |
refactor: promote new architecture to repository root
Archive the deprecated implementation under lume-legacy, make the new kernel the default root-level build, and update repository entry points without changing kernel behavior.
Diffstat (limited to 'Makefile')
| -rw-r--r-- | Makefile | 458 |
1 files changed, 368 insertions, 90 deletions
@@ -1,20 +1,81 @@ # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (C) 2026 Richard Qin +# +# LumeOS Kernel Makefile (Non-Recursive) +# +# Usage: +# make - Build kernel ELF +# make run - Run in QEMU +# make debug - Run in QEMU with GDB server +# make clean - Clean build artifacts +# make fmt - Format all source files +# make disasm - Generate disassembly listing +# +# Reference: docs/specs/00_conventions.md §7 -# Try to find a suitable RISC-V toolchain prefix +# ============================================================ +# Build Configuration +# ============================================================ +BUILD := build + +# Make sure `make` with no arguments builds the kernel image, not the +# first rule encountered during makefile parsing. scripts/Kconfig.mk +# (included next) defines `defconfig:` at the top of its rule list, +# which would otherwise become the default goal and silently overwrite +# .config from arch/$(ARCH)/defconfig. +.DEFAULT_GOAL := all + +# Load Kbuild helpers (Q, $(call cmd,...), quiet_cmd_* / cmd_* templates, +# kbuild-objs translator). Must come before Kconfig.mk so subsequent +# rules can use $(call cmd,...) immediately. +include scripts/Kbuild.include + +# Load Kconfig infrastructure (reads .config, sets KCPPFLAGS) +include scripts/Kconfig.mk + +ARCH ?= $(CONFIG_ARCH) + +# Two boot products — same pair as Linux RISC-V's arch/riscv/boot/Makefile +# (vmlinux + Image), but named LumeOS-style: +# VMLUME -> build/vmlume.elf : ELF with .symtab/PT_DYNAMIC/.rela.dyn +# IMAGE -> build/vmlume.bin : raw binary (objcopy -O binary) +VMLUME := $(BUILD)/vmlume.elf +IMAGE := $(BUILD)/vmlume.bin + +# Initramfs paths +INITRAMFS_DIR := $(BUILD)/initramfs +INITRAMFS_CPIO := $(BUILD)/initramfs.cpio +INITRAMFS_OBJ := $(BUILD)/initramfs.o +USR_INIT_ELF := $(BUILD)/usr/init +# Relocations: linker emits .rela.dyn under -shared -Bsymbolic; boot +# code in arch/riscv/mm/init.cc::relocate_kernel walks it at startup. +LDS_SRC := arch/$(ARCH)/kernel/lumeos.lds.S +LINKER_SCRIPT := $(BUILD)/lumeos.lds +PYTHON ?= python3 + +# ============================================================ +# Toolchain Detection +# ============================================================ ifndef TOOLCHAIN_PREFIX +ifeq ($(ARCH),riscv) + # Prefer the linux-gnu toolchain — it supports -shared / -pie which + # are required to emit .rela.dyn (Linux RISC-V kernel uses the same). + # The bare-metal `riscv64-unknown-elf-` is kept only as a last-resort + # fallback; with that one, `-shared` fails ("not supported") and the + # kernel can't relocate at runtime. TOOLCHAIN_PREFIX := $(shell \ - if command -v riscv64-linux-gnu-gcc >/dev/null 2>&1; then \ - echo riscv64-linux-gnu-; \ - elif command -v riscv64-unknown-gnu-gcc >/dev/null 2>&1; then \ - echo riscv64-unknown-gnu-; \ - elif command -v riscv64-unknown-linux-gnu-gcc >/dev/null 2>&1; then \ + if command -v riscv64-unknown-linux-gnu-g++ >/dev/null 2>&1; then \ echo riscv64-unknown-linux-gnu-; \ - elif command -v riscv64-unknown-elf-gcc >/dev/null 2>&1; then \ - echo riscv64-unknown-elf-; \ - else \ + elif command -v riscv64-linux-gnu-g++ >/dev/null 2>&1; then \ echo riscv64-linux-gnu-; \ + else \ + echo riscv64-unknown-linux-gnu-; \ fi) +else ifeq ($(ARCH),aarch64) + TOOLCHAIN_PREFIX := aarch64-linux-gnu- +else ifeq ($(ARCH),x86_64) + TOOLCHAIN_PREFIX := x86_64-linux-gnu- +endif endif CC := $(TOOLCHAIN_PREFIX)gcc @@ -22,120 +83,337 @@ CXX := $(TOOLCHAIN_PREFIX)g++ LD := $(TOOLCHAIN_PREFIX)ld OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy OBJDUMP := $(TOOLCHAIN_PREFIX)objdump +# Objcopy output formats for binary-to-ELF relocation blob +OBJCOPY_ELF_riscv := elf64-littleriscv +OBJCOPY_ELF_aarch64 := elf64-littleaarch64 +OBJCOPY_ELF_x86_64 := elf64-x86-64 +OBJCOPY_ELF := $(OBJCOPY_ELF_$(ARCH)) -BUILD_DIR := build -SRC_DIR := src +OBJCOPY_BINARCH_riscv := riscv +OBJCOPY_BINARCH_aarch64 := aarch64 +OBJCOPY_BINARCH_x86_64 := i386:x86-64 +OBJCOPY_BINARCH := $(OBJCOPY_BINARCH_$(ARCH)) -CFLAGS := -Wall -Wextra -O2 -g -ffreestanding -nostdlib -mcmodel=medany -Iinclude -CXXFLAGS := $(CFLAGS) -fno-exceptions -fno-rtti -fno-use-cxa-atexit -LINKER_SCRIPT := linker.ld +# Common flags (base, before module includes) +WARNINGS := -Wall -Wextra -Wno-unused-parameter +INCLUDES := -Iinclude -I. -USER_LD := $(SRC_DIR)/user/user.ld -ULIB_OBJS := $(BUILD_DIR)/user/entry.o \ - $(BUILD_DIR)/user/usys.o \ - $(BUILD_DIR)/ulib/stdio.o \ - $(BUILD_DIR)/ulib/stdlib.o \ - $(BUILD_DIR)/ulib/string.o \ - $(BUILD_DIR)/ulib/cxx.o \ - $(BUILD_DIR)/ulib/iostream.o \ - $(BUILD_DIR)/ulib/syscalls.o +# ============================================================ +# Source Collection (Non-Recursive Module Fragments) +# Module .mk files may append to SRCS_CC, SRCS_S, INCLUDES +# ============================================================ +SRCS_CC := +SRCS_C := +SRCS_S := +SRCS_s := -INITCODE_BIN := $(BUILD_DIR)/user/initcode +-include arch/$(ARCH)/module.mk +include kernel/module.mk +include mm/module.mk +include fs/module.mk +include drivers/base/module.mk +include drivers/module.mk +include drivers/tty/module.mk +include fdt/module.mk +include lib/module.mk +include test/module.mk +# Compiler flags (defined AFTER includes so INCLUDES is complete) +CFLAGS := $(WARNINGS) -O2 -g \ + -ffreestanding -nostdlib \ + -mcmodel=medany \ + -fPIE \ + -MMD -MP \ + $(KCPPFLAGS) \ + $(INCLUDES) \ + -I$(BUILD)/generated -USER_SRCS := $(wildcard $(SRC_DIR)/user/*.cc) -UPROGS := $(patsubst $(SRC_DIR)/user/%.cc, $(BUILD_DIR)/user/%, $(USER_SRCS)) +# -fPIE makes the compiler emit position-independent code (PC-relative +# addressing + GOT for globals), which is what `-shared` linking expects. +# Mirrors Linux's arch/riscv/Makefile under CONFIG_RELOCATABLE=y: +# KBUILD_CFLAGS += -fPIE -SRCS_S := $(shell find $(SRC_DIR) -name "*.S" -not -path "$(SRC_DIR)/user/*" -not -path "$(SRC_DIR)/ulib/*") -SRCS_CXX := $(shell find $(SRC_DIR) -name "*.cc" -not -path "$(SRC_DIR)/user/*" -not -path "$(SRC_DIR)/ulib/*") -OBJS := $(SRCS_S:%.S=$(BUILD_DIR)/%.o) $(SRCS_CXX:%.cc=$(BUILD_DIR)/%.o) +# C flags for musl libc sources: add libc-shim headers first +CFLAGS_LIBC := $(CFLAGS) -Iinclude/libc-shim \ + -Wno-parentheses -Wno-sign-compare -TARGET := $(BUILD_DIR)/kernel.elf +CXXFLAGS := $(CFLAGS) \ + -std=c++17 \ + -fno-exceptions -fno-rtti -fno-use-cxa-atexit \ + -fno-threadsafe-statics -QEMUOPTS = -drive file=fs.img,if=none,format=raw,id=x0 -QEMUOPTS += -device virtio-blk-device,drive=x0 -global virtio-mmio.force-legacy=false +# Assembler flags MUST NOT include -fPIE. +# Linux's arch/riscv/Makefile adds -fPIE only to KBUILD_CFLAGS, NOT to +# KBUILD_AFLAGS: with -fPIE the gcc driver puts the assembler in PIC +# mode, where the `la` macro silently expands to a GOT-indirect load +# (`auipc + ld` reading a slot that holds the link-time VA). In our +# pre-MMU boot path that VA is unmapped, so any `la sym, sym` faults +# and reboots into a `_start` loop. Stripping -fPIE makes `la` emit +# direct PC-relative addressing (`auipc + addi`) which works at PA. +ASFLAGS := $(filter-out -fPIE,$(CFLAGS)) -.PHONY: all clean run debug +# Link as a position-independent shared object so the linker emits +# `.rela.dyn` with R_RISCV_RELATIVE entries that the boot stub applies +# at load time. Mirrors Linux's arch/riscv/Makefile §10: +# LDFLAGS_vmlinux += -shared -Bsymbolic -z notext +# `-Bsymbolic` resolves all global refs at link time (no dynamic +# resolution); `-z notext` lets us keep relocations in code pages. +LDFLAGS := -nostdlib -shared -Bsymbolic -z notext -z norelro --no-dynamic-linker -all: $(TARGET) $(INITCODE_BIN) $(UPROGS) fs.img +# ============================================================ +# Object File Computation +# ============================================================ +OBJS := $(patsubst %.cc,$(BUILD)/%.o,$(SRCS_CC)) \ + $(patsubst %.c,$(BUILD)/%.o,$(SRCS_C)) \ + $(patsubst %.S,$(BUILD)/%.o,$(SRCS_S)) \ + $(patsubst %.s,$(BUILD)/%.o,$(SRCS_s)) +DEPS := $(OBJS:.o=.d) -$(BUILD_DIR)/ulib/%.o: $(SRC_DIR)/ulib/%.c - @mkdir -p $(dir $@) - @echo " ULIB_C $<" - @$(CC) $(CFLAGS) -c $< -o $@ +# ============================================================ +# Build Rules +# ============================================================ +.PHONY: all clean run debug fmt disasm defconfig savedefconfig showconfig -$(BUILD_DIR)/ulib/%.o: $(SRC_DIR)/ulib/%.cc - @mkdir -p $(dir $@) - @echo " ULIB_CC $<" - @$(CXX) $(CXXFLAGS) -c $< -o $@ +all: $(VMLUME) $(IMAGE) + +# Generate autoconf.h before any compilation +$(AUTOCONF_H): scripts/Kconfig.mk $(wildcard .config) + $(generate-autoconf) -$(BUILD_DIR)/ulib/%.o: $(SRC_DIR)/ulib/%.cpp +# ============================================================ +# Generated header: asm-offsets.h +# +# Linux-style trick (mirrors include/linux/kbuild.h + arch/*/kernel/ +# asm-offsets.c + scripts/Makefile.build): compile asm-offsets.c to +# assembly, scrape the magic `->SYM val` markers produced by the +# DEFINE/OFFSET inline-asm macros, rewrite them into `#define` +# directives via sed. head.S and friends then `#include +# <generated/asm-offsets.h>` to access struct field offsets without +# having to hand-maintain them — re-order a struct field, the +# generated constant follows. +# ============================================================ +ASM_OFFSETS_C := arch/$(ARCH)/kernel/asm-offsets.c +ASM_OFFSETS_S := $(BUILD)/arch/$(ARCH)/kernel/asm-offsets.s +ASM_OFFSETS_H := $(BUILD)/generated/asm-offsets.h +ASM_OFFSETS_SED := scripts/extract-asm-offsets.sed + +# Compile asm-offsets.c to *.s only — we never want the .o linked in. +$(ASM_OFFSETS_S): $(ASM_OFFSETS_C) $(AUTOCONF_H) + @echo " CC -S $<" @mkdir -p $(dir $@) - @echo " ULIB_CPP $<" - @$(CXX) $(CXXFLAGS) -c $< -o $@ + @$(CC) $(CFLAGS_LIBC) -S $< -o $@ -$(BUILD_DIR)/user/%.o: $(SRC_DIR)/user/%.cc +# Rewrite ->NAME markers into #define lines. Header guard hand-rolled +# at the top, sed body in the middle, closing #endif at the bottom. +$(ASM_OFFSETS_H): $(ASM_OFFSETS_S) $(ASM_OFFSETS_SED) + @echo " GEN $@" @mkdir -p $(dir $@) - @echo " USER_CC $<" - @$(CXX) $(CXXFLAGS) -c $< -o $@ + @(echo "/* AUTO-GENERATED — DO NOT EDIT */"; \ + echo "/* Generated from $(ASM_OFFSETS_C) by scripts/extract-asm-offsets.sed */"; \ + echo "#ifndef _LUME_GENERATED_ASM_OFFSETS_H"; \ + echo "#define _LUME_GENERATED_ASM_OFFSETS_H"; \ + echo ""; \ + sed -n -f $(ASM_OFFSETS_SED) $<; \ + echo ""; \ + echo "#endif /* _LUME_GENERATED_ASM_OFFSETS_H */") > $@ + +# All objects depend on autoconf.h and asm-offsets.h +$(OBJS): $(AUTOCONF_H) $(ASM_OFFSETS_H) -$(BUILD_DIR)/user/%.o: $(SRC_DIR)/user/%.S +# ============================================================ +# Generic %.pi.o post-processing rule +# +# Mirrors arch/riscv/kernel/pi/Makefile §26-30 in Linux: +# +# $(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ +# --remove-section=.note.gnu.property +# --prefix-alloc-sections=.init.pi +# $(obj)/%.pi.o: $(obj)/%.o FORCE +# $(call if_changed,objcopy) +# +# Purpose: take a regular .o produced by the normal compile rule and +# rewrite it so the early position-independent code can coexist with +# the rest of the kernel without symbol clashes: +# +# --prefix-symbols=__pi_ Every global symbol becomes __pi_<name>. +# head.S calls them as __pi_fdt_path_offset +# etc., keeping the pre-MMU namespace +# cleanly isolated. +# +# --prefix-alloc-sections=.init.pi +# All SHF_ALLOC sections get re-prefixed +# so they land in .init.pi in vmlinux.lds.S, +# which positions them where the boot +# loader has already mapped memory. +# +# --remove-section=.note.gnu.property +# Discarded because post-rename it can +# confuse the linker about ELF features. +# +# Generic pattern (`$(BUILD)/%.pi.o`) so any subdir's source can opt in +# by listing a `.pi.o` target in its SRCS. The companion compile-side +# CFLAGS overrides (replacing -fPIE with -fpie, adding -Os, etc.) are +# expected to come from the subdir's own .mk fragment via target- +# specific CFLAGS_LIBC / CXXFLAGS overrides. +# ============================================================ +$(BUILD)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \ + --remove-section=.note.gnu.property \ + --prefix-alloc-sections=.init.pi + +$(BUILD)/%.pi.o: $(BUILD)/%.o + $(call cmd,objcopy) + +# Preprocess linker script template (.lds.S → .lds) +$(LINKER_SCRIPT): $(LDS_SRC) include/lume/lumeos.lds.h + @echo " LDS $@" @mkdir -p $(dir $@) - @echo " USER_AS $<" - @$(CC) $(CFLAGS) -c $< -o $@ + @$(CC) -E -P -x c $(INCLUDES) $< -o $@ -$(INITCODE_BIN): $(BUILD_DIR)/user/init.o $(ULIB_OBJS) $(USER_LD) - @echo " U_LD $@" - @$(LD) -T $(USER_LD) -o $@.out $(BUILD_DIR)/user/init.o $(ULIB_OBJS) - @$(OBJCOPY) -S -O binary $@.out $@ - @$(OBJDUMP) -S $@.out > $@.asm +# ============================================================ +# Initramfs: pack a root filesystem into a newc cpio. +# +# Pipeline mirrors Linux's Kbuild: +# usr/gen_init_cpio — host C tool, produces cpio bytes +# scripts/gen_initramfs.sh — wrapper that prepares the listing, +# handles directories vs. listing files, +# applies uid/gid remap, then invokes the +# host tool. +# Sourced from $(CONFIG_INITRAMFS_SOURCE) — see scripts/Kconfig.mk. +# ============================================================ +# Host compiler — distinct from $(CC), which may be the cross compiler. +HOSTCC ?= cc +HOSTCFLAGS ?= -O2 -Wall -$(BUILD_DIR)/user/%: $(BUILD_DIR)/user/%.o $(ULIB_OBJS) $(USER_LD) - @echo " USER_LD $@" - @$(LD) -T $(USER_LD) -o $@ $< $(ULIB_OBJS) - @$(OBJDUMP) -S $@ > $@.asm - @$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $@.sym +# Output path matches Linux convention (usr/gen_init_cpio) so the +# verbatim copy of scripts/gen_initramfs.sh from Linux finds it via its +# hardcoded relative path when invoked from the kernel source root. +GEN_INIT_CPIO := usr/gen_init_cpio +$(GEN_INIT_CPIO): usr/gen_init_cpio.c + @echo " HOSTCC $@" + @$(HOSTCC) $(HOSTCFLAGS) -o $@ $< -$(TARGET): $(OBJS) $(LINKER_SCRIPT) - @echo " K_LD $@" - @$(LD) -T $(LINKER_SCRIPT) -o $@ $(OBJS) - @echo " K_ASM $@.asm" - @$(OBJDUMP) -S $@ > $@.asm - @$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $@.sym +INITRAMFS_SOURCE := $(CONFIG_INITRAMFS_SOURCE) -$(BUILD_DIR)/src/kernel/initcode.o: $(SRC_DIR)/kernel/initcode.S $(INITCODE_BIN) - @mkdir -p $(dir $@) - @echo " AS_INC $<" - @$(CC) $(CFLAGS) -c $< -o $@ +# Record the chosen source so changing CONFIG_INITRAMFS_SOURCE on the +# command line forces a rebuild — without this, `make` only compares +# file mtimes and would happily reuse a cpio packed from a different +# source as long as that other source isn't newer. Evaluated at +# Makefile parse time so the dep edge is correct from the first rule +# check. Mirrors the idea behind Linux's $(call if_changed,...). +INITRAMFS_SRC_STAMP := $(BUILD)/.initramfs_src.stamp +$(shell mkdir -p $(BUILD) 2>/dev/null; \ + prev=$$([ -f "$(INITRAMFS_SRC_STAMP)" ] && cat "$(INITRAMFS_SRC_STAMP)" || echo); \ + if [ "$$prev" != "$(INITRAMFS_SOURCE)" ]; then \ + printf '%s\n' "$(INITRAMFS_SOURCE)" > "$(INITRAMFS_SRC_STAMP)"; \ + fi) -$(BUILD_DIR)/%.o: %.S +$(INITRAMFS_CPIO): $(INITRAMFS_SOURCE) $(INITRAMFS_SRC_STAMP) \ + $(GEN_INIT_CPIO) scripts/gen_initramfs.sh + @echo " INITRAMFS $(INITRAMFS_SOURCE)" @mkdir -p $(dir $@) - @echo " K_AS $<" - @$(CC) $(CFLAGS) -c $< -o $@ + @./scripts/gen_initramfs.sh -o $@ \ + -u $(CONFIG_INITRAMFS_ROOT_UID) \ + -g $(CONFIG_INITRAMFS_ROOT_GID) \ + $(INITRAMFS_SOURCE) -$(BUILD_DIR)/%.o: %.cc +$(INITRAMFS_OBJ): $(INITRAMFS_CPIO) + @echo " OBJCOPY $@ (initramfs)" + @$(OBJCOPY) -I binary -O $(OBJCOPY_ELF) -B $(OBJCOPY_BINARCH) \ + --rename-section .data=.init.ramfs,alloc,load,readonly,data,contents \ + $< $@ + +# Single-pass kernel link. With `-shared -Bsymbolic`, the linker +# emits `.rela.dyn` containing R_RISCV_RELATIVE entries directly into +# the output ELF — no separate gen_reloc pass. +$(VMLUME): $(OBJS) $(INITRAMFS_OBJ) $(LINKER_SCRIPT) + @echo " LD $@" @mkdir -p $(dir $@) - @echo " K_CXX $<" - @$(CXX) $(CXXFLAGS) -c $< -o $@ + @$(LD) $(LDFLAGS) -T $(LINKER_SCRIPT) -o $@ $(OBJS) $(INITRAMFS_OBJ) + @$(TOOLCHAIN_PREFIX)size $@ + +# Image = raw binary, mirrors Linux's `arch/riscv/boot/Image` (objcopy +# vmlinux to raw bytes, no ELF header — what U-Boot or QEMU's `-bios` +# bare-loading would consume). Linux always builds both vmlinux and +# Image; LumeOS follows the same convention. +$(IMAGE): $(VMLUME) + @echo " OBJCOPY $@" + @$(OBJCOPY) -O binary $< $@ + +# Compile C++ sources. Recipe goes through $(call cmd,...) so that +# `make V=1` echoes the full command line. $(Q) prefix on mkdir keeps +# the directory-creation step silent in quiet mode but visible at V=1. +$(BUILD)/%.o: %.cc + $(Q)mkdir -p $(dir $@) + $(call cmd,cxx_o_cc) + +$(BUILD)/%.o: %.c + $(Q)mkdir -p $(dir $@) + $(call cmd,cc_o_c) -fs.img: $(UPROGS) - @echo " IMG Generating fs.img (FAT32)" - @dd if=/dev/zero of=fs.img bs=1M count=32 2>/dev/null - @mkfs.vfat -F 32 fs.img >/dev/null - $(foreach prog,$(UPROGS),mcopy -i fs.img $(prog) ::/$(notdir $(prog));) +$(BUILD)/%.o: %.S + $(Q)mkdir -p $(dir $@) + $(call cmd,as_o_S) -run: $(TARGET) fs.img +$(BUILD)/%.o: %.s + $(Q)mkdir -p $(dir $@) + $(call cmd,as_o_S) + +# Auto-dependency tracking +-include $(DEPS) + +# ============================================================ +# Run & Debug +# ============================================================ +ifeq ($(ARCH),riscv) +QEMU := qemu-system-riscv64 +QEMU_MACHINE := -machine virt -smp 4 -m 128M -nographic +QEMU_BIOS := -bios default +else ifeq ($(ARCH),aarch64) +QEMU := qemu-system-aarch64 +QEMU_MACHINE := -machine virt -cpu cortex-a53 -m 128M -nographic +QEMU_BIOS := +else ifeq ($(ARCH),x86_64) +QEMU := qemu-system-x86_64 +QEMU_MACHINE := -m 128M -nographic +QEMU_BIOS := +endif + +run: $(VMLUME) $(IMAGE) @echo " QEMU Running..." - @qemu-system-riscv64 -machine virt -nographic \ - -kernel $(TARGET) -m 128M $(QEMUOPTS) + $(QEMU) $(QEMU_MACHINE) $(QEMU_BIOS) -kernel $(VMLUME) -debug: $(TARGET) fs.img - @echo " QEMU (DEBUG) Waiting for GDB..." - @qemu-system-riscv64 -machine virt -nographic \ - -kernel $(TARGET) -m 128M -s -S $(QEMUOPTS) +debug: $(VMLUME) $(IMAGE) + @echo " QEMU Waiting for GDB on :1234..." + $(QEMU) $(QEMU_MACHINE) $(QEMU_BIOS) -kernel $(VMLUME) -s -S +# ============================================================ +# Utilities +# ============================================================ clean: - rm -rf $(BUILD_DIR) fs.img
\ No newline at end of file + rm -rf $(BUILD) + +disasm: $(VMLUME) + @echo " OBJDUMP $<" + @$(OBJDUMP) -d -S $(VMLUME) > $(VMLUME).asm + @echo " Written to $(VMLUME).asm" + +fmt: + @echo " FMT Formatting source files..." + @find . -name '*.cc' -o -name '*.h' | xargs clang-format -i 2>/dev/null || true + +lint: + @echo " LINT Generating compile_commands.json via bear..." + @bear -- $(MAKE) all + @echo " LINT Running clang-tidy on C++ sources..." + @clang-tidy -p . $(SRCS_CC) || true + +# Print build info (for debugging Makefile issues) +info: + @echo "TOOLCHAIN_PREFIX = $(TOOLCHAIN_PREFIX)" + @echo "SRCS_CC = $(SRCS_CC)" + @echo "SRCS_S = $(SRCS_S)" + @echo "OBJS = $(OBJS)" + @echo "KCPPFLAGS = $(KCPPFLAGS)" |
