From 548905a86473101325540446f35ffda8acd0c3bb Mon Sep 17 00:00:00 2001 From: Nathan Lee Date: Fri, 25 Sep 2026 23:24:31 -0500 Subject: scaffold kernel from parts of wkern x86 --- website-kernel/Makefile | 73 ++++++++++++++++++++++++++++++ website-kernel/arch/kernel.c | 9 ++++ website-kernel/arch/linker.ld | 52 ++++++++++++++++++++++ website-kernel/arch/log.c | 100 ++++++++++++++++++++++++++++++++++++++++++ website-kernel/arch/start.S | 23 ++++++++++ website-kernel/include/int.h | 8 ++++ website-kernel/include/log.h | 11 +++++ 7 files changed, 276 insertions(+) create mode 100644 website-kernel/Makefile create mode 100644 website-kernel/arch/kernel.c create mode 100644 website-kernel/arch/linker.ld create mode 100644 website-kernel/arch/log.c create mode 100644 website-kernel/arch/start.S create mode 100644 website-kernel/include/int.h create mode 100644 website-kernel/include/log.h (limited to 'website-kernel') diff --git a/website-kernel/Makefile b/website-kernel/Makefile new file mode 100644 index 0000000..eb5a76e --- /dev/null +++ b/website-kernel/Makefile @@ -0,0 +1,73 @@ +CC = clang +LD = ld.lld +OBJCOPY = llvm-objcopy + +COMPILER = $(shell $(CC) --version | head -n 1) +LINKER = $(shell $(LD) --version | head -n 1) +ARCH_NAME = 32-bit RISC-V, IM_Zicsr ISA, little endian, unknown ELF, System V ABI + +CFLAGS = \ + --target=riscv32-unknown-elf \ + -march=rv32im_zicsr \ + -mabi=ilp32 \ + -ffreestanding \ + -fno-builtin \ + -nostdlib \ + -nostdinc \ + -nodefaultlibs \ + -DVERSION='"$(VERSION)"' \ + -DCOMPILER_NAME='"$(COMPILER)"' \ + -DLINKER_NAME='"$(LINKER)"' \ + -DARCH_NAME='"$(ARCH_NAME)"' \ + -static \ + -ffunction-sections -fdata-sections -fno-common \ + -Iinclude -O2 -g3 \ + -Wall -Wextra -Werror -Wundef + +LD_FLAGS = \ + -T $(LINKER_SCRIPT) -nostdlib -m elf32lriscv --gc-sections + +OBJCOPY_FLAGS = \ + -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 + +C_SRCS = $(shell find . -name '*.c') +S_SRCS = $(shell find . -name '*.S') +C_OBJECTS = $(C_SRCS:.c=.o) +S_OBJECTS = $(S_SRCS:.S=.o) +ALL_OBJECTS = $(C_OBJECTS) $(S_OBJECTS) +LINKER_SCRIPT = arch/linker.ld + +KERNEL_BINARY = Image.bin +KERNEL_ELF = arch/webos-kernel.elf + +$(V).SILENT: + +%.o: %.c + @echo " CC $<" + $(CC) $(CFLAGS) -c $< -o $@ +%.o: %.S + @echo " AS $<" + $(CC) $(CFLAGS) -c $< -o $@ +$(KERNEL_ELF): $(ALL_OBJECTS) $(LINKER_SCRIPT) + @echo " LD $@" + $(LD) $(LD_FLAGS) -o $@ $(ALL_OBJECTS) +$(KERNEL_BINARY): $(KERNEL_ELF) + @echo " OBJCOPY $@" + $(OBJCOPY) $(OBJCOPY_FLAGS) $(KERNEL_ELF) $(KERNEL_BIN) +clean: + @echo " CLEAN $(ALL_OBJECTS)" + $(RM) $(ALL_OBJECTS) + @echo " CLEAN $(KERNEL_ELF)" + $(RM) $(KERNEL_ELF) + @echo " CLEAN $(KERNEL_BINARY)" + $(RM) $(KERNEL_BINARY) + +.PHONY: all clean +all: $(KERNEL_BINARY) diff --git a/website-kernel/arch/kernel.c b/website-kernel/arch/kernel.c new file mode 100644 index 0000000..28c94d3 --- /dev/null +++ b/website-kernel/arch/kernel.c @@ -0,0 +1,9 @@ +#include +#include + +#define SERIAL_PORT 0x70000000 + +void kernel_main(size_t hart) { + (void)hart; + printk("wkern version %s (Compiler %s, Linker %s) on %s\n", VERSION, COMPILER_NAME, LINKER_NAME, ARCH_NAME); +} diff --git a/website-kernel/arch/linker.ld b/website-kernel/arch/linker.ld new file mode 100644 index 0000000..52a3a05 --- /dev/null +++ b/website-kernel/arch/linker.ld @@ -0,0 +1,52 @@ +OUTPUT_ARCH(riscv) +ENTRY(_start) + +MEMORY +{ + ROM (rx) : ORIGIN = 0x80000000, LENGTH = 1M + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 4M +} + +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 +} diff --git a/website-kernel/arch/log.c b/website-kernel/arch/log.c new file mode 100644 index 0000000..63e0615 --- /dev/null +++ b/website-kernel/arch/log.c @@ -0,0 +1,100 @@ +#include +void stub(char c) { + (void)c; + return; +} + +console_callback_t callback = stub; + +void put_char(char c) { + callback(c); +} + +void put_string(const char *s) { + while (*s) + put_char(*s++); +} + +void put_uint(unsigned int value, unsigned int radix) { + char tmp[16]; + const char digits[] = "0123456789abcdef"; + int i = 0; + + if (value == 0) { + put_char('0'); + return; + } + + while (value) { + tmp[i++] = digits[value % radix]; + value /= radix; + } + + while (i--) + put_char(tmp[i]); +} + +void put_int(int value) { + if (value < 0) { + put_char('-'); + put_uint((unsigned int)(-value), 10); + } else { + put_uint((unsigned int)value, 10); + } +} + +void vprintk(const char *fmt, __builtin_va_list args) { + while (*fmt) { + if (*fmt != '%') { + put_char(*fmt++); + continue; + } + + fmt++; + + switch (*fmt) { + case '%': + put_char('%'); + break; + + case 'c': + put_char((char)__builtin_va_arg(args, int)); + break; + + case 's': + put_string(__builtin_va_arg(args, const char *)); + break; + + case 'd': + case 'i': + put_int(__builtin_va_arg(args, int)); + break; + + case 'u': + put_uint(__builtin_va_arg(args, unsigned int), 10); + break; + + case 'x': + put_uint(__builtin_va_arg(args, unsigned int), 16); + break; + + default: + put_char('%'); + put_char(*fmt); + break; + } + + fmt++; + } +} + +void printk(const char *fmt, ...) { + __builtin_va_list args; + __builtin_va_start(args, fmt); + vprintk(fmt, args); + __builtin_va_end(args); +} + +void register_console_callback(console_callback_t cb) { + callback = cb; +} diff --git a/website-kernel/arch/start.S b/website-kernel/arch/start.S new file mode 100644 index 0000000..8248ab9 --- /dev/null +++ b/website-kernel/arch/start.S @@ -0,0 +1,23 @@ +.section .text._start +.global _start +.type _start, @function + +.extern user_regs + +_start: + csrw sstatus, zero + csrw sie, 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 + wfi + diff --git a/website-kernel/include/int.h b/website-kernel/include/int.h new file mode 100644 index 0000000..2a378e7 --- /dev/null +++ b/website-kernel/include/int.h @@ -0,0 +1,8 @@ +#pragma once +#define NULL (void*)0 + +typedef __UINTPTR_TYPE__ size_t; +typedef __UINT8_TYPE__ uint8_t; +typedef __UINT16_TYPE__ uint16_t; +typedef __UINT32_TYPE__ uint32_t; +typedef __UINT64_TYPE__ uint64_t; diff --git a/website-kernel/include/log.h b/website-kernel/include/log.h new file mode 100644 index 0000000..4312baf --- /dev/null +++ b/website-kernel/include/log.h @@ -0,0 +1,11 @@ +#pragma once + +#define RINGBUF_SIZE 64 * 1024 + +typedef void (*console_callback_t)(char); + +void vprintk(const char *message, __builtin_va_list args); +void printk(const char *message, ...); + +void register_console_callback(console_callback_t callback); + -- cgit v1.2.3