Initial Commit
This commit is contained in:
commit
7f943be8f0
7 changed files with 114 additions and 0 deletions
56
Makefile
Normal file
56
Makefile
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
# Toolchain
|
||||||
|
CC = riscv64-unknown-elf-gcc
|
||||||
|
LD = riscv64-unknown-elf-ld
|
||||||
|
|
||||||
|
# Directories
|
||||||
|
SRC_DIR = src
|
||||||
|
BUILD_DIR = build
|
||||||
|
OUTPUT_DIR = output
|
||||||
|
|
||||||
|
# Flags
|
||||||
|
# Added -O0 for easier debugging and -g for symbols
|
||||||
|
CFLAGS = -Wall -Wextra -ffreestanding -nostdlib -mcmodel=medany -Iinclude -O0 -g
|
||||||
|
LDFLAGS = -T linker.ld
|
||||||
|
|
||||||
|
# 1. Find sources
|
||||||
|
SRCS_C = $(shell find $(SRC_DIR) -name "*.c")
|
||||||
|
SRCS_S = $(shell find $(SRC_DIR) -name "*.S")
|
||||||
|
|
||||||
|
# 2. Object mapping
|
||||||
|
OBJS_C = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(SRCS_C))
|
||||||
|
OBJS_S = $(patsubst $(SRC_DIR)/%.S, $(BUILD_DIR)/%.o, $(SRCS_S))
|
||||||
|
# Put Assembly first to help the linker find _start
|
||||||
|
OBJS = $(OBJS_S) $(OBJS_C)
|
||||||
|
|
||||||
|
# 3. List of all required build subdirectories
|
||||||
|
OBJ_DIRS = $(sort $(dir $(OBJS)))
|
||||||
|
|
||||||
|
TARGET = $(OUTPUT_DIR)/kernel.elf
|
||||||
|
|
||||||
|
.PHONY: all clean run
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
# The final link step
|
||||||
|
# Added -Wl, to pass LDFLAGS to the actual linker
|
||||||
|
$(TARGET): $(OBJS) | $(OUTPUT_DIR)
|
||||||
|
$(CC) $(CFLAGS) -Wl,$(LDFLAGS) $(OBJS) -o $(TARGET)
|
||||||
|
|
||||||
|
# Rule for C files
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIRS)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Rule for Assembly files
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.S | $(OBJ_DIRS)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Create directories using order-only prerequisites (|)
|
||||||
|
$(OBJ_DIRS) $(OUTPUT_DIR):
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
run: all
|
||||||
|
clear
|
||||||
|
qemu-system-riscv64 -M virt -bios none -kernel $(TARGET) -nographic
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILD_DIR) $(OUTPUT_DIR)
|
||||||
BIN
build/boot/entry.o
Normal file
BIN
build/boot/entry.o
Normal file
Binary file not shown.
BIN
build/kernel/kernel.o
Normal file
BIN
build/kernel/kernel.o
Normal file
Binary file not shown.
33
linker.ld
Normal file
33
linker.ld
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000000;
|
||||||
|
|
||||||
|
.text : ALIGN(4K) {
|
||||||
|
/* This matches the .section .text.boot in your assembly */
|
||||||
|
*(.text.boot)
|
||||||
|
*(.text .text.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : ALIGN(4K) {
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : ALIGN(4K) {
|
||||||
|
*(.data .data.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss : ALIGN(4K) {
|
||||||
|
PROVIDE(_bss_start = .);
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
PROVIDE(_bss_end = .);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep the stack at the very end to prevent it from overwriting code if it overflows */
|
||||||
|
. = ALIGN(16);
|
||||||
|
PROVIDE(_stack_bottom = .);
|
||||||
|
. += 4096;
|
||||||
|
PROVIDE(stack_top = .);
|
||||||
|
}
|
||||||
BIN
output/kernel.elf
Executable file
BIN
output/kernel.elf
Executable file
Binary file not shown.
14
src/boot/entry.S
Normal file
14
src/boot/entry.S
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
.section .text
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
la sp, stack_top # Set up the stack pointer
|
||||||
|
call kmain # Jump to our C code
|
||||||
|
loop:
|
||||||
|
wfi # Wait for Interrupt (saves CPU)
|
||||||
|
j loop # Infinite loop if C returns
|
||||||
|
|
||||||
|
.section .bss
|
||||||
|
.align 16
|
||||||
|
stack_low:
|
||||||
|
.skip 4096 # 4KB of stack space
|
||||||
|
stack_top:
|
||||||
11
src/kernel/kernel.c
Normal file
11
src/kernel/kernel.c
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void kmain() {
|
||||||
|
char *uart = (char *)0x10000000;
|
||||||
|
char *msg = "Hello, OS World!\n";
|
||||||
|
|
||||||
|
for (int i = 0; msg[i] != '\0'; i++) {
|
||||||
|
*uart = msg[i]; // Write each character to the UART
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue