summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile84
-rw-r--r--linker.ld65
-rw-r--r--src/kernel.c20
-rw-r--r--src/start.S20
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 .