summaryrefslogtreecommitdiff
path: root/na/Makefile
diff options
context:
space:
mode:
Diffstat (limited to 'na/Makefile')
-rw-r--r--na/Makefile419
1 files changed, 0 insertions, 419 deletions
diff --git a/na/Makefile b/na/Makefile
deleted file mode 100644
index 88689f5..0000000
--- a/na/Makefile
+++ /dev/null
@@ -1,419 +0,0 @@
-# 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
-
-# ============================================================
-# 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-unknown-linux-gnu-g++ >/dev/null 2>&1; then \
- echo riscv64-unknown-linux-gnu-; \
- 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
-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))
-
-OBJCOPY_BINARCH_riscv := riscv
-OBJCOPY_BINARCH_aarch64 := aarch64
-OBJCOPY_BINARCH_x86_64 := i386:x86-64
-OBJCOPY_BINARCH := $(OBJCOPY_BINARCH_$(ARCH))
-
-# Common flags (base, before module includes)
-WARNINGS := -Wall -Wextra -Wno-unused-parameter
-INCLUDES := -Iinclude -I.
-
-# ============================================================
-# 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 :=
-
--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
-
-# -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
-
-# C flags for musl libc sources: add libc-shim headers first
-CFLAGS_LIBC := $(CFLAGS) -Iinclude/libc-shim \
- -Wno-parentheses -Wno-sign-compare
-
-CXXFLAGS := $(CFLAGS) \
- -std=c++17 \
- -fno-exceptions -fno-rtti -fno-use-cxa-atexit \
- -fno-threadsafe-statics
-
-# 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))
-
-# 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
-
-# ============================================================
-# 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 Rules
-# ============================================================
-.PHONY: all clean run debug fmt disasm defconfig savedefconfig showconfig
-
-all: $(VMLUME) $(IMAGE)
-
-# Generate autoconf.h before any compilation
-$(AUTOCONF_H): scripts/Kconfig.mk $(wildcard .config)
- $(generate-autoconf)
-
-# ============================================================
-# 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 $@)
- @$(CC) $(CFLAGS_LIBC) -S $< -o $@
-
-# 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 "/* 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)
-
-# ============================================================
-# 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 $@)
- @$(CC) -E -P -x c $(INCLUDES) $< -o $@
-
-# ============================================================
-# 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
-
-# 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 $@ $<
-
-INITRAMFS_SOURCE := $(CONFIG_INITRAMFS_SOURCE)
-
-# 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)
-
-$(INITRAMFS_CPIO): $(INITRAMFS_SOURCE) $(INITRAMFS_SRC_STAMP) \
- $(GEN_INIT_CPIO) scripts/gen_initramfs.sh
- @echo " INITRAMFS $(INITRAMFS_SOURCE)"
- @mkdir -p $(dir $@)
- @./scripts/gen_initramfs.sh -o $@ \
- -u $(CONFIG_INITRAMFS_ROOT_UID) \
- -g $(CONFIG_INITRAMFS_ROOT_GID) \
- $(INITRAMFS_SOURCE)
-
-$(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 $@)
- @$(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)
-
-$(BUILD)/%.o: %.S
- $(Q)mkdir -p $(dir $@)
- $(call cmd,as_o_S)
-
-$(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) $(QEMU_MACHINE) $(QEMU_BIOS) -kernel $(VMLUME)
-
-debug: $(VMLUME) $(IMAGE)
- @echo " QEMU Waiting for GDB on :1234..."
- $(QEMU) $(QEMU_MACHINE) $(QEMU_BIOS) -kernel $(VMLUME) -s -S
-
-# ============================================================
-# Utilities
-# ============================================================
-clean:
- 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)"