summaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile121
1 files changed, 87 insertions, 34 deletions
diff --git a/Makefile b/Makefile
index 12aadf8..9465dd1 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,8 @@ ARCH_FLAG = \
-march=rv32im \
-mabi=ilp32
-KERNEL_FLAG = \
+
+COMMON_FLAGS = \
-ffreestanding \
-fno-builtin \
-fno-stack-protector \
@@ -17,68 +18,120 @@ KERNEL_FLAG = \
-fno-asynchronous-unwind-tables \
-nostdlib \
-nostdinc \
- -static \
- -nodefaultlibs
+ -nodefaultlibs \
+
+KERNEL_FLAG = $(COMMON_FLAGS) -static
+MODULE_FLAG = $(COMMON_FLAGS) -fPIC -fpie
SECTION_FLAG = \
-ffunction-sections \
-fdata-sections \
-fno-common
-INCLUDE_FLAG = -Iinclude -Isrc
+INCLUDE_FLAG = -Iinclude -Ikernel
OPT_FLAG = -O2 -g3
WARN_FLAG = -Wall -Wextra -Werror -Wundef
-CFLAGS = $(ARCH_FLAG) $(KERNEL_FLAG) $(SECTION_FLAG) $(INCLUDE_FLAG) $(OPT_FLAG) $(WARN_FLAG)
-
-C_SRCS = $(wildcard src/*.c)
-ASM_SRCS = $(wildcard src/*.S)
-
-C_OBJS = $(notdir $(C_SRCS:.c=.o))
-ASM_OBJS = $(notdir $(ASM_SRCS:.S=.o))
-OBJS = $(C_OBJS) $(ASM_OBJS)
-
-KERNEL_ELF = out/bin/wkern.elf
-KERNEL_BIN = out/bin/wkern.bin
-MAP_FILE = out/bin/kernel.map
-
-OBJ_DIR = out/objects
-BIN_DIR = out/bin
-OBJS_PATH = $(addprefix $(OBJ_DIR)/, $(OBJS))
+KERNEL_LD_FLAG = -T linker.ld -fuse-ld=lld -Wl,-nostdlib -Wl,-melf32lriscv -Wl,--gc-sections -Wl,-Map=$(MAP_FILE)
+MODULE_LD_FLAG = -fuse-ld=lld -Wl,-nostdlib -Wl,-shared -Wl,-melf32lriscv -Wl,--gc-sections
-LD_FLAG = -T linker.ld -fuse-ld=lld -Wl,-nostdlib -Wl,-melf32lriscv -Wl,--gc-sections -Wl,-Map=$(MAP_FILE)
-OBJCOPY_FLAG = -O binary \
+KERNEL_OBJCOPY_FLAG = -O binary \
--strip-all \
--remove-section=.comment \
--remove-section=.debug* \
--remove-section=.note* \
--remove-section=.eh_frame \
--remove-section=.eh_frame_ptr \
- --remove-section=.eh_frame_hdr \
+ --remove-section=.eh_frame_hdr
+MODULE_OBJCOPY_FLAG = \
+ --strip-debug \
+ --remove-section=.comment \
+ --remove-section=.note*
-.PHONY: all clean
-all: $(KERNEL_BIN)
+KERNEL_CFLAGS = $(ARCH_FLAG) $(KERNEL_FLAG) $(SECTION_FLAG) $(INCLUDE_FLAG) $(OPT_FLAG) $(WARN_FLAG)
+MODULE_CFLAGS = $(ARCH_FLAG) $(MODULE_FLAG) $(SECTION_FLAG) $(INCLUDE_FLAG) $(OPT_FLAG) $(WARN_FLAG) -D__KERNEL_MODULE__
-$(OBJ_DIR)/%.o: src/%.c | $(OBJ_DIR)
+INCLUDE_DIR = include
+KERNEL_DIR = kernel
+OBJ_DIR = out/objects
+BIN_DIR = out/bin
+MODULE_BIN_DIR = out/modules
+
+MODULES = $(filter-out kernel include out, $(shell find . -maxdepth 1 -type d -printf "%f\n" | grep -v "^\."))
+MODULE_OBJ_DIR = $(addprefix $(OBJ_DIR)/, $(MODULES))
+KERNEL_OBJ_DIR = $(OBJ_DIR)/kernel
+
+KERNEL_C_SRCS = $(wildcard kernel/*.c)
+KERNEL_ASM_SRCS = $(wildcard kernel/*.S)
+KERNEL_C_OBJS = $(addprefix $(OBJ_DIR)/kernel/, $(notdir $(KERNEL_C_SRCS:.c=.o)))
+KERNEL_ASM_OBJS = $(addprefix $(OBJ_DIR)/kernel/, $(notdir $(KERNEL_ASM_SRCS:.S=.o)))
+KERNEL_OBJS = $(KERNEL_C_OBJS) $(KERNEL_ASM_OBJS)
+
+define module_template
+MODULE_$(1)_C_SRCS = $$(wildcard $(1)/*.c)
+MODULE_$(1)_ASM_SRCS = $$(wildcard $(1)/*.S)
+MODULE_$(1)_C_OBJS = $$(addprefix $(OBJ_DIR)/$(1)/, $$(notdir $$(MODULE_$(1)_C_SRCS:.c=.o)))
+MODULE_$(1)_ASM_OBJS = $$(addprefix $(OBJ_DIR)/$(1)/, $$(notdir $$(MODULE_$(1)_ASM_SRCS:.S=.o)))
+MODULE_$(1)_OBJS = $$(MODULE_$(1)_C_OBJS) $$(MODULE_$(1)_ASM_OBJS)
+MODULE_$(1)_KO = $(MODULE_BIN_DIR)/$(1).ko
+endef
+
+$(foreach module,$(MODULES),$(eval $(call module_template,$(module))))
+
+ALL_MODULES = $(foreach module,$(MODULES),$(MODULE_BIN_DIR)/$(module).ko)
+
+KERNEL_ELF = $(BIN_DIR)/wkern.elf
+KERNEL_BIN = $(BIN_DIR)/wkern.bin
+MAP_FILE = $(BIN_DIR)/kernel.map
+ALL_MOODULES = $(foreach module,$(MODULES),$(MODULE_BIN_DIR)/$(module).ko)
+
+MODULE_OBJ_DIRS = $(addprefix $(OBJ_DIR)/, $(MODULES))
+ALL_DIRS = $(OBJ_DIR)/kernel $(MODULE_OBJ_DIRS) $(BIN_DIR) $(MODULE_BIN_DIR)
+
+.PHONY: all clean kernel modules $(MODULES)
+all: kernel modules
+kernel: $(KERNEL_BIN)
+modules: $(ALL_MODULES)
+$(MODULES): %: $(MODULE_BIN_DIR)/%.ko
+
+$(OBJ_DIR)/kernel/%.o: $(KERNEL_DIR)/%.c | $(OBJ_DIR)/kernel
@echo " CC $<"
- $(CC) $(CFLAGS) -c $< -o $@
+ $(CC) $(KERNEL_CFLAGS) -c $< -o $@
-$(OBJ_DIR)/%.o: src/%.S | $(OBJ_DIR)
+$(OBJ_DIR)/kernel/%.o: $(KERNEL_DIR)/%.S | $(OBJ_DIR)/kernel
@echo " AS $<"
- $(CC) $(CFLAGS) -c $< -o $@
+ $(CC) $(KERNEL_CFLAGS) -c $< -o $@
-$(KERNEL_ELF): $(OBJS_PATH) linker.ld | $(BIN_DIR)
+$(KERNEL_ELF): $(KERNEL_OBJS) linker.ld | $(BIN_DIR)
@echo " LD $@"
- $(CC) $(CFLAGS) $(LD_FLAG) $(OBJS_PATH) -o $@
+ $(CC) $(KERNEL_CFLAGS) $(KERNEL_LD_FLAG) $(KERNEL_OBJS) -o $@
$(KERNEL_BIN): $(KERNEL_ELF) | $(BIN_DIR)
@echo " OBJCOPY $@"
$(OBJCOPY) $(OBJCOPY_FLAG) $(KERNEL_ELF) $(KERNEL_BIN)
-$(OBJ_DIR) $(BIN_DIR):
+$(OBJ_DIR)/%.o: %.c# | $(OBJ_DIR)/%
+ @mkdir -p $(dir $@)
+ @echo " CC $@"
+ $(CC) $(MODULE_CFLAGS) -c $< -o $@
+
+$(OBJ_DIR)/%.o: %.S# | $(OBJ_DIR)/%
+ @mkdir -p $(dir $@)
+ @echo " AS $@"
+ $(CC) $(MODULE_CFLAGS) -c $< -o $@
+
+define module_link_rule
+$(MODULE_BIN_DIR)/$(1).ko: $$(MODULE_$(1)_OBJS) | $(MODULE_BIN_DIR)
+ @echo " LD $$@"
+ $$(CC) $$(MODULE_CFLAGS) $$(MODULE_LD_FLAG) $$^ -o $$@
+ $$(OBJCOPY) $$(MODULE_OBJCOPY_FLAG) $$@ $$@
+endef
+
+$(foreach module,$(MODULES),$(eval $(call module_link_rule,$(module))))
+
+$(ALL_DIRS):
mkdir -p $@
clean:
- rm -rf out
-
+ rm -rf out