diff --git a/Makefile b/Makefile index d3fa917..f994fe8 100644 --- a/Makefile +++ b/Makefile @@ -9,10 +9,10 @@ html: ## 1. Basic Setup and Checks -### Default to create all static libraries +### Default to create a bare-metal kernel image ifeq ($(MAKECMDGOALS),) - MAKECMDGOALS = libs - .DEFAULT_GOAL = libs + MAKECMDGOALS = image + .DEFAULT_GOAL = image endif ### Override checks when `make clean/clean-all/html` @@ -37,7 +37,7 @@ PLATFORM = $(word 2,$(ARCH_SPLIT)) ### Checks end here endif -## 2. Setup variables pointing to build and install directory +## 2. General Compilation Targets ### Create the destination directory (`build/$ARCH`) WORK_DIR ?= $(shell pwd) @@ -47,7 +47,7 @@ INSTALLDIR ?= $(WORK_DIR)/build/install/$(ARCH) LIB_INSTALLDIR ?= $(INSTALLDIR)/lib INC_INSTALLDIR ?= $(INSTALLDIR)/include -## 3. Toolchain setup +## 3. General Compilation Flags ### (Cross) compilers, e.g., mips-linux-gnu-g++ CC ?= $(CROSS_COMPILE)gcc @@ -59,38 +59,37 @@ OBJDUMP ?= $(CROSS_COMPILE)objdump OBJCOPY ?= $(CROSS_COMPILE)objcopy READELF ?= $(CROSS_COMPILE)readelf +CXXFLAGS += $(CFLAGS) -ffreestanding -fno-rtti -fno-exceptions +LDFLAGS += -z noexecstack +INTERFACE_LDFLAGS += -z noexecstack + ## 4. Arch-Specific Configurations -# TODO: Removed CROSS_COMPILE toolchain setup as it's too complicated -# for Makefile to do right. Force the user to provide a CROSS_COMPILE -# prefix for now. They can also specify CFLAGS and LDFLAGS through -# environment variable. -include $(AM_HOME)/scripts/$(ARCH).mk +### Fall back to native gcc/binutils if there is no cross compiler +ifeq ($(wildcard $(shell which $(CC))),) + $(info # $(CC) not found; fall back to default gcc and binutils) + CROSS_COMPILE := riscv64-unknown-linux-gnu- +endif ## 5. Compilation Rules BUILDDIR := $(DST_DIR) -COMMON_CFLAGS := $(CFLAGS) -g -O3 -MMD -Wall \ - -fno-asynchronous-unwind-tables -fno-builtin -fno-stack-protector \ - -Wno-main -U_FORTIFY_SOURCE -fvisibility=hidden -INTERFACE_LDFLAGS += -z noexecstack -INTERFACE_CFLAGS += -fno-asynchronous-unwind-tables \ - -fno-builtin -fno-stack-protector \ - -Wno-main -U_FORTIFY_SOURCE -fvisibility=hidden ### Build libam + #### Include archetecture specific build flags -COMMON_CFLAGS += -D__ARCH_$(shell echo $(ARCH) | tr a-z A-Z | tr - _) \ - -D__ISA_$(shell echo $(ISA) | tr a-z A-Z)__ \ - -DARCH_H=\"$(ARCH_H)\" -INTERFACE_CFLAGS += -DARCH_H=\"$(ARCH_H)\" +include $(AM_HOME)/scripts/$(ARCH).mk #### Generating build rules with ADD_LIBRARY call. Target specific build flags can be tuned via changing prefixed variables (AM_ here) AM_INCPATH += $(AM_HOME)/am/include $(AM_HOME)/am/src $(AM_HOME)/klib/include -AM_CFLAGS += $(COMMON_CFLAGS) $(addprefix -I, $(AM_INCPATH)) +AM_CFLAGS += -lm -g -O3 -MMD -Wall $(addprefix -I, $(AM_INCPATH)) \ + -D__ISA__=\"$(ISA)\" -D__ISA_$(shell echo $(ISA) | tr a-z A-Z)__ \ + -D__ARCH__=$(ARCH) -D__ARCH_$(shell echo $(ARCH) | tr a-z A-Z | tr - _) \ + -D__PLATFORM__=$(PLATFORM) -D__PLATFORM_$(shell echo $(PLATFORM) | tr a-z A-Z | tr - _) \ + -DARCH_H=\"$(ARCH_H)\" AM_INTERFACE_INCPATH += $(AM_HOME)/am/include $(AM_HOME)/klib/include -AM_INTERFACE_CFLAGS += - -AM_INTERFACE_LDFLAGS += -lm -lam-$(ARCH) +AM_INTERFACE_CFLAGS += $(addprefix -I, $(AM_INTERFACE_INCPATH:%=$(INC_INSTALLDIR))) \ + -lm -DARCH_H=\"$(ARCH_H)\" -fno-asynchronous-unwind-tables -fno-builtin -fno-stack-protector \ + -Wno-main -U_FORTIFY_SOURCE -fvisibility=hidden $(eval $(call ADD_LIBRARY,$(LIB_BUILDDIR)/libam-$(ARCH).a,AM_)) @@ -99,10 +98,10 @@ $(eval $(call ADD_LIBRARY,$(LIB_BUILDDIR)/libam-$(ARCH).a,AM_)) KLIB_SRCS := $(shell find klib/src/ -name "*.c") KLIB_INCPATH += $(AM_HOME)/am/include $(AM_HOME)/klib/include -KLIB_CFLAGS += $(COMMON_CFLAGS) $(addprefix -I, $(KLIB_INCPATH)) +KLIB_CFLAGS += -MMD -Wall $(addprefix -I, $(KLIB_INCPATH)) \ + -DARCH_H=\"$(ARCH_H)\" KLIB_INTERFACE_INCPATH += $(AM_HOME)/am/include $(AM_HOME)/klib/include -KLIB_INTERFACE_CFLAGS += -KLIB_INTERFACE_LDFLAGS += -lklib-$(ARCH) +KLIB_INTERFACE_CFLAGS += -DARCH_H=\"$(ARCH_H)\" $(addprefix -I, $(KLIB_INTERFACE_INCPATH:%=$(INC_INSTALLDIR))) $(eval $(call ADD_LIBRARY,$(LIB_BUILDDIR)/libklib-$(ARCH).a,KLIB_)) @@ -110,18 +109,35 @@ LIBS := am klib libs: $(addsuffix -$(ARCH).a, $(addprefix $(LIB_BUILDDIR)/lib, $(ALL))) $(LIBS): %: $(addsuffix -$(ARCH).a, $(addprefix $(LIB_BUILDDIR)/lib, %)) -## 6. Install rules +### Rule (link): objects (`*.o`) and libraries (`*.a`) -> `IMAGE.elf`, the final ELF binary to be packed into image (ld) +$(IMAGE).elf: $(OBJS) $(LIBS) + @echo + LD "->" $(IMAGE_REL).elf + @$(LD) $(LDFLAGS) -o $(IMAGE).elf --start-group $(LINKAGE) --end-group + +## 6. Miscellaneous + +### Build order control +image: image-dep +archive: $(ARCHIVE) +image-dep: $(OBJS) $(LIBS) + @echo \# Creating image [$(ARCH)] +.PHONY: image image-dep archive run libs $(LIBS) install + +### Install rules + INTERFACE_INCPATH += $(sort $(KLIB_INTERFACE_INCPATH) $(AM_INTERFACE_INCPATH)) -# TODO: Use sort here will cause error on seperated flags, such as: -e _start -# but without sort, duplicated flags will not be removed. -INTERFACE_CFLAGS += $(addprefix -I, $(INTERFACE_INCPATH:%=$(INC_INSTALLDIR))) $(sort $(KLIB_INTERFACE_CFLAGS) $(AM_INTERFACE_CFLAGS)) -INTERFACE_LDFLAGS += -L$(LIB_INSTALLDIR) $(sort $(KLIB_INTERFACE_LDFLAGS) $(AM_INTERFACE_LDFLAGS)) +INTERFACE_CFLAGS += $(sort $(KLIB_INTERFACE_CFLAGS) $(AM_INTERFACE_CFLAGS)) +INTERFACE_LDFLAGS += $(sort $(KLIB_LDFLAGS) $(AM_LDFLAGS)) EXPORT_FLAGS_FILE := $(LIB_INSTALLDIR)/make/flags-$(ARCH).mk EXPORT_FLAGS_TEMPLATE := $(file < $(AM_HOME)/scripts/templates/flags.tmpl) HELPERS := $(wildcard find scripts/helpers/*.mk) EXPORT_HELPERS := $(HELPERS:scripts/helpers/%=$(LIB_INSTALLDIR)/make/%) +test: + @echo $(EXPORT_HELPERS) + @echo $(LIB_INSTALLDIR) + EXPORTS := $(EXPORT_FLAGS_FILE) $(EXPORT_HELPERS) $(EXPORT_HELPERS): $(LIB_INSTALLDIR)/make/%: scripts/helpers/% @@ -134,13 +150,6 @@ $(EXPORT_FLAGS_FILE): @echo + INSTALL $(patsubst $(INSTALLDIR)/%,%,$@) @install -Dm644 <(printf $(EXPORT_FLAGS_TEMPLATE)) $(EXPORT_FLAGS_FILE) -LDSCRIPTS := $(patsubst $(AM_HOME)/scripts/%, $(LIB_INSTALLDIR)/ldscripts/%, $(shell find $(AM_HOME)/scripts -name "*.ld")) - -$(LDSCRIPTS): $(LIB_INSTALLDIR)/ldscripts/%: $(AM_HOME)/scripts/% - @echo + INSTALL $(patsubst $(INSTALLDIR)/%,%,$@) - @mkdir -p $(LIB_INSTALLDIR)/ldscripts - @install -Dm644 $< $(dir $@) - install-libs: $(LIBS) @echo + INSTALL LIBS: $(LIBS) @install -dm755 $(LIB_INSTALLDIR) @@ -152,9 +161,7 @@ install-headers: $(HEADERS) # Headers needs to be reinstalled if they are change @install -dm755 $(INC_INSTALLDIR) @cp -r $(addsuffix /*, $(INTERFACE_INCPATH)) $(INC_INSTALLDIR) -install: $(EXPORTS) install-libs install-headers $(LDSCRIPTS) - -.PHONY: libs $(LIBS) install +install: $(EXPORTS) install-libs install-headers ### Clean a single project (remove `build/`) clean: diff --git a/am/src/platform/nemu/ioe/ioe.c b/am/src/platform/nemu/ioe/ioe.c index b0883a9..5970e20 100644 --- a/am/src/platform/nemu/ioe/ioe.c +++ b/am/src/platform/nemu/ioe/ioe.c @@ -59,4 +59,3 @@ bool ioe_init() { void ioe_read(int reg, void *buf) { ((handler_t)lut[reg])(buf); } void ioe_write(int reg, void *buf) { ((handler_t)lut[reg])(buf); } - diff --git a/scripts/helpers/rules.mk b/scripts/helpers/rules.mk index 6c37be6..7ce4255 100644 --- a/scripts/helpers/rules.mk +++ b/scripts/helpers/rules.mk @@ -56,7 +56,7 @@ $(eval $(call COMPILE_RULES,$(2))) $(1).elf: $$($(2)OBJS) @mkdir -p $$(dir $$@) @echo + LD "->" $$(patsubst $$(CURDIR)/%,%,$(1).elf) - @$$(LD) $$($(2)LDFLAGS) -o $$@ --start-group $$($(2)OBJS) --end-group + @$$(LD) $$($(2)_LDFLAGS) -o $$@ --start-group $$($(2)OBJS) --end-group $(1).bin: $(1).elf @echo + OBJCOPY "->" $$(patsubst $$(CURDIR)/%,%,$(1)) @$$(OBJCOPY) -S --set-section-flags .bss=alloc,contents -O binary $(1).elf $(1).bin diff --git a/scripts/isa/riscv.mk b/scripts/isa/riscv.mk index a8e7b17..89d3653 100644 --- a/scripts/isa/riscv.mk +++ b/scripts/isa/riscv.mk @@ -1,3 +1,4 @@ +CROSS_COMPILE := riscv64-linux-gnu- AM_CFLAGS += -static -fno-pic -march=rv64g -mcmodel=medany -mstrict-align AM_ASFLAGS += -static -fno-pic -march=rv32g_zicsr -mcmodel=medany -O0 AM_LDFLAGS += -melf64lriscv -O2 diff --git a/scripts/platform/nemu.mk b/scripts/platform/nemu.mk index 0e95484..5f4e578 100644 --- a/scripts/platform/nemu.mk +++ b/scripts/platform/nemu.mk @@ -7,17 +7,20 @@ AM_SRCS := am/src/platform/nemu/trm.c \ am/src/platform/nemu/ioe/disk.c \ am/src/platform/nemu/mpe.c -AM_PUBLIC_CFLAGS := -fdata-sections -ffunction-sections -AM_PUBLIC_LDFLAGS := --defsym=_pmem_start=0x80000000 --defsym=_entry_offset=0x0 \ - --gc-sections --entry=_start -AM_CFLAGS += $(AM_PUBLIC_CFLAGS) -DMAINARGS=\"$(mainargs)\" -AM_LDFLAGS += -T$(AM_HOME)/scripts/linker.ld $(AM_PUBLIC_LDFLAGS) -AM_INCPATH += $(AM_HOME)/am/src/platform/nemu/include +AM_CFLAGS += -fdata-sections -ffunction-sections +AM_LDFLAGS += -T $(AM_HOME)/scripts/linker.ld \ + --defsym=_pmem_start=0x80000000 --defsym=_entry_offset=0x0 +AM_LDFLAGS += --gc-sections -e _start -AM_INTERFACE_CFLAGS += $(AM_PUBLIC_CFLAGS) -AM_INTERFACE_LDFLAGS += -T$(LIB_INSTALLDIR)/ldscripts/linker.ld $(AM_PUBLIC_LDFLAGS) +AM_CFLAGS += -DMAINARGS=\"$(mainargs)\" +AM_INCPATH += $(AM_HOME)/am/src/platform/nemu/include .PHONY: $(AM_HOME)/am/src/platform/nemu/trm.c +image: $(IMAGE).elf + @$(OBJDUMP) -d $(IMAGE).elf > $(IMAGE).txt + @echo + OBJCOPY "->" $(IMAGE_REL).bin + @$(OBJCOPY) -S --set-section-flags .bss=alloc,contents -O binary $(IMAGE).elf $(IMAGE).bin + NEMUFLAGS += -b #-l $(shell dirname $(IMAGE).elf)/nemu-log.txt diff --git a/scripts/riscv32-nemu.mk b/scripts/riscv32-nemu.mk index bf3dc58..eb7c24f 100644 --- a/scripts/riscv32-nemu.mk +++ b/scripts/riscv32-nemu.mk @@ -1,7 +1,7 @@ include $(AM_HOME)/scripts/isa/riscv.mk include $(AM_HOME)/scripts/platform/nemu.mk -AM_CFLAGS += -DISA_H=\"riscv/riscv.h\" -march=rv32im_zicsr -mabi=ilp32 -AM_LDFLAGS += -melf32lriscv +AM_CFLAGS += -DISA_H=\"riscv/riscv.h\" -march=rv32im_zicsr -mabi=ilp32 # overwrite +AM_LDFLAGS += -melf32lriscv # overwrite AM_SRCS += am/src/riscv/nemu/start.S \ am/src/riscv/nemu/cte.c \