From d9663547a1f4337e1a31d727abe15a8aafa0c9c8 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 8 Feb 2025 14:03:10 -0800 Subject: Initial commit. --- .gitignore | 1 + Makefile | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ run.sh | 10 ++++++++++ src/boot.s | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/kernel.c | 4 ++++ src/link.ld | 20 ++++++++++++++++++++ 6 files changed, 132 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100755 run.sh create mode 100644 src/boot.s create mode 100644 src/kernel.c create mode 100644 src/link.ld diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7478d63 --- /dev/null +++ b/Makefile @@ -0,0 +1,53 @@ +SRC_DIR := src +BUILD_DIR := build +OBJ_DIR := $(BUILD_DIR) +BIN_DIR := $(BUILD_DIR)/bin + +IMG := $(BIN_DIR)/kernel8.img +ELF := $(BIN_DIR)/kernel8.elf + +SRC := $(wildcard $(SRC_DIR)/*.c) +OBJ := $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) +ASM_SRC := $(wildcard $(SRC_DIR)/*.s) +ASM_OBJ := $(ASM_SRC:$(SRC_DIR)/%.s=$(OBJ_DIR)/%.o) +LINK := $(SRC_DIR)/link.ld + +CPPFLAGS := -I$(SRC_DIR) -MMD -MP +CFLAGS := -Wall -Wextra -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles +LDFLAGS := -nostdlib + +TOOLCHAIN := $(HOME)/bin/arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-elf/bin +AS := $(TOOLCHAIN)/aarch64-none-elf-as +CC := $(TOOLCHAIN)/aarch64-none-elf-gcc +LD := $(TOOLCHAIN)/aarch64-none-elf-ld +OBJCOPY := $(TOOLCHAIN)/aarch64-none-elf-objcopy + +.PHONY: all clean + +all: $(IMG) + +$(IMG): $(ELF) | $(BIN_DIR) + @echo Building $@ + $(OBJCOPY) -O binary $(ELF) $@ + +$(ELF): $(OBJ) $(ASM_OBJ) | $(BIN_DIR) + @echo Building $@ + $(LD) $(LDFLAGS) $^ -T $(LINK) -o $@ + +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR) + @echo Building $< "->" $@ + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.s | $(BUILD_DIR) + @echo Building $< "->" $@ + $(AS) $< -o $@ + +clean: + rm -rf $(BUILD_DIR) + +$(BUILD_DIR): + mkdir -p $(BUILD_DIR) + +$(BIN_DIR): + mkdir -p $(BIN_DIR) + diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..3b2c6f2 --- /dev/null +++ b/run.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +make +qemu-system-aarch64 \ + -cpu cortex-a53 \ + -m 1024 \ + -M raspi3b \ + -serial stdio \ + -kernel build/bin/kernel8.elf + diff --git a/src/boot.s b/src/boot.s new file mode 100644 index 0000000..7baa463 --- /dev/null +++ b/src/boot.s @@ -0,0 +1,44 @@ +/* +References: + https://wiki.osdev.org/Raspberry_Pi_Bare_Bones + https://jsandler18.github.io/tutorial/boot.html + https://jsandler18.github.io/explanations/boot_S.html + https://www.rpi4os.com/part1-bootstrapping/ + https://developer.arm.com/documentation/102422/0100/Example-solutions/System-control-solution + https://developer.arm.com/documentation/102422/0100/GAS-syntax-reference?lang=en +*/ + +.section ".text.boot" + +.global _start + +_start: + // Let core 0.0.0.0 be the only one running for now. The other cores halt. + // Each core has a unique affinity number: .... + // On AArch64, Aff3 takes bits 39-32. The code below copies bits 39-32 over + // to 31-24 so that we get a 32-bit value .... + mrs x0, MPIDR_EL1 + ubfx x1, x0, #32, #8 // x1[0..7] = Aff3; x[8..63] = 0 + bfi w0, w1, #24, #8 // w0[31..24] = Aff3 + cbnz w0, halt // All cores except 0.0.0.0 halt. + +core0: + // Initialize the stack. The stack will grow below this boot code. + ldr x1, =_start + mov sp, x1 + + // Zero-initialize the BSS section. + ldr x1, =__bss_start // Start address of BSS section. + ldr x2, =__bss_size // Size of the BSS section. +bss_init_loop: + str xzr, [x1], #8 // Store 64-bit 0 to addr; increment addr by 8 bytes. + sub x2, x2, #8 // Decrement remaining size. + cbnz x2, bss_init_loop // Loop back if remaining size is non-zero (>0). + + // Jump to C main() + bl main + +halt: + wfi // Wait for interrupt. Core enters low-power state. + b halt // Loop back. + diff --git a/src/kernel.c b/src/kernel.c new file mode 100644 index 0000000..eb7d832 --- /dev/null +++ b/src/kernel.c @@ -0,0 +1,4 @@ +void main() { + while (1); +} + diff --git a/src/link.ld b/src/link.ld new file mode 100644 index 0000000..f1d1730 --- /dev/null +++ b/src/link.ld @@ -0,0 +1,20 @@ +SECTIONS +{ + . = 0x80000; /* Kernel load address for AArch64 */ + .text (READONLY) : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) } + .rodata (READONLY) : { *(.rodata .rodata.* .gnu.linkonce.r*) } + PROVIDE(_data = .); + .data : { *(.data .data.* .gnu.linkonce.d*) } + .bss (NOLOAD) : { + . = ALIGN(16); + __bss_start = .; + *(.bss .bss.*) + *(COMMON) + __bss_end = .; + } + _end = .; + + /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) } +} +__bss_size = (__bss_end - __bss_start); + -- cgit v1.2.3