summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-02-08 14:03:10 -0800
committer3gg <3gg@shellblade.net>2025-02-08 14:03:10 -0800
commitd9663547a1f4337e1a31d727abe15a8aafa0c9c8 (patch)
tree05795108e35cb8a9c5d05a19cd7a28487322ad6b
Initial commit.
-rw-r--r--.gitignore1
-rw-r--r--Makefile53
-rwxr-xr-xrun.sh10
-rw-r--r--src/boot.s44
-rw-r--r--src/kernel.c4
-rw-r--r--src/link.ld20
6 files changed, 132 insertions, 0 deletions
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 @@
1SRC_DIR := src
2BUILD_DIR := build
3OBJ_DIR := $(BUILD_DIR)
4BIN_DIR := $(BUILD_DIR)/bin
5
6IMG := $(BIN_DIR)/kernel8.img
7ELF := $(BIN_DIR)/kernel8.elf
8
9SRC := $(wildcard $(SRC_DIR)/*.c)
10OBJ := $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
11ASM_SRC := $(wildcard $(SRC_DIR)/*.s)
12ASM_OBJ := $(ASM_SRC:$(SRC_DIR)/%.s=$(OBJ_DIR)/%.o)
13LINK := $(SRC_DIR)/link.ld
14
15CPPFLAGS := -I$(SRC_DIR) -MMD -MP
16CFLAGS := -Wall -Wextra -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
17LDFLAGS := -nostdlib
18
19TOOLCHAIN := $(HOME)/bin/arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-elf/bin
20AS := $(TOOLCHAIN)/aarch64-none-elf-as
21CC := $(TOOLCHAIN)/aarch64-none-elf-gcc
22LD := $(TOOLCHAIN)/aarch64-none-elf-ld
23OBJCOPY := $(TOOLCHAIN)/aarch64-none-elf-objcopy
24
25.PHONY: all clean
26
27all: $(IMG)
28
29$(IMG): $(ELF) | $(BIN_DIR)
30 @echo Building $@
31 $(OBJCOPY) -O binary $(ELF) $@
32
33$(ELF): $(OBJ) $(ASM_OBJ) | $(BIN_DIR)
34 @echo Building $@
35 $(LD) $(LDFLAGS) $^ -T $(LINK) -o $@
36
37$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
38 @echo Building $< "->" $@
39 $(CC) $(CFLAGS) -c $< -o $@
40
41$(OBJ_DIR)/%.o: $(SRC_DIR)/%.s | $(BUILD_DIR)
42 @echo Building $< "->" $@
43 $(AS) $< -o $@
44
45clean:
46 rm -rf $(BUILD_DIR)
47
48$(BUILD_DIR):
49 mkdir -p $(BUILD_DIR)
50
51$(BIN_DIR):
52 mkdir -p $(BIN_DIR)
53
diff --git a/run.sh b/run.sh
new file mode 100755
index 0000000..3b2c6f2
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,10 @@
1#!/bin/sh
2
3make
4qemu-system-aarch64 \
5 -cpu cortex-a53 \
6 -m 1024 \
7 -M raspi3b \
8 -serial stdio \
9 -kernel build/bin/kernel8.elf
10
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 @@
1/*
2References:
3 https://wiki.osdev.org/Raspberry_Pi_Bare_Bones
4 https://jsandler18.github.io/tutorial/boot.html
5 https://jsandler18.github.io/explanations/boot_S.html
6 https://www.rpi4os.com/part1-bootstrapping/
7 https://developer.arm.com/documentation/102422/0100/Example-solutions/System-control-solution
8 https://developer.arm.com/documentation/102422/0100/GAS-syntax-reference?lang=en
9*/
10
11.section ".text.boot"
12
13.global _start
14
15_start:
16 // Let core 0.0.0.0 be the only one running for now. The other cores halt.
17 // Each core has a unique affinity number: <aff3>.<aff2>.<aff1>.<aff0>.
18 // On AArch64, Aff3 takes bits 39-32. The code below copies bits 39-32 over
19 // to 31-24 so that we get a 32-bit value <aff3>.<aff2>.<aff1>.<aff0>.
20 mrs x0, MPIDR_EL1
21 ubfx x1, x0, #32, #8 // x1[0..7] = Aff3; x[8..63] = 0
22 bfi w0, w1, #24, #8 // w0[31..24] = Aff3
23 cbnz w0, halt // All cores except 0.0.0.0 halt.
24
25core0:
26 // Initialize the stack. The stack will grow below this boot code.
27 ldr x1, =_start
28 mov sp, x1
29
30 // Zero-initialize the BSS section.
31 ldr x1, =__bss_start // Start address of BSS section.
32 ldr x2, =__bss_size // Size of the BSS section.
33bss_init_loop:
34 str xzr, [x1], #8 // Store 64-bit 0 to addr; increment addr by 8 bytes.
35 sub x2, x2, #8 // Decrement remaining size.
36 cbnz x2, bss_init_loop // Loop back if remaining size is non-zero (>0).
37
38 // Jump to C main()
39 bl main
40
41halt:
42 wfi // Wait for interrupt. Core enters low-power state.
43 b halt // Loop back.
44
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 @@
1void main() {
2 while (1);
3}
4
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 @@
1SECTIONS
2{
3 . = 0x80000; /* Kernel load address for AArch64 */
4 .text (READONLY) : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
5 .rodata (READONLY) : { *(.rodata .rodata.* .gnu.linkonce.r*) }
6 PROVIDE(_data = .);
7 .data : { *(.data .data.* .gnu.linkonce.d*) }
8 .bss (NOLOAD) : {
9 . = ALIGN(16);
10 __bss_start = .;
11 *(.bss .bss.*)
12 *(COMMON)
13 __bss_end = .;
14 }
15 _end = .;
16
17 /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
18}
19__bss_size = (__bss_end - __bss_start);
20