From 2fb81f37d20fd442d1954a7356e3ab7f88314a9c Mon Sep 17 00:00:00 2001 From: Nathan Lee Date: Sat, 13 Jun 2026 21:24:33 -0500 Subject: create support for kernel modules (but don't implement them yet) --- Makefile | 121 ++++++++++++++++++++++++++++++++++++++++---------------- kernel/kernel.c | 20 ++++++++++ kernel/start.S | 20 ++++++++++ pci/pci_main.c | 10 +++++ src/kernel.c | 20 ---------- src/start.S | 20 ---------- 6 files changed, 137 insertions(+), 74 deletions(-) create mode 100644 kernel/kernel.c create mode 100644 kernel/start.S create mode 100644 pci/pci_main.c delete mode 100644 src/kernel.c delete mode 100644 src/start.S 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 diff --git a/kernel/kernel.c b/kernel/kernel.c new file mode 100644 index 0000000..753f4a5 --- /dev/null +++ b/kernel/kernel.c @@ -0,0 +1,20 @@ +#define UART_BASE 0x10000000 // Example UART address + +static inline void putchar(char c) { + volatile char *uart = (volatile char *)UART_BASE; + *uart = c; +} + +static void print_string(const char *str) { + while (*str) { + putchar(*str++); + } +} + +void kernel_main(void) { + print_string("Hello from RISC-V kernel!\n"); + + while (1) { + // Wait + } +} diff --git a/kernel/start.S b/kernel/start.S new file mode 100644 index 0000000..dce0faa --- /dev/null +++ b/kernel/start.S @@ -0,0 +1,20 @@ +.section .text._start +.global _start +.type _start, @function + +_start: + csrw mstatus, zero + csrw mie, zero + + la sp, __stack_top + + la t0, __bss_start + la t1, __bss_end + beq t0, t1, 2f +1: + sw zero, 0(t0) + addi t0, t0, 4 + bltu t0, t1, 1b +2: + call kernel_main + j . diff --git a/pci/pci_main.c b/pci/pci_main.c new file mode 100644 index 0000000..521aebc --- /dev/null +++ b/pci/pci_main.c @@ -0,0 +1,10 @@ +#ifndef __KERNEL_MODULE__ +#define __KERNEL_MODULE__ +#endif + +int test_module_init(void) { + return 0; +} + +void test_module_exit(void) { +} diff --git a/src/kernel.c b/src/kernel.c deleted file mode 100644 index 753f4a5..0000000 --- a/src/kernel.c +++ /dev/null @@ -1,20 +0,0 @@ -#define UART_BASE 0x10000000 // Example UART address - -static inline void putchar(char c) { - volatile char *uart = (volatile char *)UART_BASE; - *uart = c; -} - -static void print_string(const char *str) { - while (*str) { - putchar(*str++); - } -} - -void kernel_main(void) { - print_string("Hello from RISC-V kernel!\n"); - - while (1) { - // Wait - } -} diff --git a/src/start.S b/src/start.S deleted file mode 100644 index 118b1c1..0000000 --- a/src/start.S +++ /dev/null @@ -1,20 +0,0 @@ -.section .text._start -.global _start -.type _start, @function - -_start: - # csrw mstatus, zero - # csrw mie, zero - - la sp, __stack_top - - la t0, __bss_start - la t1, __bss_end - beq t0, t1, 2f -1: - sw zero, 0(t0) - addi t0, t0, 4 - bltu t0, t1, 1b -2: - call kernel_main - j . -- cgit v1.2.3