diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 84 | ||||
| -rw-r--r-- | linker.ld | 65 | ||||
| -rw-r--r-- | src/kernel.c | 20 | ||||
| -rw-r--r-- | src/start.S | 20 |
5 files changed, 190 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e2e7327 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/out diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..12aadf8 --- /dev/null +++ b/Makefile @@ -0,0 +1,84 @@ +CC = clang +LD = ld.lld +OBJCOPY = llvm-objcopy + +ARCH_FLAG = \ + --target=riscv32-unknown-elf \ + -march=rv32im \ + -mabi=ilp32 + +KERNEL_FLAG = \ + -ffreestanding \ + -fno-builtin \ + -fno-stack-protector \ + -fno-exceptions \ + -fno-rtti \ + -fno-unwind-tables \ + -fno-asynchronous-unwind-tables \ + -nostdlib \ + -nostdinc \ + -static \ + -nodefaultlibs + +SECTION_FLAG = \ + -ffunction-sections \ + -fdata-sections \ + -fno-common + +INCLUDE_FLAG = -Iinclude -Isrc +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)) + +LD_FLAG = -T linker.ld -fuse-ld=lld -Wl,-nostdlib -Wl,-melf32lriscv -Wl,--gc-sections -Wl,-Map=$(MAP_FILE) +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 \ + + +.PHONY: all clean +all: $(KERNEL_BIN) + +$(OBJ_DIR)/%.o: src/%.c | $(OBJ_DIR) + @echo " CC $<" + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)/%.o: src/%.S | $(OBJ_DIR) + @echo " AS $<" + $(CC) $(CFLAGS) -c $< -o $@ + +$(KERNEL_ELF): $(OBJS_PATH) linker.ld | $(BIN_DIR) + @echo " LD $@" + $(CC) $(CFLAGS) $(LD_FLAG) $(OBJS_PATH) -o $@ + +$(KERNEL_BIN): $(KERNEL_ELF) | $(BIN_DIR) + @echo " OBJCOPY $@" + $(OBJCOPY) $(OBJCOPY_FLAG) $(KERNEL_ELF) $(KERNEL_BIN) + +$(OBJ_DIR) $(BIN_DIR): + mkdir -p $@ + +clean: + rm -rf out + diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..4f86e10 --- /dev/null +++ b/linker.ld @@ -0,0 +1,65 @@ +OUTPUT_ARCH(riscv) +ENTRY(_start) + +MEMORY +{ + ROM (rx) : ORIGIN = 0x80000000, LENGTH = 1M + RAM (rwx) : ORIGIN = 0x80400000, LENGTH = 1M +} + +SECTIONS +{ + .text : { + KEEP(*(.text._start)) + KEEP(*(.text.start)) + *(.text) + *(.text.*) + } > ROM + + .rodata : { + *(.rodata) + *(.rodata.*) + } > ROM + + .init_array : { + __init_array_start = .; + KEEP(*(.init_array)) + KEEP(*(.init_array.*)) + __init_array_end = .; + } > ROM + + .data : { + __data_start = .; + *(.data) + *(.data.*) + __data_end = .; + } > RAM AT> ROM + __data_load = LOADADDR(.data); + + .bss : { + __bss_start = .; + *(.bss) + *(.bss.*) + *(COMMON) + __bss_end = .; + } > RAM + + .stack (NOLOAD) : { + . = ALIGN(16); + __stack_bottom = .; + . += 8K; + __stack_top = .; + } > RAM + + /DISCARD/ : { + *(.eh_frame) + *(.eh_frame.*) + *(.eh_frame_hdr) + *(.comment) + *(.note.*) + *(.debug_*) + *(.stab*) + *(.llvm_*) + *(.rela.*) + } +} diff --git a/src/kernel.c b/src/kernel.c new file mode 100644 index 0000000..753f4a5 --- /dev/null +++ b/src/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/src/start.S b/src/start.S new file mode 100644 index 0000000..118b1c1 --- /dev/null +++ b/src/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 . |
