mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-26 09:02:46 +00:00
feat(arch): Add AArch64 / ARMv8i CPU support, cross-compilation & Linux Kconfig TUI
- Implement AArch64 HAL, vector table (16 aligned vectors), GICv2, Generic Timer, Stage-1 MMU (39-bit VA), PL011 UART - Build unified multi-architecture abstraction layer in include/arch/arch.h - Create interactive Linux-like Kconfig TUI menuconfig in scripts/kconfig/menuconfig.py - Support make menuconfig, defconfig, x86_64_defconfig, aarch64_defconfig - Update master Makefile for cross-compiling x86_64 (x86_64-elf-) and AArch64 (aarch64-linux-gnu-) - Dynamic architecture awareness across printk, uname, neofetch, and LazyBox
This commit is contained in:
1 parent
125a891621
commit
70d5925b16
41 files changed
+1926
-187
No files matched your search
@@ -8,3 +8,4 @@ build/
|
|||||||
*.tmp
|
*.tmp
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.system_generated/
|
.system_generated/
|
||||||
|
.config
|
||||||
@@ -1,43 +1,97 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
# SUB-OS Master Makefile - Modular Monolithic Linux-Like Kernel Build System
|
# SUB-OS Master Multi-Architecture Linux-Style Makefile
|
||||||
|
# Supports: x86_64, aarch64, armv8i
|
||||||
|
# Features: Linux Kconfig TUI (make menuconfig), multi-arch cross-compilation
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
# Cross Compiler & Toolchain Detection
|
-include .config
|
||||||
CROSS_COMPILE ?= x86_64-elf-
|
|
||||||
|
|
||||||
CC = $(CROSS_COMPILE)gcc
|
# Architecture Selection (Default: x86_64)
|
||||||
LD = $(CROSS_COMPILE)ld
|
ifdef CONFIG_ARCH
|
||||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
ARCH ?= $(CONFIG_ARCH)
|
||||||
ASM = nasm
|
else
|
||||||
|
ARCH ?= x86_64
|
||||||
|
endif
|
||||||
|
|
||||||
# Build Directories
|
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
BOOT_DIR = boot
|
BOOT_DIR = boot
|
||||||
|
|
||||||
# Target Architecture Flags
|
# -----------------------------------------------------------------------------
|
||||||
CFLAGS = -ffreestanding \
|
# Toolchain & Architecture Flags
|
||||||
-fno-pie \
|
# -----------------------------------------------------------------------------
|
||||||
-fno-pic \
|
ifeq ($(ARCH), x86_64)
|
||||||
-mno-red-zone \
|
CROSS_COMPILE ?= x86_64-elf-
|
||||||
-mno-mmx \
|
CC = $(CROSS_COMPILE)gcc
|
||||||
-mno-sse \
|
LD = $(CROSS_COMPILE)ld
|
||||||
-mno-sse2 \
|
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||||
-mcmodel=kernel \
|
ASM = nasm
|
||||||
-Wall \
|
|
||||||
-Wextra \
|
|
||||||
-Wno-unused-function \
|
|
||||||
-Wno-unused-parameter \
|
|
||||||
-O2 \
|
|
||||||
-Iinclude
|
|
||||||
|
|
||||||
ASMFLAGS_ELF = -f elf64
|
CFLAGS = -ffreestanding \
|
||||||
ASMFLAGS_BOOT = -f bin -I$(BOOT_DIR)/
|
-fno-pie \
|
||||||
|
-fno-pic \
|
||||||
|
-mno-red-zone \
|
||||||
|
-mno-mmx \
|
||||||
|
-mno-sse \
|
||||||
|
-mno-sse2 \
|
||||||
|
-mcmodel=kernel \
|
||||||
|
-Wall \
|
||||||
|
-Wextra \
|
||||||
|
-Wno-unused-function \
|
||||||
|
-Wno-unused-parameter \
|
||||||
|
-O2 \
|
||||||
|
-Iinclude \
|
||||||
|
-D__x86_64__
|
||||||
|
|
||||||
LDFLAGS = -nostdlib -no-pie -T linker.ld
|
ASMFLAGS_ELF = -f elf64
|
||||||
|
ASMFLAGS_BOOT = -f bin -I$(BOOT_DIR)/
|
||||||
|
LDFLAGS = -nostdlib -no-pie -T linker.ld
|
||||||
|
|
||||||
# Source Files Discovery
|
# Source files for x86_64
|
||||||
ARCH_C_SRCS = $(shell find arch -name '*.c' 2>/dev/null)
|
ARCH_C_SRCS = $(shell find arch/x86_64 -name '*.c' 2>/dev/null)
|
||||||
ARCH_ASM_SRCS = $(shell find arch -name '*.asm' 2>/dev/null)
|
ARCH_ASM_SRCS = $(shell find arch/x86_64 -name '*.asm' 2>/dev/null)
|
||||||
|
ENTRY_OBJ = $(BUILD_DIR)/arch/x86_64/boot/entry.o
|
||||||
|
IMAGE = SUB-OS.img
|
||||||
|
TARGET = $(IMAGE)
|
||||||
|
QEMU_CMD = qemu-system-x86_64 -drive format=raw,file=$(IMAGE) \
|
||||||
|
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80 \
|
||||||
|
-device e1000,netdev=net0 -serial stdio
|
||||||
|
|
||||||
|
else ifneq ($(filter $(ARCH), aarch64 armv8 armv8i),)
|
||||||
|
CROSS_COMPILE ?= aarch64-linux-gnu-
|
||||||
|
CC = $(CROSS_COMPILE)gcc
|
||||||
|
LD = $(CROSS_COMPILE)ld
|
||||||
|
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||||
|
AS = $(CROSS_COMPILE)as
|
||||||
|
|
||||||
|
CFLAGS = -ffreestanding \
|
||||||
|
-fno-pie \
|
||||||
|
-fno-pic \
|
||||||
|
-Wall \
|
||||||
|
-Wextra \
|
||||||
|
-Wno-unused-function \
|
||||||
|
-Wno-unused-parameter \
|
||||||
|
-mno-outline-atomics \
|
||||||
|
-O2 \
|
||||||
|
-Iinclude \
|
||||||
|
-D__aarch64__ \
|
||||||
|
-march=armv8-a
|
||||||
|
|
||||||
|
LDFLAGS = -nostdlib -no-pie -T arch/aarch64/linker.ld
|
||||||
|
|
||||||
|
# Source files for AArch64
|
||||||
|
ARCH_C_SRCS = $(shell find arch/aarch64 -name '*.c' 2>/dev/null)
|
||||||
|
ARCH_S_SRCS = $(shell find arch/aarch64 -name '*.S' 2>/dev/null)
|
||||||
|
ENTRY_OBJ = $(BUILD_DIR)/arch/aarch64/boot/entry.o
|
||||||
|
TARGET = $(BUILD_DIR)/kernel.elf
|
||||||
|
QEMU_CMD = qemu-system-aarch64 -M virt -cpu cortex-a57 -m 128M -nographic -kernel $(BUILD_DIR)/kernel.elf
|
||||||
|
|
||||||
|
else
|
||||||
|
$(error Unsupported Architecture '$(ARCH)'. Supported: x86_64, aarch64, armv8i)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Common Kernel Subsystems
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
KERNEL_C_SRCS = $(shell find kernel -name '*.c' 2>/dev/null)
|
KERNEL_C_SRCS = $(shell find kernel -name '*.c' 2>/dev/null)
|
||||||
MM_C_SRCS = $(shell find mm -name '*.c' 2>/dev/null)
|
MM_C_SRCS = $(shell find mm -name '*.c' 2>/dev/null)
|
||||||
DRIVERS_C_SRCS = $(shell find drivers -name '*.c' 2>/dev/null)
|
DRIVERS_C_SRCS = $(shell find drivers -name '*.c' 2>/dev/null)
|
||||||
@@ -52,7 +106,6 @@ IO_URING_C_SRCS = $(shell find io_uring -name '*.c' 2>/dev/null)
|
|||||||
SECURITY_C_SRCS = $(shell find security -name '*.c' 2>/dev/null)
|
SECURITY_C_SRCS = $(shell find security -name '*.c' 2>/dev/null)
|
||||||
USR_C_SRCS = $(shell find usr -name '*.c' 2>/dev/null)
|
USR_C_SRCS = $(shell find usr -name '*.c' 2>/dev/null)
|
||||||
VIRT_C_SRCS = $(shell find virt -name '*.c' 2>/dev/null)
|
VIRT_C_SRCS = $(shell find virt -name '*.c' 2>/dev/null)
|
||||||
|
|
||||||
BLOCK_C_SRCS = $(shell find block -name '*.c' 2>/dev/null)
|
BLOCK_C_SRCS = $(shell find block -name '*.c' 2>/dev/null)
|
||||||
IPC_C_SRCS = $(shell find ipc -name '*.c' 2>/dev/null)
|
IPC_C_SRCS = $(shell find ipc -name '*.c' 2>/dev/null)
|
||||||
SOUND_C_SRCS = $(shell find sound -name '*.c' 2>/dev/null)
|
SOUND_C_SRCS = $(shell find sound -name '*.c' 2>/dev/null)
|
||||||
@@ -63,81 +116,107 @@ ALL_C_SRCS = $(ARCH_C_SRCS) $(KERNEL_C_SRCS) $(MM_C_SRCS) $(DRIVERS_C_SRCS) \
|
|||||||
$(USR_C_SRCS) $(VIRT_C_SRCS) $(BLOCK_C_SRCS) $(IPC_C_SRCS) $(SOUND_C_SRCS)
|
$(USR_C_SRCS) $(VIRT_C_SRCS) $(BLOCK_C_SRCS) $(IPC_C_SRCS) $(SOUND_C_SRCS)
|
||||||
|
|
||||||
# Object Files Mapping
|
# Object Files Mapping
|
||||||
C_OBJS = $(patsubst %.c, $(BUILD_DIR)/%.o, $(ALL_C_SRCS))
|
C_OBJS = $(patsubst %.c, $(BUILD_DIR)/%.o, $(ALL_C_SRCS))
|
||||||
ASM_OBJS = $(patsubst %.asm, $(BUILD_DIR)/%.o, $(ARCH_ASM_SRCS))
|
|
||||||
|
|
||||||
# Put entry.o first in linker sequence
|
ifeq ($(ARCH), x86_64)
|
||||||
ENTRY_OBJ = $(BUILD_DIR)/arch/x86_64/boot/entry.o
|
ASM_OBJS = $(patsubst %.asm, $(BUILD_DIR)/%.o, $(ARCH_ASM_SRCS))
|
||||||
OTHER_OBJS = $(filter-out $(ENTRY_OBJ), $(ASM_OBJS) $(C_OBJS))
|
OTHER_OBJS = $(filter-out $(ENTRY_OBJ), $(ASM_OBJS) $(C_OBJS))
|
||||||
|
else
|
||||||
|
S_OBJS = $(patsubst %.S, $(BUILD_DIR)/%.o, $(ARCH_S_SRCS))
|
||||||
|
OTHER_OBJS = $(filter-out $(ENTRY_OBJ), $(S_OBJS) $(C_OBJS))
|
||||||
|
endif
|
||||||
|
|
||||||
IMAGE = SUB-OS.img
|
.PHONY: all clean run debug info menuconfig config defconfig x86_64_defconfig aarch64_defconfig armv8_defconfig armv8i_defconfig qemu
|
||||||
|
|
||||||
.PHONY: all clean run debug info
|
all: $(TARGET)
|
||||||
|
|
||||||
all: $(IMAGE)
|
# -----------------------------------------------------------------------------
|
||||||
|
# Configuration Targets (Linux Kconfig TUI)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
menuconfig config:
|
||||||
|
@python3 scripts/kconfig/menuconfig.py
|
||||||
|
|
||||||
# Assemble 16-bit Bootloader Stage 1
|
defconfig:
|
||||||
$(BUILD_DIR)/boot/boot.bin: $(BOOT_DIR)/boot.asm | $(BUILD_DIR)/boot
|
@python3 scripts/kconfig/menuconfig.py --defconfig $(ARCH)
|
||||||
$(ASM) $(ASMFLAGS_BOOT) $< -o $@
|
|
||||||
|
|
||||||
# Assemble 16/32/64-bit Bootloader Stage 2
|
x86_64_defconfig:
|
||||||
$(BUILD_DIR)/boot/stage2.bin: $(BOOT_DIR)/stage2.asm $(BOOT_DIR)/gdt.asm | $(BUILD_DIR)/boot
|
@python3 scripts/kconfig/menuconfig.py --x86_64
|
||||||
$(ASM) $(ASMFLAGS_BOOT) $< -o $@
|
|
||||||
|
|
||||||
# Compile 64-bit C source files
|
aarch64_defconfig:
|
||||||
|
@python3 scripts/kconfig/menuconfig.py --aarch64
|
||||||
|
|
||||||
|
armv8_defconfig armv8i_defconfig:
|
||||||
|
@python3 scripts/kconfig/menuconfig.py --armv8i
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Compilation Rules
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# C Source Files
|
||||||
$(BUILD_DIR)/%.o: %.c
|
$(BUILD_DIR)/%.o: %.c
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
# Assemble 64-bit ASM source files
|
# x86_64 NASM Assembly Files
|
||||||
$(BUILD_DIR)/%.o: %.asm
|
$(BUILD_DIR)/%.o: %.asm
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(ASM) $(ASMFLAGS_ELF) $< -o $@
|
$(ASM) $(ASMFLAGS_ELF) $< -o $@
|
||||||
|
|
||||||
# Link Kernel ELF
|
# AArch64 GNU Assembly Files (.S)
|
||||||
$(BUILD_DIR)/kernel.elf: $(ENTRY_OBJ) $(OTHER_OBJS) linker.ld
|
$(BUILD_DIR)/%.o: %.S
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# x86_64 Bootloader & Image Rules
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
$(BUILD_DIR)/boot/boot.bin: $(BOOT_DIR)/boot.asm | $(BUILD_DIR)/boot
|
||||||
|
$(ASM) $(ASMFLAGS_BOOT) $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/boot/stage2.bin: $(BOOT_DIR)/stage2.asm $(BOOT_DIR)/gdt.asm | $(BUILD_DIR)/boot
|
||||||
|
$(ASM) $(ASMFLAGS_BOOT) $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/boot:
|
||||||
|
mkdir -p $(BUILD_DIR)/boot
|
||||||
|
|
||||||
|
$(BUILD_DIR)/kernel.elf: $(ENTRY_OBJ) $(OTHER_OBJS)
|
||||||
$(LD) $(LDFLAGS) -o $@ $(ENTRY_OBJ) $(OTHER_OBJS)
|
$(LD) $(LDFLAGS) -o $@ $(ENTRY_OBJ) $(OTHER_OBJS)
|
||||||
|
@echo "=== [Kernel ELF Linked: $@ (Architecture: $(ARCH))] ==="
|
||||||
|
|
||||||
# Convert ELF to Flat Binary
|
|
||||||
$(BUILD_DIR)/kernel.bin: $(BUILD_DIR)/kernel.elf
|
$(BUILD_DIR)/kernel.bin: $(BUILD_DIR)/kernel.elf
|
||||||
$(OBJCOPY) -O binary $< $@
|
$(OBJCOPY) -O binary $< $@
|
||||||
|
|
||||||
# Create Bootable Floppy / HDD Raw Disk Image
|
|
||||||
$(IMAGE): $(BUILD_DIR)/boot/boot.bin $(BUILD_DIR)/boot/stage2.bin $(BUILD_DIR)/kernel.bin
|
$(IMAGE): $(BUILD_DIR)/boot/boot.bin $(BUILD_DIR)/boot/stage2.bin $(BUILD_DIR)/kernel.bin
|
||||||
dd if=/dev/zero of=$@ bs=512 count=2880 status=none
|
dd if=/dev/zero of=$@ bs=512 count=2880 status=none
|
||||||
dd if=$(BUILD_DIR)/boot/boot.bin of=$@ bs=512 conv=notrunc status=none
|
dd if=$(BUILD_DIR)/boot/boot.bin of=$@ bs=512 conv=notrunc status=none
|
||||||
dd if=$(BUILD_DIR)/boot/stage2.bin of=$@ bs=512 seek=1 conv=notrunc status=none
|
dd if=$(BUILD_DIR)/boot/stage2.bin of=$@ bs=512 seek=1 conv=notrunc status=none
|
||||||
dd if=$(BUILD_DIR)/kernel.bin of=$@ bs=512 seek=16 conv=notrunc status=none
|
dd if=$(BUILD_DIR)/kernel.bin of=$@ bs=512 seek=16 conv=notrunc status=none
|
||||||
@echo "=== [SUB-OS Disk Image Built Successfully: $@ (Size: $$(du -h $@ | cut -f1))] ==="
|
@echo "=== [SUB-OS x86_64 Disk Image Built: $@ (Size: $$(du -h $@ | cut -f1))] ==="
|
||||||
|
|
||||||
$(BUILD_DIR)/boot:
|
# -----------------------------------------------------------------------------
|
||||||
mkdir -p $(BUILD_DIR)/boot
|
# Execution & Emulation Targets
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
run: $(IMAGE)
|
run qemu: $(TARGET)
|
||||||
qemu-system-x86_64 -drive format=raw,file=$(IMAGE) \
|
$(QEMU_CMD)
|
||||||
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80 \
|
|
||||||
-device e1000,netdev=net0 -serial stdio
|
|
||||||
|
|
||||||
run-server: $(IMAGE)
|
run-server: $(IMAGE)
|
||||||
qemu-system-x86_64 -drive format=raw,file=$(IMAGE) \
|
qemu-system-x86_64 -drive format=raw,file=$(IMAGE) \
|
||||||
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80 \
|
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80 \
|
||||||
-device e1000,netdev=net0 -serial stdio -display none
|
-device e1000,netdev=net0 -serial stdio -display none
|
||||||
|
|
||||||
run-remote: $(IMAGE)
|
debug: $(TARGET)
|
||||||
qemu-system-x86_64 -drive format=raw,file=$(IMAGE) \
|
ifeq ($(ARCH), x86_64)
|
||||||
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80 \
|
|
||||||
-device e1000,netdev=net0 \
|
|
||||||
-serial telnet:0.0.0.0:2222,server,nowait -display none
|
|
||||||
|
|
||||||
debug: $(IMAGE)
|
|
||||||
qemu-system-x86_64 -drive format=raw,file=$(IMAGE) \
|
qemu-system-x86_64 -drive format=raw,file=$(IMAGE) \
|
||||||
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80 \
|
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80 \
|
||||||
-device e1000,netdev=net0 -serial stdio -s -S
|
-device e1000,netdev=net0 -serial stdio -s -S
|
||||||
|
else
|
||||||
|
qemu-system-aarch64 -M virt -cpu cortex-a57 -m 128M -nographic -kernel $(BUILD_DIR)/kernel.elf -s -S
|
||||||
|
endif
|
||||||
|
|
||||||
info:
|
info:
|
||||||
@echo "C Sources: $(words $(ALL_C_SRCS)) files"
|
@echo "Target Architecture: $(ARCH)"
|
||||||
@echo "ASM Sources: $(words $(ARCH_ASM_SRCS)) files"
|
@echo "Cross Compiler: $(CROSS_COMPILE)"
|
||||||
@echo "Target: $(IMAGE)"
|
@echo "C Sources: $(words $(ALL_C_SRCS)) files"
|
||||||
|
@echo "Target Binary: $(TARGET)"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD_DIR) $(IMAGE)
|
rm -rf $(BUILD_DIR) $(IMAGE)
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* SUB-OS AArch64 / ARMv8 Bootstrap Entry Point
|
||||||
|
* Handles EL2/EL3 -> EL1 drop, sets up stack, zeroes BSS, and jumps to kernel_main_aarch64
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section ".text.boot"
|
||||||
|
.global _start
|
||||||
|
.global aarch64_entry
|
||||||
|
|
||||||
|
_start:
|
||||||
|
aarch64_entry:
|
||||||
|
// Early UART debug ping
|
||||||
|
mov x0, #0x09000000
|
||||||
|
mov w1, #'['
|
||||||
|
str w1, [x0]
|
||||||
|
mov w1, #'S'
|
||||||
|
str w1, [x0]
|
||||||
|
mov w1, #'U'
|
||||||
|
str w1, [x0]
|
||||||
|
mov w1, #'B'
|
||||||
|
str w1, [x0]
|
||||||
|
mov w1, #'-'
|
||||||
|
str w1, [x0]
|
||||||
|
mov w1, #'O'
|
||||||
|
str w1, [x0]
|
||||||
|
mov w1, #'S'
|
||||||
|
str w1, [x0]
|
||||||
|
mov w1, #']'
|
||||||
|
str w1, [x0]
|
||||||
|
mov w1, #'\n'
|
||||||
|
str w1, [x0]
|
||||||
|
|
||||||
|
// 1. Primary Core Check (Core 0 proceeds, other cores halt)
|
||||||
|
mrs x0, mpidr_el1
|
||||||
|
and x0, x0, #0xFF
|
||||||
|
cbz x0, .primary_core
|
||||||
|
|
||||||
|
.secondary_halt:
|
||||||
|
wfe
|
||||||
|
b .secondary_halt
|
||||||
|
|
||||||
|
.primary_core:
|
||||||
|
// 2. Check current Exception Level (EL)
|
||||||
|
mrs x0, CurrentEL
|
||||||
|
lsr x0, x0, #2
|
||||||
|
cmp x0, #2
|
||||||
|
b.eq .from_el2
|
||||||
|
cmp x0, #3
|
||||||
|
b.eq .from_el3
|
||||||
|
b .in_el1
|
||||||
|
|
||||||
|
.from_el3:
|
||||||
|
// Setup Secure Configuration Register (SCR_EL3)
|
||||||
|
mov x0, #(1 << 10) // RW=1 (64-bit execution in EL2/EL1)
|
||||||
|
orr x0, x0, #(1 << 0) // NS=1 (Non-secure)
|
||||||
|
msr scr_el3, x0
|
||||||
|
mov x0, #0b01001 // EL2h mode with DAIF masked
|
||||||
|
msr spsr_el3, x0
|
||||||
|
adr x0, .from_el2
|
||||||
|
msr elr_el3, x0
|
||||||
|
eret
|
||||||
|
|
||||||
|
.from_el2:
|
||||||
|
// Setup Hypervisor Configuration Register (HCR_EL2)
|
||||||
|
mov x0, #(1 << 31) // RW=1 (64-bit execution in EL1)
|
||||||
|
msr hcr_el2, x0
|
||||||
|
|
||||||
|
// Setup SPSR_EL2 for drop to EL1h (EL1 with dedicated SP_EL1)
|
||||||
|
mov x0, #0b00101 // M[3:0] = 0101 (EL1h)
|
||||||
|
orr x0, x0, #(0xF << 6) // Mask DAIF
|
||||||
|
msr spsr_el2, x0
|
||||||
|
|
||||||
|
adr x0, .in_el1
|
||||||
|
msr elr_el2, x0
|
||||||
|
eret
|
||||||
|
|
||||||
|
.in_el1:
|
||||||
|
// Enable Floating-Point and Advanced SIMD (NEON) in EL1
|
||||||
|
mov x0, #(3 << 20)
|
||||||
|
msr cpacr_el1, x0
|
||||||
|
isb
|
||||||
|
|
||||||
|
// 3. Set up Kernel Stack (64 KB dedicated EL1 stack)
|
||||||
|
ldr x0, =stack_top
|
||||||
|
mov sp, x0
|
||||||
|
|
||||||
|
// 4. Enable Vector Table
|
||||||
|
ldr x0, =vectors
|
||||||
|
msr vbar_el1, x0
|
||||||
|
|
||||||
|
// 5. Zero out BSS
|
||||||
|
ldr x0, =__bss_start
|
||||||
|
ldr x1, =__bss_end
|
||||||
|
.bss_loop:
|
||||||
|
cmp x0, x1
|
||||||
|
b.ge .bss_done
|
||||||
|
str xzr, [x0], #8
|
||||||
|
b .bss_loop
|
||||||
|
.bss_done:
|
||||||
|
|
||||||
|
// 6. Jump to AArch64 C Entry
|
||||||
|
bl kernel_main_aarch64
|
||||||
|
|
||||||
|
.hang:
|
||||||
|
wfi
|
||||||
|
b .hang
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#
|
||||||
|
# Automatically generated by SUB-OS Kconfig for aarch64
|
||||||
|
#
|
||||||
|
CONFIG_ARCH=aarch64
|
||||||
|
CONFIG_ARCH_AARCH64=y
|
||||||
|
# CONFIG_ARCH_X86_64 is not set
|
||||||
|
CONFIG_BPF_VM=y
|
||||||
|
CONFIG_DRV_CANVAS_2D=y
|
||||||
|
CONFIG_DRV_PTY=y
|
||||||
|
CONFIG_DRV_RAMDISK=y
|
||||||
|
CONFIG_DRV_VIRTIO_BLK=y
|
||||||
|
CONFIG_DRV_VIRTIO_NET=y
|
||||||
|
CONFIG_DRV_VIRTIO_RNG=y
|
||||||
|
CONFIG_FS_DEVFS=y
|
||||||
|
CONFIG_FS_EXT2=y
|
||||||
|
CONFIG_FS_FAT32=y
|
||||||
|
CONFIG_FS_PROCFS=y
|
||||||
|
CONFIG_FS_RAMFS=y
|
||||||
|
CONFIG_FS_SYSFS=y
|
||||||
|
CONFIG_FS_VFS=y
|
||||||
|
CONFIG_IO_URING=y
|
||||||
|
CONFIG_MM_PMM=y
|
||||||
|
CONFIG_MM_SLAB=y
|
||||||
|
CONFIG_MM_VMA=y
|
||||||
|
CONFIG_NET_FILTER=y
|
||||||
|
CONFIG_NET_HTTPD=y
|
||||||
|
CONFIG_NET_SSHD=y
|
||||||
|
CONFIG_NET_STACK=y
|
||||||
|
CONFIG_OPTIMIZATION="-O2"
|
||||||
|
CONFIG_PREEMPT=y
|
||||||
|
CONFIG_SECURITY_KEYRING=y
|
||||||
|
CONFIG_SECURITY_LSM=y
|
||||||
|
CONFIG_SMP=y
|
||||||
|
CONFIG_SUBOS_HOSTNAME="sub-os"
|
||||||
|
CONFIG_SUBOS_VERSION="0.2.0-lts"
|
||||||
|
CONFIG_USERLAND_LAZYBOX=y
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
#include <arch/arch.h>
|
||||||
|
#include <arch/aarch64/cpu.h>
|
||||||
|
#include <arch/aarch64/gic.h>
|
||||||
|
#include <arch/aarch64/timer.h>
|
||||||
|
#include <arch/aarch64/uart.h>
|
||||||
|
#include <arch/aarch64/mmu.h>
|
||||||
|
#include <arch/x86_64/cpuid.h>
|
||||||
|
#include <kernel/printk.h>
|
||||||
|
#include <lib/string.h>
|
||||||
|
|
||||||
|
static cpu_info_t aarch64_compat_cpu;
|
||||||
|
|
||||||
|
void arch_early_init(void) {
|
||||||
|
uart_pl011_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_init(void) {
|
||||||
|
aarch64_cpu_init();
|
||||||
|
gic_init();
|
||||||
|
aarch64_timer_init(100);
|
||||||
|
aarch64_mmu_init();
|
||||||
|
|
||||||
|
// Populate compatibility CPU info structure for procfs
|
||||||
|
memset(&aarch64_compat_cpu, 0, sizeof(aarch64_compat_cpu));
|
||||||
|
const aarch64_cpu_info_t* info = aarch64_get_cpu_info();
|
||||||
|
strncpy(aarch64_compat_cpu.vendor, "ARM Ltd", sizeof(aarch64_compat_cpu.vendor) - 1);
|
||||||
|
strncpy(aarch64_compat_cpu.model, info->model_name, sizeof(aarch64_compat_cpu.model) - 1);
|
||||||
|
aarch64_compat_cpu.has_fpu = true;
|
||||||
|
|
||||||
|
arch_enable_interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* arch_get_name(void) {
|
||||||
|
return "aarch64 (ARMv8-A)";
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t arch_get_cpu_id(void) {
|
||||||
|
return (uint32_t)(aarch64_get_mpidr() & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer Compatibility Layer for Portable Drivers
|
||||||
|
uint64_t pit_get_ticks(void) {
|
||||||
|
return aarch64_timer_get_ticks();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pit_sleep(uint32_t ms) {
|
||||||
|
uint64_t count = (ms > 10) ? (ms / 10) : 1;
|
||||||
|
uint64_t target = aarch64_timer_get_ticks() + count;
|
||||||
|
while (aarch64_timer_get_ticks() < target) {
|
||||||
|
__asm__ volatile("wfi");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interrupt & CPUID Compatibility Stubs
|
||||||
|
void isr_register_handler(uint8_t isr, void* handler) {
|
||||||
|
(void)isr; (void)handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pic_clear_mask(uint8_t irq) {
|
||||||
|
(void)irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cpu_info_t* cpuid_get_info(void) {
|
||||||
|
return &aarch64_compat_cpu;
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#include <arch/aarch64/cpu.h>
|
||||||
|
#include <lib/string.h>
|
||||||
|
#include <kernel/printk.h>
|
||||||
|
|
||||||
|
static aarch64_cpu_info_t cpu_info;
|
||||||
|
|
||||||
|
uint64_t aarch64_get_midr(void) {
|
||||||
|
uint64_t midr;
|
||||||
|
__asm__ volatile("mrs %0, midr_el1" : "=r"(midr));
|
||||||
|
return midr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t aarch64_get_mpidr(void) {
|
||||||
|
uint64_t mpidr;
|
||||||
|
__asm__ volatile("mrs %0, mpidr_el1" : "=r"(mpidr));
|
||||||
|
return mpidr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t aarch64_get_current_el(void) {
|
||||||
|
uint64_t cur_el;
|
||||||
|
__asm__ volatile("mrs %0, CurrentEL" : "=r"(cur_el));
|
||||||
|
return (uint32_t)(cur_el >> 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void aarch64_cpu_init(void) {
|
||||||
|
memset(&cpu_info, 0, sizeof(cpu_info));
|
||||||
|
|
||||||
|
uint64_t midr = aarch64_get_midr();
|
||||||
|
cpu_info.implementer = (uint32_t)((midr >> 24) & 0xFF);
|
||||||
|
cpu_info.variant = (uint32_t)((midr >> 20) & 0x0F);
|
||||||
|
cpu_info.architecture = (uint32_t)((midr >> 16) & 0x0F);
|
||||||
|
cpu_info.part_num = (uint32_t)((midr >> 4) & 0xFFF);
|
||||||
|
cpu_info.revision = (uint32_t)(midr & 0x0F);
|
||||||
|
cpu_info.current_el = aarch64_get_current_el();
|
||||||
|
|
||||||
|
if (cpu_info.implementer == 0x41) { // ARM Limited
|
||||||
|
switch (cpu_info.part_num) {
|
||||||
|
case 0xD03: strcpy(cpu_info.model_name, "ARM Cortex-A53 (ARMv8.0-A)"); break;
|
||||||
|
case 0xD07: strcpy(cpu_info.model_name, "ARM Cortex-A57 (ARMv8.0-A)"); break;
|
||||||
|
case 0xD08: strcpy(cpu_info.model_name, "ARM Cortex-A72 (ARMv8.0-A)"); break;
|
||||||
|
case 0xD09: strcpy(cpu_info.model_name, "ARM Cortex-A73 (ARMv8.0-A)"); break;
|
||||||
|
case 0xD0B: strcpy(cpu_info.model_name, "ARM Cortex-A76 (ARMv8.2-A)"); break;
|
||||||
|
case 0xD40: strcpy(cpu_info.model_name, "ARM Neoverse-V1 (ARMv8.4-A)"); break;
|
||||||
|
default: strcpy(cpu_info.model_name, "ARMv8-A Compatible 64-Bit Processor"); break;
|
||||||
|
}
|
||||||
|
} else if (cpu_info.implementer == 0x61) { // Apple Silicon
|
||||||
|
strcpy(cpu_info.model_name, "Apple Silicon M-Series (ARMv8-A)");
|
||||||
|
} else {
|
||||||
|
strcpy(cpu_info.model_name, "Generic AArch64 / ARMv8 64-Bit Core");
|
||||||
|
}
|
||||||
|
|
||||||
|
printk(KERN_INFO "CPU: %s (Implementer: 0x%02x, Part: 0x%03x, EL%u)\n",
|
||||||
|
cpu_info.model_name, cpu_info.implementer, cpu_info.part_num, cpu_info.current_el);
|
||||||
|
}
|
||||||
|
|
||||||
|
const aarch64_cpu_info_t* aarch64_get_cpu_info(void) {
|
||||||
|
return &cpu_info;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#include <arch/aarch64/arch.h>
|
||||||
|
#include <arch/aarch64/gic.h>
|
||||||
|
#include <kernel/printk.h>
|
||||||
|
|
||||||
|
void aarch64_sync_handler(aarch64_context_t* ctx) {
|
||||||
|
uint64_t esr, elr, far;
|
||||||
|
__asm__ volatile("mrs %0, esr_el1" : "=r"(esr));
|
||||||
|
__asm__ volatile("mrs %0, elr_el1" : "=r"(elr));
|
||||||
|
__asm__ volatile("mrs %0, far_el1" : "=r"(far));
|
||||||
|
|
||||||
|
uint32_t ec = (esr >> 26) & 0x3F;
|
||||||
|
printk(ANSI_BRIGHT_RED "\n[KERNEL PANIC] AArch64 Synchronous Exception!\n" ANSI_RESET);
|
||||||
|
printk("ESR_EL1: 0x%016llx (EC: 0x%02x, ISS: 0x%08x)\n", esr, ec, (uint32_t)(esr & 0x01FFFFFF));
|
||||||
|
printk("ELR_EL1 (PC): 0x%016llx FAR_EL1: 0x%016llx\n", elr, far);
|
||||||
|
printk("Registers:\n");
|
||||||
|
for (int i = 0; i < 30; i += 2) {
|
||||||
|
printk(" X%02d: 0x%016llx X%02d: 0x%016llx\n", i, ctx->r[i], i + 1, ctx->r[i + 1]);
|
||||||
|
}
|
||||||
|
printk(" X30 (LR): 0x%016llx SP: 0x%016llx\n", ctx->r[30], ctx->sp);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
__asm__ volatile("wfe");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void aarch64_irq_handler(aarch64_context_t* ctx) {
|
||||||
|
(void)ctx;
|
||||||
|
gic_handle_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
void aarch64_fiq_handler(aarch64_context_t* ctx) {
|
||||||
|
(void)ctx;
|
||||||
|
printk(KERN_WARNING "AArch64: Unexpected FIQ caught\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void aarch64_serror_handler(aarch64_context_t* ctx) {
|
||||||
|
(void)ctx;
|
||||||
|
printk(ANSI_BRIGHT_RED "[KERNEL PANIC] AArch64 SError Interrupt caught!\n" ANSI_RESET);
|
||||||
|
while (1) {
|
||||||
|
__asm__ volatile("wfe");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
#include <arch/aarch64/gic.h>
|
||||||
|
#include <arch/aarch64/io.h>
|
||||||
|
#include <lib/string.h>
|
||||||
|
#include <kernel/printk.h>
|
||||||
|
|
||||||
|
#define MAX_GIC_IRQS 256
|
||||||
|
|
||||||
|
static gic_irq_handler_t irq_handlers[MAX_GIC_IRQS];
|
||||||
|
|
||||||
|
void gic_init(void) {
|
||||||
|
memset(irq_handlers, 0, sizeof(irq_handlers));
|
||||||
|
|
||||||
|
// 1. Disable Distributor
|
||||||
|
mmio_write32(GIC_DIST_BASE + GICD_CTLR, 0);
|
||||||
|
|
||||||
|
// 2. Clear pending and enable default priorities
|
||||||
|
uint32_t typer = mmio_read32(GIC_DIST_BASE + GICD_TYPER);
|
||||||
|
uint32_t num_irqs = 32 * ((typer & 0x1F) + 1);
|
||||||
|
if (num_irqs > MAX_GIC_IRQS) num_irqs = MAX_GIC_IRQS;
|
||||||
|
|
||||||
|
for (uint32_t i = 32; i < num_irqs; i += 32) {
|
||||||
|
mmio_write32(GIC_DIST_BASE + GICD_ICENABLER(i / 32), 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < num_irqs; i += 4) {
|
||||||
|
mmio_write32(GIC_DIST_BASE + GICD_IPRIORITYR(i / 4), 0xA0A0A0A0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 32; i < num_irqs; i += 4) {
|
||||||
|
mmio_write32(GIC_DIST_BASE + GICD_ITARGETSR(i / 4), 0x01010101); // Target Core 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Enable Distributor
|
||||||
|
mmio_write32(GIC_DIST_BASE + GICD_CTLR, 1);
|
||||||
|
|
||||||
|
// 4. Enable CPU Interface
|
||||||
|
mmio_write32(GIC_CPU_BASE + GICC_PMR, 0xF0); // Priority mask
|
||||||
|
mmio_write32(GIC_CPU_BASE + GICC_CTLR, 1); // Enable signaling
|
||||||
|
|
||||||
|
printk(KERN_INFO "GIC: ARM Generic Interrupt Controller v2 initialized (%u IRQ lines)\n", num_irqs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_enable_irq(uint32_t irq) {
|
||||||
|
if (irq >= MAX_GIC_IRQS) return;
|
||||||
|
mmio_write32(GIC_DIST_BASE + GICD_ISENABLER(irq / 32), (1U << (irq % 32)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_disable_irq(uint32_t irq) {
|
||||||
|
if (irq >= MAX_GIC_IRQS) return;
|
||||||
|
mmio_write32(GIC_DIST_BASE + GICD_ICENABLER(irq / 32), (1U << (irq % 32)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_register_handler(uint32_t irq, gic_irq_handler_t handler) {
|
||||||
|
if (irq < MAX_GIC_IRQS) {
|
||||||
|
irq_handlers[irq] = handler;
|
||||||
|
gic_enable_irq(irq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_handle_irq(void) {
|
||||||
|
uint32_t iar = mmio_read32(GIC_CPU_BASE + GICC_IAR);
|
||||||
|
uint32_t irq = iar & 0x3FF;
|
||||||
|
|
||||||
|
if (irq < 1020) {
|
||||||
|
if (irq_handlers[irq]) {
|
||||||
|
irq_handlers[irq](irq);
|
||||||
|
}
|
||||||
|
// End of Interrupt (EOIR)
|
||||||
|
mmio_write32(GIC_CPU_BASE + GICC_EOIR, iar);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#include <arch/aarch64/timer.h>
|
||||||
|
#include <arch/aarch64/gic.h>
|
||||||
|
#include <kernel/timer.h>
|
||||||
|
#include <kernel/printk.h>
|
||||||
|
|
||||||
|
static uint64_t timer_ticks = 0;
|
||||||
|
static uint64_t timer_freq = 62500000; // Standard 62.5MHz QEMU virt frequency
|
||||||
|
static uint32_t tick_interval = 0;
|
||||||
|
|
||||||
|
void aarch64_timer_handle_irq(void) {
|
||||||
|
timer_ticks++;
|
||||||
|
|
||||||
|
// Reset next comparator interval
|
||||||
|
__asm__ volatile("msr cntv_tval_el0, %0" :: "r"((uint64_t)tick_interval));
|
||||||
|
|
||||||
|
// Call generic kernel timer tick
|
||||||
|
timer_tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gic_timer_wrapper(uint32_t irq) {
|
||||||
|
(void)irq;
|
||||||
|
aarch64_timer_handle_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
void aarch64_timer_init(uint32_t freq_hz) {
|
||||||
|
if (freq_hz == 0) freq_hz = 100;
|
||||||
|
|
||||||
|
__asm__ volatile("mrs %0, cntfrq_el0" : "=r"(timer_freq));
|
||||||
|
tick_interval = (uint32_t)(timer_freq / freq_hz);
|
||||||
|
|
||||||
|
// Register with GIC (PPI 27 = Virtual Timer IRQ)
|
||||||
|
gic_register_handler(ARCH_TIMER_VIRT_IRQ, gic_timer_wrapper);
|
||||||
|
|
||||||
|
// Set countdown and enable virtual timer
|
||||||
|
__asm__ volatile("msr cntv_tval_el0, %0" :: "r"((uint64_t)tick_interval));
|
||||||
|
uint64_t ctl = 1; // Enable=1, IMASK=0
|
||||||
|
__asm__ volatile("msr cntv_ctl_el0, %0" :: "r"(ctl));
|
||||||
|
|
||||||
|
printk(KERN_INFO "Timer: ARM Generic Arch Timer active (%u Hz, Base Clock: %llu MHz)\n",
|
||||||
|
freq_hz, timer_freq / 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t aarch64_timer_get_ticks(void) {
|
||||||
|
return timer_ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t aarch64_timer_get_freq(void) {
|
||||||
|
return timer_freq;
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* SUB-OS AArch64 Exception Vector Table
|
||||||
|
* 16 vectors aligned on 128-byte (0x80) boundaries
|
||||||
|
*/
|
||||||
|
|
||||||
|
.macro SAVE_ALL
|
||||||
|
sub sp, sp, #272
|
||||||
|
stp x0, x1, [sp, #0]
|
||||||
|
stp x2, x3, [sp, #16]
|
||||||
|
stp x4, x5, [sp, #32]
|
||||||
|
stp x6, x7, [sp, #48]
|
||||||
|
stp x8, x9, [sp, #64]
|
||||||
|
stp x10, x11, [sp, #80]
|
||||||
|
stp x12, x13, [sp, #96]
|
||||||
|
stp x14, x15, [sp, #112]
|
||||||
|
stp x16, x17, [sp, #128]
|
||||||
|
stp x18, x19, [sp, #144]
|
||||||
|
stp x20, x21, [sp, #160]
|
||||||
|
stp x22, x23, [sp, #176]
|
||||||
|
stp x24, x25, [sp, #192]
|
||||||
|
stp x26, x27, [sp, #208]
|
||||||
|
stp x28, x29, [sp, #224]
|
||||||
|
mrs x0, elr_el1
|
||||||
|
mrs x1, spsr_el1
|
||||||
|
stp x30, x0, [sp, #240]
|
||||||
|
str x1, [sp, #256]
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro RESTORE_ALL
|
||||||
|
ldr x1, [sp, #256]
|
||||||
|
msr spsr_el1, x1
|
||||||
|
ldp x30, x0, [sp, #240]
|
||||||
|
msr elr_el1, x0
|
||||||
|
ldp x28, x29, [sp, #224]
|
||||||
|
ldp x26, x27, [sp, #208]
|
||||||
|
ldp x24, x25, [sp, #192]
|
||||||
|
ldp x22, x23, [sp, #176]
|
||||||
|
ldp x20, x21, [sp, #160]
|
||||||
|
ldp x18, x19, [sp, #144]
|
||||||
|
ldp x16, x17, [sp, #128]
|
||||||
|
ldp x14, x15, [sp, #112]
|
||||||
|
ldp x12, x13, [sp, #96]
|
||||||
|
ldp x10, x11, [sp, #80]
|
||||||
|
ldp x8, x9, [sp, #64]
|
||||||
|
ldp x6, x7, [sp, #48]
|
||||||
|
ldp x4, x5, [sp, #32]
|
||||||
|
ldp x2, x3, [sp, #16]
|
||||||
|
ldp x0, x1, [sp, #0]
|
||||||
|
add sp, sp, #272
|
||||||
|
eret
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.section ".vectors", "ax"
|
||||||
|
.align 11
|
||||||
|
.global vectors
|
||||||
|
|
||||||
|
vectors:
|
||||||
|
// 1. Current EL with SP0
|
||||||
|
.align 7; b handle_sync_curr_sp0
|
||||||
|
.align 7; b handle_irq_curr_sp0
|
||||||
|
.align 7; b handle_fiq_curr_sp0
|
||||||
|
.align 7; b handle_serror_curr_sp0
|
||||||
|
|
||||||
|
// 2. Current EL with SPx
|
||||||
|
.align 7; b handle_sync_curr_spx
|
||||||
|
.align 7; b handle_irq_curr_spx
|
||||||
|
.align 7; b handle_fiq_curr_spx
|
||||||
|
.align 7; b handle_serror_curr_spx
|
||||||
|
|
||||||
|
// 3. Lower EL using AArch64
|
||||||
|
.align 7; b handle_sync_lower_aarch64
|
||||||
|
.align 7; b handle_irq_lower_aarch64
|
||||||
|
.align 7; b handle_fiq_lower_aarch64
|
||||||
|
.align 7; b handle_serror_lower_aarch64
|
||||||
|
|
||||||
|
// 4. Lower EL using AArch32
|
||||||
|
.align 7; b handle_sync_lower_aarch32
|
||||||
|
.align 7; b handle_irq_lower_aarch32
|
||||||
|
.align 7; b handle_fiq_lower_aarch32
|
||||||
|
.align 7; b handle_serror_lower_aarch32
|
||||||
|
|
||||||
|
// Common Vector Handlers
|
||||||
|
handle_sync_curr_sp0:
|
||||||
|
handle_sync_curr_spx:
|
||||||
|
handle_sync_lower_aarch64:
|
||||||
|
handle_sync_lower_aarch32:
|
||||||
|
SAVE_ALL
|
||||||
|
mov x0, sp
|
||||||
|
bl aarch64_sync_handler
|
||||||
|
RESTORE_ALL
|
||||||
|
|
||||||
|
handle_irq_curr_sp0:
|
||||||
|
handle_irq_curr_spx:
|
||||||
|
handle_irq_lower_aarch64:
|
||||||
|
handle_irq_lower_aarch32:
|
||||||
|
SAVE_ALL
|
||||||
|
mov x0, sp
|
||||||
|
bl aarch64_irq_handler
|
||||||
|
RESTORE_ALL
|
||||||
|
|
||||||
|
handle_fiq_curr_sp0:
|
||||||
|
handle_fiq_curr_spx:
|
||||||
|
handle_fiq_lower_aarch64:
|
||||||
|
handle_fiq_lower_aarch32:
|
||||||
|
SAVE_ALL
|
||||||
|
mov x0, sp
|
||||||
|
bl aarch64_fiq_handler
|
||||||
|
RESTORE_ALL
|
||||||
|
|
||||||
|
handle_serror_curr_sp0:
|
||||||
|
handle_serror_curr_spx:
|
||||||
|
handle_serror_lower_aarch64:
|
||||||
|
handle_serror_lower_aarch32:
|
||||||
|
SAVE_ALL
|
||||||
|
mov x0, sp
|
||||||
|
bl aarch64_serror_handler
|
||||||
|
RESTORE_ALL
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#include <arch/aarch64/uart.h>
|
||||||
|
#include <arch/aarch64/io.h>
|
||||||
|
|
||||||
|
void uart_pl011_init(void) {
|
||||||
|
// Enable UART, TX, and RX (bits 0, 8, 9)
|
||||||
|
mmio_write32(PL011_UART0_BASE + UARTCR, (1 << 0) | (1 << 8) | (1 << 9));
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_pl011_putc(char c) {
|
||||||
|
if (c == '\n') {
|
||||||
|
while (mmio_read32(PL011_UART0_BASE + UARTFR) & UARTFR_TXFF) {
|
||||||
|
__asm__ volatile("nop");
|
||||||
|
}
|
||||||
|
mmio_write32(PL011_UART0_BASE + UARTDR, '\r');
|
||||||
|
}
|
||||||
|
while (mmio_read32(PL011_UART0_BASE + UARTFR) & UARTFR_TXFF) {
|
||||||
|
__asm__ volatile("nop");
|
||||||
|
}
|
||||||
|
mmio_write32(PL011_UART0_BASE + UARTDR, (uint32_t)(uint8_t)c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_pl011_puts(const char* str) {
|
||||||
|
if (!str) return;
|
||||||
|
while (*str) {
|
||||||
|
uart_pl011_putc(*str++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char uart_pl011_getc(void) {
|
||||||
|
while (mmio_read32(PL011_UART0_BASE + UARTFR) & UARTFR_RXFE) {
|
||||||
|
__asm__ volatile("wfe");
|
||||||
|
}
|
||||||
|
return (char)(mmio_read32(PL011_UART0_BASE + UARTDR) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
int uart_pl011_has_data(void) {
|
||||||
|
return !(mmio_read32(PL011_UART0_BASE + UARTFR) & UARTFR_RXFE);
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
OUTPUT_FORMAT("elf64-littleaarch64")
|
||||||
|
OUTPUT_ARCH(aarch64)
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x40080000;
|
||||||
|
|
||||||
|
__kernel_start = .;
|
||||||
|
|
||||||
|
.text.boot : {
|
||||||
|
KEEP(*(.text.boot))
|
||||||
|
}
|
||||||
|
|
||||||
|
.vectors : ALIGN(2048) {
|
||||||
|
KEEP(*(.vectors))
|
||||||
|
}
|
||||||
|
|
||||||
|
.text : ALIGN(4096) {
|
||||||
|
*(.text .text.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : ALIGN(4096) {
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : ALIGN(4096) {
|
||||||
|
*(.data .data.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss : ALIGN(4096) {
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stack : ALIGN(4096) {
|
||||||
|
. += 0x20000; /* 128 KB dedicated kernel stack */
|
||||||
|
stack_top = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
__kernel_end = .;
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#include <arch/aarch64/mmu.h>
|
||||||
|
#include <arch/aarch64/io.h>
|
||||||
|
#include <lib/string.h>
|
||||||
|
#include <kernel/printk.h>
|
||||||
|
|
||||||
|
// Level 1 Translation Table (PUD / L1, 512 x 1GB entries, root table for 39-bit VA)
|
||||||
|
static uint64_t __attribute__((aligned(4096))) l1_table[512];
|
||||||
|
// Level 2 Translation Table (PMD / L2, 512 x 2MB entries for first 1GB: 0x00000000 - 0x3FFFFFFF Device MMIO)
|
||||||
|
static uint64_t __attribute__((aligned(4096))) l2_dev_table[512];
|
||||||
|
// Level 2 Translation Table (PMD / L2, 512 x 2MB entries for second 1GB: 0x40000000 - 0x7FFFFFFF RAM)
|
||||||
|
static uint64_t __attribute__((aligned(4096))) l2_ram_table[512];
|
||||||
|
|
||||||
|
void aarch64_mmu_init(void) {
|
||||||
|
memset(l1_table, 0, sizeof(l1_table));
|
||||||
|
memset(l2_dev_table, 0, sizeof(l2_dev_table));
|
||||||
|
memset(l2_ram_table, 0, sizeof(l2_ram_table));
|
||||||
|
|
||||||
|
// L1 Table Entry 0 points to L2 Device Table (0 - 1GB)
|
||||||
|
l1_table[0] = ((uint64_t)l2_dev_table) | PTE_VALID | PTE_TABLE;
|
||||||
|
// L1 Table Entry 1 points to L2 RAM Table (1GB - 2GB: QEMU virt RAM is 0x40000000)
|
||||||
|
l1_table[1] = ((uint64_t)l2_ram_table) | PTE_VALID | PTE_TABLE;
|
||||||
|
|
||||||
|
// 1. Identity map Device MMIO (0x00000000 - 0x3FFFFFFF) as Device-nGnRnE
|
||||||
|
for (uint64_t i = 0; i < 512; i++) {
|
||||||
|
uint64_t phys = i * 0x200000; // 2MB blocks
|
||||||
|
l2_dev_table[i] = phys | PTE_VALID | PTE_AF | PTE_SH_INNER | PTE_ATTRINDX(MT_DEVICE_nGnRnE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Identity map System RAM (0x40000000 - 0x7FFFFFFF, 1GB) as Normal Cacheable
|
||||||
|
for (uint64_t i = 0; i < 512; i++) {
|
||||||
|
uint64_t phys = 0x40000000 + (i * 0x200000);
|
||||||
|
l2_ram_table[i] = phys | PTE_VALID | PTE_AF | PTE_SH_INNER | PTE_ATTRINDX(MT_NORMAL_WB);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Set Memory Attribute Indirection Register (MAIR_EL1)
|
||||||
|
__asm__ volatile("msr mair_el1, %0" :: "r"((uint64_t)MAIR_VAL));
|
||||||
|
|
||||||
|
// 4. Configure Translation Control Register (TCR_EL1)
|
||||||
|
// T0SZ=25 (39-bit VA starting at L1 / 1GB chunks), TG0=0 (4KB granule), Inner/Outer WBWA, Inner Shareable
|
||||||
|
uint64_t tcr = (25ULL << 0) | // T0SZ = 25 (39-bit VA)
|
||||||
|
(1ULL << 8) | // IRGN0 = Normal WBWA
|
||||||
|
(1ULL << 10) | // ORGN0 = Normal WBWA
|
||||||
|
(3ULL << 12) | // SH0 = Inner Shareable
|
||||||
|
(0ULL << 14) | // TG0 = 4KB
|
||||||
|
(1ULL << 23) | // EPD1 = Disable TTBR1 translations
|
||||||
|
(2ULL << 32); // IPS = 40-bit Physical Address (1TB)
|
||||||
|
__asm__ volatile("msr tcr_el1, %0" :: "r"(tcr));
|
||||||
|
|
||||||
|
// 5. Load Translation Table Base Register 0 (TTBR0_EL1)
|
||||||
|
__asm__ volatile("msr ttbr0_el1, %0" :: "r"((uint64_t)l1_table));
|
||||||
|
|
||||||
|
isb();
|
||||||
|
|
||||||
|
// 6. Enable MMU and Caching in SCTLR_EL1 (M=1, C=1, I=1)
|
||||||
|
uint64_t sctlr;
|
||||||
|
__asm__ volatile("mrs %0, sctlr_el1" : "=r"(sctlr));
|
||||||
|
sctlr |= (1 << 0) | // M: Enable MMU
|
||||||
|
(1 << 2) | // C: Enable Data Cache
|
||||||
|
(1 << 12); // I: Enable Instruction Cache
|
||||||
|
__asm__ volatile("msr sctlr_el1, %0" :: "r"(sctlr));
|
||||||
|
|
||||||
|
isb();
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#
|
||||||
|
# Automatically generated by SUB-OS Kconfig for x86_64
|
||||||
|
#
|
||||||
|
CONFIG_ARCH=x86_64
|
||||||
|
CONFIG_ARCH_X86_64=y
|
||||||
|
CONFIG_BPF_VM=y
|
||||||
|
CONFIG_DRV_AHCI=y
|
||||||
|
CONFIG_DRV_ATA=y
|
||||||
|
CONFIG_DRV_BOCHS_VBE=y
|
||||||
|
CONFIG_DRV_CANVAS_2D=y
|
||||||
|
CONFIG_DRV_E1000=y
|
||||||
|
CONFIG_DRV_HWMON=y
|
||||||
|
CONFIG_DRV_NVME=y
|
||||||
|
CONFIG_DRV_PTY=y
|
||||||
|
CONFIG_DRV_RAMDISK=y
|
||||||
|
CONFIG_DRV_RTL8139=y
|
||||||
|
CONFIG_DRV_SOUND_AC97=y
|
||||||
|
CONFIG_DRV_SOUND_HDA=y
|
||||||
|
CONFIG_DRV_USB_XHCI=y
|
||||||
|
CONFIG_DRV_VIRTIO_BLK=y
|
||||||
|
CONFIG_DRV_VIRTIO_NET=y
|
||||||
|
CONFIG_DRV_VIRTIO_RNG=y
|
||||||
|
CONFIG_FS_DEVFS=y
|
||||||
|
CONFIG_FS_EXT2=y
|
||||||
|
CONFIG_FS_FAT32=y
|
||||||
|
CONFIG_FS_PROCFS=y
|
||||||
|
CONFIG_FS_RAMFS=y
|
||||||
|
CONFIG_FS_SYSFS=y
|
||||||
|
CONFIG_FS_VFS=y
|
||||||
|
CONFIG_IO_URING=y
|
||||||
|
CONFIG_MM_PMM=y
|
||||||
|
CONFIG_MM_SLAB=y
|
||||||
|
CONFIG_MM_VMA=y
|
||||||
|
CONFIG_NET_FILTER=y
|
||||||
|
CONFIG_NET_HTTPD=y
|
||||||
|
CONFIG_NET_SSHD=y
|
||||||
|
CONFIG_NET_STACK=y
|
||||||
|
CONFIG_OPTIMIZATION="-O2"
|
||||||
|
CONFIG_PREEMPT=y
|
||||||
|
CONFIG_SECURITY_KEYRING=y
|
||||||
|
CONFIG_SECURITY_LSM=y
|
||||||
|
CONFIG_SMP=y
|
||||||
|
CONFIG_SUBOS_HOSTNAME="sub-os"
|
||||||
|
CONFIG_SUBOS_VERSION="0.2.0-lts"
|
||||||
|
CONFIG_USERLAND_LAZYBOX=y
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#include <arch/arch.h>
|
||||||
|
#include <arch/x86_64/gdt.h>
|
||||||
|
#include <arch/x86_64/idt.h>
|
||||||
|
#include <arch/x86_64/isr.h>
|
||||||
|
#include <arch/x86_64/pic.h>
|
||||||
|
#include <arch/x86_64/pit.h>
|
||||||
|
#include <arch/x86_64/cpuid.h>
|
||||||
|
#include <kernel/timer.h>
|
||||||
|
|
||||||
|
void arch_early_init(void) {
|
||||||
|
// x86_64 serial and tty initialized in main
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_init(void) {
|
||||||
|
gdt_init();
|
||||||
|
idt_init();
|
||||||
|
isr_init();
|
||||||
|
pic_init();
|
||||||
|
pit_init(100);
|
||||||
|
timer_wheel_init();
|
||||||
|
arch_enable_interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* arch_get_name(void) {
|
||||||
|
return "x86_64 (AMD64)";
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t arch_get_cpu_id(void) {
|
||||||
|
uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||||
|
cpuid(1, &eax, &ebx, &ecx, &edx);
|
||||||
|
return (ebx >> 24) & 0xFF;
|
||||||
|
}
|
||||||
+20
-4
@@ -1,8 +1,6 @@
|
|||||||
#include <drivers/keyboard.h>
|
#include <drivers/keyboard.h>
|
||||||
#include <drivers/tty.h>
|
#include <drivers/tty.h>
|
||||||
#include <arch/x86_64/isr.h>
|
#include <arch/arch.h>
|
||||||
#include <arch/x86_64/pic.h>
|
|
||||||
#include <arch/x86_64/io.h>
|
|
||||||
|
|
||||||
#define KEYBOARD_DATA_PORT 0x60
|
#define KEYBOARD_DATA_PORT 0x60
|
||||||
#define KEYBOARD_STATUS_PORT 0x64
|
#define KEYBOARD_STATUS_PORT 0x64
|
||||||
@@ -44,6 +42,7 @@ static void buffer_enqueue(uint16_t key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
static void keyboard_interrupt_handler(registers_t* regs) {
|
static void keyboard_interrupt_handler(registers_t* regs) {
|
||||||
(void)regs;
|
(void)regs;
|
||||||
uint8_t scancode = inb(KEYBOARD_DATA_PORT);
|
uint8_t scancode = inb(KEYBOARD_DATA_PORT);
|
||||||
@@ -112,23 +111,40 @@ static void keyboard_interrupt_handler(registers_t* regs) {
|
|||||||
buffer_enqueue((uint16_t)c);
|
buffer_enqueue((uint16_t)c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void keyboard_init(void) {
|
void keyboard_init(void) {
|
||||||
buffer_head = 0;
|
buffer_head = 0;
|
||||||
buffer_tail = 0;
|
buffer_tail = 0;
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
isr_register_handler(33, keyboard_interrupt_handler); // IRQ1
|
isr_register_handler(33, keyboard_interrupt_handler); // IRQ1
|
||||||
pic_clear_mask(1);
|
pic_clear_mask(1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
#include <arch/aarch64/uart.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
bool keyboard_has_key(void) {
|
bool keyboard_has_key(void) {
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
if (uart_pl011_has_data()) return true;
|
||||||
|
#endif
|
||||||
return buffer_head != buffer_tail;
|
return buffer_head != buffer_tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t keyboard_get_key(void) {
|
uint16_t keyboard_get_key(void) {
|
||||||
while (!keyboard_has_key()) {
|
while (!keyboard_has_key()) {
|
||||||
hlt();
|
arch_halt();
|
||||||
}
|
}
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
if (uart_pl011_has_data()) {
|
||||||
|
char c = uart_pl011_getc();
|
||||||
|
if (c == '\r') c = '\n';
|
||||||
|
return (uint16_t)(uint8_t)c;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
uint16_t key = key_buffer[buffer_tail];
|
uint16_t key = key_buffer[buffer_tail];
|
||||||
buffer_tail = (buffer_tail + 1) % KEYBOARD_BUFFER_SIZE;
|
buffer_tail = (buffer_tail + 1) % KEYBOARD_BUFFER_SIZE;
|
||||||
return key;
|
return key;
|
||||||
|
|||||||
+8
-3
@@ -12,16 +12,17 @@ typedef struct {
|
|||||||
static tty_t ttys[MAX_TTYS];
|
static tty_t ttys[MAX_TTYS];
|
||||||
static int current_tty = 0;
|
static int current_tty = 0;
|
||||||
|
|
||||||
static volatile uint16_t* const VGA_MEM = (uint16_t*)VGA_MEMORY;
|
|
||||||
|
|
||||||
static void tty_render_current(void) {
|
static void tty_render_current(void) {
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
volatile uint16_t* const vga_mem = (uint16_t*)VGA_MEMORY;
|
||||||
tty_t* t = &ttys[current_tty];
|
tty_t* t = &ttys[current_tty];
|
||||||
for (int y = 0; y < TTY_HEIGHT; y++) {
|
for (int y = 0; y < TTY_HEIGHT; y++) {
|
||||||
for (int x = 0; x < TTY_WIDTH; x++) {
|
for (int x = 0; x < TTY_WIDTH; x++) {
|
||||||
VGA_MEM[y * TTY_WIDTH + x] = t->buffer[y][x];
|
vga_mem[y * TTY_WIDTH + x] = t->buffer[y][x];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vga_set_cursor(t->cursor_row, t->cursor_col);
|
vga_set_cursor(t->cursor_row, t->cursor_col);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_switch(int index) {
|
void tty_switch(int index) {
|
||||||
@@ -62,7 +63,9 @@ void tty_set_cursor(int row, int col) {
|
|||||||
tty_t* t = &ttys[current_tty];
|
tty_t* t = &ttys[current_tty];
|
||||||
t->cursor_row = row;
|
t->cursor_row = row;
|
||||||
t->cursor_col = col;
|
t->cursor_col = col;
|
||||||
|
#if defined(__x86_64__)
|
||||||
vga_set_cursor(row, col);
|
vga_set_cursor(row, col);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_write(const char* data, size_t size) {
|
void tty_write(const char* data, size_t size) {
|
||||||
@@ -150,7 +153,9 @@ void tty_write_string(const char* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void tty_init(void) {
|
void tty_init(void) {
|
||||||
|
#if defined(__x86_64__)
|
||||||
vga_init();
|
vga_init();
|
||||||
|
#endif
|
||||||
for (int i = 0; i < MAX_TTYS; i++) {
|
for (int i = 0; i < MAX_TTYS; i++) {
|
||||||
ttys[i].cursor_row = 0;
|
ttys[i].cursor_row = 0;
|
||||||
ttys[i].cursor_col = 0;
|
ttys[i].cursor_col = 0;
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef _ARCH_AARCH64_ARCH_H
|
||||||
|
#define _ARCH_AARCH64_ARCH_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t r[31]; // X0 - X30
|
||||||
|
uint64_t sp;
|
||||||
|
uint64_t pc;
|
||||||
|
uint64_t pstate;
|
||||||
|
} __attribute__((packed)) aarch64_context_t;
|
||||||
|
|
||||||
|
void aarch64_init(void);
|
||||||
|
|
||||||
|
#endif // _ARCH_AARCH64_ARCH_H
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _ARCH_AARCH64_CPU_H
|
||||||
|
#define _ARCH_AARCH64_CPU_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t implementer;
|
||||||
|
uint32_t variant;
|
||||||
|
uint32_t architecture;
|
||||||
|
uint32_t part_num;
|
||||||
|
uint32_t revision;
|
||||||
|
char model_name[64];
|
||||||
|
uint32_t current_el;
|
||||||
|
uint64_t core_frequency_hz;
|
||||||
|
} aarch64_cpu_info_t;
|
||||||
|
|
||||||
|
void aarch64_cpu_init(void);
|
||||||
|
const aarch64_cpu_info_t* aarch64_get_cpu_info(void);
|
||||||
|
uint32_t aarch64_get_current_el(void);
|
||||||
|
uint64_t aarch64_get_midr(void);
|
||||||
|
uint64_t aarch64_get_mpidr(void);
|
||||||
|
|
||||||
|
#endif // _ARCH_AARCH64_CPU_H
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef _ARCH_AARCH64_GIC_H
|
||||||
|
#define _ARCH_AARCH64_GIC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define GIC_DIST_BASE 0x08000000
|
||||||
|
#define GIC_CPU_BASE 0x08010000
|
||||||
|
|
||||||
|
// GIC Distributor Registers
|
||||||
|
#define GICD_CTLR 0x000
|
||||||
|
#define GICD_TYPER 0x004
|
||||||
|
#define GICD_ISENABLER(n) (0x100 + ((n) * 4))
|
||||||
|
#define GICD_ICENABLER(n) (0x180 + ((n) * 4))
|
||||||
|
#define GICD_IPRIORITYR(n) (0x400 + ((n) * 4))
|
||||||
|
#define GICD_ITARGETSR(n) (0x800 + ((n) * 4))
|
||||||
|
#define GICD_ICFGR(n) (0xC00 + ((n) * 4))
|
||||||
|
|
||||||
|
// GIC CPU Interface Registers
|
||||||
|
#define GICC_CTLR 0x0000
|
||||||
|
#define GICC_PMR 0x0004
|
||||||
|
#define GICC_BPR 0x0008
|
||||||
|
#define GICC_IAR 0x000C
|
||||||
|
#define GICC_EOIR 0x0010
|
||||||
|
|
||||||
|
typedef void (*gic_irq_handler_t)(uint32_t irq);
|
||||||
|
|
||||||
|
void gic_init(void);
|
||||||
|
void gic_enable_irq(uint32_t irq);
|
||||||
|
void gic_disable_irq(uint32_t irq);
|
||||||
|
void gic_register_handler(uint32_t irq, gic_irq_handler_t handler);
|
||||||
|
void gic_handle_irq(void);
|
||||||
|
|
||||||
|
#endif // _ARCH_AARCH64_GIC_H
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
#ifndef _ARCH_AARCH64_IO_H
|
||||||
|
#define _ARCH_AARCH64_IO_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static inline void mmio_write8(uintptr_t reg, uint8_t val) {
|
||||||
|
*(volatile uint8_t*)reg = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8_t mmio_read8(uintptr_t reg) {
|
||||||
|
return *(volatile uint8_t*)reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mmio_write16(uintptr_t reg, uint16_t val) {
|
||||||
|
*(volatile uint16_t*)reg = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t mmio_read16(uintptr_t reg) {
|
||||||
|
return *(volatile uint16_t*)reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mmio_write32(uintptr_t reg, uint32_t val) {
|
||||||
|
*(volatile uint32_t*)reg = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t mmio_read32(uintptr_t reg) {
|
||||||
|
return *(volatile uint32_t*)reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mmio_write64(uintptr_t reg, uint64_t val) {
|
||||||
|
*(volatile uint64_t*)reg = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t mmio_read64(uintptr_t reg) {
|
||||||
|
return *(volatile uint64_t*)reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Memory barriers
|
||||||
|
static inline void dsb(void) {
|
||||||
|
__asm__ volatile("dsb sy" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dmb(void) {
|
||||||
|
__asm__ volatile("dmb sy" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void isb(void) {
|
||||||
|
__asm__ volatile("isb" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
// x86 I/O Port Emulation / Stubs for Portable Device Drivers
|
||||||
|
static inline void outb(uint16_t port, uint8_t val) {
|
||||||
|
(void)port; (void)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8_t inb(uint16_t port) {
|
||||||
|
(void)port;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void outw(uint16_t port, uint16_t val) {
|
||||||
|
(void)port; (void)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t inw(uint16_t port) {
|
||||||
|
(void)port;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void outl(uint16_t port, uint32_t val) {
|
||||||
|
(void)port; (void)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t inl(uint16_t port) {
|
||||||
|
(void)port;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void io_wait(void) {
|
||||||
|
__asm__ volatile("nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void cli(void) {
|
||||||
|
__asm__ volatile("msr daifset, #2" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sti(void) {
|
||||||
|
__asm__ volatile("msr daifclr, #2" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hlt(void) {
|
||||||
|
__asm__ volatile("wfi");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _ARCH_AARCH64_IO_H
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef _ARCH_AARCH64_MMU_H
|
||||||
|
#define _ARCH_AARCH64_MMU_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define MMU_PAGE_SIZE 4096
|
||||||
|
|
||||||
|
// Memory Types / Attributes index for MAIR_EL1
|
||||||
|
#define MT_DEVICE_nGnRnE 0
|
||||||
|
#define MT_NORMAL_NC 1
|
||||||
|
#define MT_NORMAL_WB 2
|
||||||
|
|
||||||
|
#define MAIR_DEVICE_nGnRnE 0x00
|
||||||
|
#define MAIR_NORMAL_NC 0x44
|
||||||
|
#define MAIR_NORMAL_WB 0xFF
|
||||||
|
|
||||||
|
#define MAIR_VAL ((MAIR_DEVICE_nGnRnE << (MT_DEVICE_nGnRnE * 8)) | \
|
||||||
|
(MAIR_NORMAL_NC << (MT_NORMAL_NC * 8)) | \
|
||||||
|
(MAIR_NORMAL_WB << (MT_NORMAL_WB * 8)))
|
||||||
|
|
||||||
|
// Page descriptor bits
|
||||||
|
#define PTE_VALID (1ULL << 0)
|
||||||
|
#define PTE_TABLE (1ULL << 1)
|
||||||
|
#define PTE_BLOCK (0ULL << 1)
|
||||||
|
#define PTE_USER (1ULL << 6)
|
||||||
|
#define PTE_RO (1ULL << 7)
|
||||||
|
#define PTE_SH_INNER (3ULL << 8)
|
||||||
|
#define PTE_AF (1ULL << 10)
|
||||||
|
#define PTE_NG (1ULL << 11)
|
||||||
|
#define PTE_PXN (1ULL << 53)
|
||||||
|
#define PTE_UXN (1ULL << 54)
|
||||||
|
|
||||||
|
#define PTE_ATTRINDX(x) (((uint64_t)(x)) << 2)
|
||||||
|
|
||||||
|
void aarch64_mmu_init(void);
|
||||||
|
void aarch64_mmu_map_2mb(uint64_t virt_addr, uint64_t phys_addr, uint32_t mem_type);
|
||||||
|
|
||||||
|
#endif // _ARCH_AARCH64_MMU_H
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef _ARCH_AARCH64_TIMER_H
|
||||||
|
#define _ARCH_AARCH64_TIMER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define ARCH_TIMER_VIRT_IRQ 27
|
||||||
|
|
||||||
|
void aarch64_timer_init(uint32_t freq_hz);
|
||||||
|
uint64_t aarch64_timer_get_ticks(void);
|
||||||
|
uint64_t aarch64_timer_get_freq(void);
|
||||||
|
void aarch64_timer_handle_irq(void);
|
||||||
|
|
||||||
|
#endif // _ARCH_AARCH64_TIMER_H
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef _ARCH_AARCH64_UART_H
|
||||||
|
#define _ARCH_AARCH64_UART_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define PL011_UART0_BASE 0x09000000
|
||||||
|
|
||||||
|
// PL011 Registers
|
||||||
|
#define UARTDR 0x000
|
||||||
|
#define UARTRSR 0x004
|
||||||
|
#define UARTFR 0x018
|
||||||
|
#define UARTILPR 0x020
|
||||||
|
#define UARTIBRD 0x024
|
||||||
|
#define UARTFBRD 0x028
|
||||||
|
#define UARTLCR 0x02C
|
||||||
|
#define UARTCR 0x030
|
||||||
|
#define UARTIFLS 0x034
|
||||||
|
#define UARTIMSC 0x038
|
||||||
|
#define UARTRIS 0x03C
|
||||||
|
#define UARTMIS 0x040
|
||||||
|
#define UARTICR 0x044
|
||||||
|
|
||||||
|
// Flag register bits
|
||||||
|
#define UARTFR_TXFF (1 << 5)
|
||||||
|
#define UARTFR_RXFE (1 << 4)
|
||||||
|
|
||||||
|
void uart_pl011_init(void);
|
||||||
|
void uart_pl011_putc(char c);
|
||||||
|
void uart_pl011_puts(const char* str);
|
||||||
|
char uart_pl011_getc(void);
|
||||||
|
int uart_pl011_has_data(void);
|
||||||
|
|
||||||
|
#endif // _ARCH_AARCH64_UART_H
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
#ifndef _ARCH_ARCH_H
|
||||||
|
#define _ARCH_ARCH_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
#define ARCH_NAME "x86_64"
|
||||||
|
#define ARCH_IS_64BIT 1
|
||||||
|
#include <arch/x86_64/gdt.h>
|
||||||
|
#include <arch/x86_64/idt.h>
|
||||||
|
#include <arch/x86_64/isr.h>
|
||||||
|
#include <arch/x86_64/pic.h>
|
||||||
|
#include <arch/x86_64/pit.h>
|
||||||
|
#include <arch/x86_64/cpuid.h>
|
||||||
|
#include <arch/x86_64/paging.h>
|
||||||
|
#include <arch/x86_64/io.h>
|
||||||
|
|
||||||
|
static inline void arch_enable_interrupts(void) {
|
||||||
|
__asm__ volatile("sti");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void arch_disable_interrupts(void) {
|
||||||
|
__asm__ volatile("cli");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void arch_halt(void) {
|
||||||
|
__asm__ volatile("hlt");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void arch_wait_for_interrupt(void) {
|
||||||
|
__asm__ volatile("sti; hlt");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t arch_get_ticks(void) {
|
||||||
|
return pit_get_ticks();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void arch_sleep(uint32_t ms) {
|
||||||
|
pit_sleep(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__aarch64__) || defined(__arm64__)
|
||||||
|
#define ARCH_NAME "aarch64"
|
||||||
|
#define ARCH_IS_64BIT 1
|
||||||
|
#include <arch/aarch64/arch.h>
|
||||||
|
#include <arch/aarch64/cpu.h>
|
||||||
|
#include <arch/aarch64/gic.h>
|
||||||
|
#include <arch/aarch64/timer.h>
|
||||||
|
#include <arch/aarch64/mmu.h>
|
||||||
|
#include <arch/aarch64/uart.h>
|
||||||
|
#include <arch/aarch64/io.h>
|
||||||
|
|
||||||
|
static inline void arch_enable_interrupts(void) {
|
||||||
|
__asm__ volatile("msr daifclr, #2" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void arch_disable_interrupts(void) {
|
||||||
|
__asm__ volatile("msr daifset, #2" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void arch_halt(void) {
|
||||||
|
__asm__ volatile("wfi");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void arch_wait_for_interrupt(void) {
|
||||||
|
__asm__ volatile("msr daifclr, #2; wfi" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t arch_get_ticks(void) {
|
||||||
|
return aarch64_timer_get_ticks();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void arch_sleep(uint32_t ms) {
|
||||||
|
uint64_t count = (ms > 10) ? (ms / 10) : 1;
|
||||||
|
uint64_t target = aarch64_timer_get_ticks() + count;
|
||||||
|
while (aarch64_timer_get_ticks() < target) {
|
||||||
|
__asm__ volatile("wfi");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prototype declarations for timer/interrupt compatibility
|
||||||
|
uint64_t pit_get_ticks(void);
|
||||||
|
void pit_sleep(uint32_t ms);
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Unsupported Target CPU Architecture!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Generic Architecture API
|
||||||
|
void arch_early_init(void);
|
||||||
|
void arch_init(void);
|
||||||
|
const char* arch_get_name(void);
|
||||||
|
uint32_t arch_get_cpu_id(void);
|
||||||
|
|
||||||
|
#endif // _ARCH_ARCH_H
|
||||||
@@ -25,9 +25,17 @@ typedef struct {
|
|||||||
} cpu_info_t;
|
} cpu_info_t;
|
||||||
|
|
||||||
static inline void cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
|
static inline void cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
|
||||||
|
#if defined(__x86_64__)
|
||||||
__asm__ volatile("cpuid"
|
__asm__ volatile("cpuid"
|
||||||
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||||
: "a"(leaf), "c"(0));
|
: "a"(leaf), "c"(0));
|
||||||
|
#else
|
||||||
|
(void)leaf;
|
||||||
|
if (eax) *eax = 0;
|
||||||
|
if (ebx) *ebx = 0;
|
||||||
|
if (ecx) *ecx = 0;
|
||||||
|
if (edx) *edx = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpuid_detect(cpu_info_t* info);
|
void cpuid_detect(cpu_info_t* info);
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
|
||||||
static inline void outb(uint16_t port, uint8_t val) {
|
static inline void outb(uint16_t port, uint8_t val) {
|
||||||
__asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
|
__asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||||
}
|
}
|
||||||
@@ -49,4 +51,20 @@ static inline void hlt(void) {
|
|||||||
__asm__ volatile ("hlt");
|
__asm__ volatile ("hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Portable Stubs for non-x86 architectures
|
||||||
|
static inline void outb(uint16_t port, uint8_t val) { (void)port; (void)val; }
|
||||||
|
static inline uint8_t inb(uint16_t port) { (void)port; return 0; }
|
||||||
|
static inline void outw(uint16_t port, uint16_t val) { (void)port; (void)val; }
|
||||||
|
static inline uint16_t inw(uint16_t port) { (void)port; return 0; }
|
||||||
|
static inline void outl(uint16_t port, uint32_t val) { (void)port; (void)val; }
|
||||||
|
static inline uint32_t inl(uint16_t port) { (void)port; return 0; }
|
||||||
|
static inline void io_wait(void) { }
|
||||||
|
static inline void cli(void) { __asm__ volatile("msr daifset, #2" ::: "memory"); }
|
||||||
|
static inline void sti(void) { __asm__ volatile("msr daifclr, #2" ::: "memory"); }
|
||||||
|
static inline void hlt(void) { __asm__ volatile("wfi"); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // _ARCH_X86_64_IO_H
|
#endif // _ARCH_X86_64_IO_H
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/* Automatically generated by SUB-OS Kconfig. Do not edit. */
|
||||||
|
#ifndef _AUTOCONF_H
|
||||||
|
#define _AUTOCONF_H
|
||||||
|
|
||||||
|
#define CONFIG_ARCH "aarch64"
|
||||||
|
#define CONFIG_ARCH_AARCH64 1
|
||||||
|
#define CONFIG_BPF_VM 1
|
||||||
|
#define CONFIG_DRV_AHCI 1
|
||||||
|
#define CONFIG_DRV_ATA 1
|
||||||
|
#define CONFIG_DRV_BOCHS_VBE 1
|
||||||
|
#define CONFIG_DRV_CANVAS_2D 1
|
||||||
|
#define CONFIG_DRV_E1000 1
|
||||||
|
#define CONFIG_DRV_HWMON 1
|
||||||
|
#define CONFIG_DRV_NVME 1
|
||||||
|
#define CONFIG_DRV_PTY 1
|
||||||
|
#define CONFIG_DRV_RAMDISK 1
|
||||||
|
#define CONFIG_DRV_RTL8139 1
|
||||||
|
#define CONFIG_DRV_SOUND_AC97 1
|
||||||
|
#define CONFIG_DRV_SOUND_HDA 1
|
||||||
|
#define CONFIG_DRV_USB_XHCI 1
|
||||||
|
#define CONFIG_DRV_VIRTIO_BLK 1
|
||||||
|
#define CONFIG_DRV_VIRTIO_NET 1
|
||||||
|
#define CONFIG_DRV_VIRTIO_RNG 1
|
||||||
|
#define CONFIG_FS_DEVFS 1
|
||||||
|
#define CONFIG_FS_EXT2 1
|
||||||
|
#define CONFIG_FS_FAT32 1
|
||||||
|
#define CONFIG_FS_PROCFS 1
|
||||||
|
#define CONFIG_FS_RAMFS 1
|
||||||
|
#define CONFIG_FS_SYSFS 1
|
||||||
|
#define CONFIG_FS_VFS 1
|
||||||
|
#define CONFIG_IO_URING 1
|
||||||
|
#define CONFIG_MM_PMM 1
|
||||||
|
#define CONFIG_MM_SLAB 1
|
||||||
|
#define CONFIG_MM_VMA 1
|
||||||
|
#define CONFIG_NET_FILTER 1
|
||||||
|
#define CONFIG_NET_HTTPD 1
|
||||||
|
#define CONFIG_NET_SSHD 1
|
||||||
|
#define CONFIG_NET_STACK 1
|
||||||
|
#define CONFIG_OPTIMIZATION "-O2"
|
||||||
|
#define CONFIG_PREEMPT 1
|
||||||
|
#define CONFIG_SECURITY_KEYRING 1
|
||||||
|
#define CONFIG_SECURITY_LSM 1
|
||||||
|
#define CONFIG_SMP 1
|
||||||
|
#define CONFIG_SUBOS_HOSTNAME "sub-os"
|
||||||
|
#define CONFIG_SUBOS_VERSION "0.2.0-lts"
|
||||||
|
#define CONFIG_USERLAND_LAZYBOX 1
|
||||||
|
|
||||||
|
#endif /* _AUTOCONF_H */
|
||||||
+12
-1
@@ -5,9 +5,20 @@
|
|||||||
#define SUBOS_VERSION_MINOR 2
|
#define SUBOS_VERSION_MINOR 2
|
||||||
#define SUBOS_VERSION_PATCH 0
|
#define SUBOS_VERSION_PATCH 0
|
||||||
#define SUBOS_VERSION_CODENAME "Titan"
|
#define SUBOS_VERSION_CODENAME "Titan"
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
#define SUBOS_VERSION_STRING "0.2.0-lts (x86_64)"
|
#define SUBOS_VERSION_STRING "0.2.0-lts (x86_64)"
|
||||||
#define SUBOS_BUILD_TARGET "x86_64-elf-baremetal"
|
#define SUBOS_BUILD_TARGET "x86_64-elf-baremetal"
|
||||||
#define SUBOS_COMPILER "x86_64-elf-gcc (Modular Monolithic)"
|
#define SUBOS_COMPILER "x86_64-elf-gcc"
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
#define SUBOS_VERSION_STRING "0.2.0-lts (aarch64)"
|
||||||
|
#define SUBOS_BUILD_TARGET "aarch64-linux-gnu-baremetal"
|
||||||
|
#define SUBOS_COMPILER "aarch64-linux-gnu-gcc"
|
||||||
|
#else
|
||||||
|
#define SUBOS_VERSION_STRING "0.2.0-lts (generic)"
|
||||||
|
#define SUBOS_BUILD_TARGET "generic-elf-baremetal"
|
||||||
|
#define SUBOS_COMPILER "gcc"
|
||||||
|
#endif
|
||||||
|
|
||||||
const char* kernel_get_version(void);
|
const char* kernel_get_version(void);
|
||||||
const char* kernel_get_build_banner(void);
|
const char* kernel_get_build_banner(void);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "printk.h"
|
#include "printk.h"
|
||||||
#include <arch/x86_64/io.h>
|
#include <arch/arch.h>
|
||||||
|
|
||||||
#define KERNEL_NAME "SUB-OS"
|
#define KERNEL_NAME "SUB-OS"
|
||||||
#define KERNEL_VERSION "0.2.0-lts"
|
#define KERNEL_VERSION "0.2.0-lts"
|
||||||
|
|||||||
@@ -16,7 +16,13 @@ static inline void spinlock_init(spinlock_t* lock) {
|
|||||||
|
|
||||||
static inline void spin_lock(spinlock_t* lock) {
|
static inline void spin_lock(spinlock_t* lock) {
|
||||||
while (__atomic_test_and_set(&lock->lock, __ATOMIC_ACQUIRE)) {
|
while (__atomic_test_and_set(&lock->lock, __ATOMIC_ACQUIRE)) {
|
||||||
|
#if defined(__x86_64__)
|
||||||
__asm__ volatile ("pause");
|
__asm__ volatile ("pause");
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
__asm__ volatile ("yield");
|
||||||
|
#else
|
||||||
|
__asm__ volatile ("");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+101
-86
@@ -17,13 +17,7 @@
|
|||||||
#include <mm/vma.h>
|
#include <mm/vma.h>
|
||||||
#include <drivers/canvas.h>
|
#include <drivers/canvas.h>
|
||||||
#include <drivers/pty.h>
|
#include <drivers/pty.h>
|
||||||
#include <arch/x86_64/gdt.h>
|
#include <arch/arch.h>
|
||||||
#include <arch/x86_64/idt.h>
|
|
||||||
#include <arch/x86_64/isr.h>
|
|
||||||
#include <arch/x86_64/pic.h>
|
|
||||||
#include <arch/x86_64/pit.h>
|
|
||||||
#include <arch/x86_64/cpuid.h>
|
|
||||||
#include <arch/x86_64/paging.h>
|
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <mm/kmalloc.h>
|
#include <mm/kmalloc.h>
|
||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
@@ -81,83 +75,41 @@
|
|||||||
#include <userland/sh.h>
|
#include <userland/sh.h>
|
||||||
#include <userland/shell.h>
|
#include <userland/shell.h>
|
||||||
|
|
||||||
void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
static void subos_modular_core_boot(void) {
|
||||||
// 1. Console & Telemetry
|
// Storage & Block Layer
|
||||||
tty_init();
|
printk(KERN_INFO "[4/14] Initializing Block Layer & Storage Controllers... ");
|
||||||
serial_init();
|
|
||||||
printk_init();
|
|
||||||
|
|
||||||
printk(ANSI_BRIGHT_CYAN "=================================================================\n" ANSI_RESET);
|
|
||||||
printk(ANSI_BRIGHT_CYAN " SUB-OS 64-Bit Production Modular Monolithic Kernel %s\n" ANSI_RESET, kernel_get_version());
|
|
||||||
printk(ANSI_BRIGHT_CYAN "=================================================================\n\n" ANSI_RESET);
|
|
||||||
|
|
||||||
// 2. Early Boot Parameters & RTC Real-Time Clock
|
|
||||||
init_early("root=/dev/sda console=tty1 init=/bin/lazybox quiet");
|
|
||||||
rtc_init();
|
|
||||||
|
|
||||||
// 3. CPU Architecture & Interrupts
|
|
||||||
printk(KERN_INFO "[1/18] Initializing 64-Bit GDT & TSS... ");
|
|
||||||
gdt_init();
|
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
|
||||||
|
|
||||||
printk(KERN_INFO "[2/18] Initializing Interrupt Descriptor Table (IDT & ISRs)... ");
|
|
||||||
idt_init();
|
|
||||||
isr_init();
|
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
|
||||||
|
|
||||||
printk(KERN_INFO "[3/18] Remapping Dual 8259A PIC Controller... ");
|
|
||||||
pic_init();
|
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
|
||||||
|
|
||||||
printk(KERN_INFO "[4/18] Configuring 8254 PIT Timer & High-Res Timer Wheel... ");
|
|
||||||
pit_init(100);
|
|
||||||
timer_wheel_init();
|
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
|
||||||
|
|
||||||
// 4. Input & Power Drivers
|
|
||||||
printk(KERN_INFO "[5/18] Initializing PS/2 Keyboard, Mouse & ACPI... ");
|
|
||||||
keyboard_init();
|
|
||||||
mouse_init();
|
|
||||||
acpi_init();
|
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
|
||||||
|
|
||||||
// 5. Memory Management: PMM + Dynamic Heap + SLAB Cache
|
|
||||||
printk(KERN_INFO "[6/18] Initializing Physical PMM, Dynamic Heap & SLAB Cache... ");
|
|
||||||
pmm_init(memory_map, memory_map_count);
|
|
||||||
heap_init();
|
|
||||||
slab_init();
|
|
||||||
vma_init();
|
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
|
||||||
|
|
||||||
// 6. Storage & Block Layer
|
|
||||||
printk(KERN_INFO "[7/18] Initializing Block Layer, Ramdisk & Storage Controllers... ");
|
|
||||||
block_init();
|
block_init();
|
||||||
ramdisk_init();
|
ramdisk_init();
|
||||||
|
#if defined(__x86_64__)
|
||||||
ata_init();
|
ata_init();
|
||||||
ahci_init();
|
ahci_init();
|
||||||
nvme_init();
|
nvme_init();
|
||||||
|
#endif
|
||||||
virtio_blk_init();
|
virtio_blk_init();
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
// 7. Bus & Devices
|
// Bus & Devices
|
||||||
printk(KERN_INFO "[8/18] Enumerating PCI Bus, VirtIO, xHCI, VBE, Canvas & PTY... ");
|
printk(KERN_INFO "[5/14] Enumerating System Devices, Canvas & PTY... ");
|
||||||
|
#if defined(__x86_64__)
|
||||||
pci_init();
|
pci_init();
|
||||||
virt_init();
|
virt_init();
|
||||||
fb_init();
|
fb_init();
|
||||||
bochs_vbe_init();
|
bochs_vbe_init();
|
||||||
canvas_init();
|
|
||||||
pty_init();
|
|
||||||
usb_init();
|
usb_init();
|
||||||
xhci_init();
|
xhci_init();
|
||||||
virtio_rng_init();
|
|
||||||
hwmon_init();
|
hwmon_init();
|
||||||
|
#endif
|
||||||
|
canvas_init();
|
||||||
|
pty_init();
|
||||||
|
virtio_rng_init();
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
// 7. Network Subsystem, NetFilter, HTTPD & SSH Server
|
// Network Subsystem, NetFilter, HTTPD & SSH Server
|
||||||
printk(KERN_INFO "[9/18] Initializing Network Stack, NetFilter, HTTPD & SSHD... ");
|
printk(KERN_INFO "[6/14] Initializing Network Stack, NetFilter, HTTPD & SSHD... ");
|
||||||
filter_init();
|
filter_init();
|
||||||
httpd_init();
|
httpd_init();
|
||||||
sshd_init();
|
sshd_init();
|
||||||
|
#if defined(__x86_64__)
|
||||||
rtl8139_init();
|
rtl8139_init();
|
||||||
virtio_net_init();
|
virtio_net_init();
|
||||||
if (e1000_init()) {
|
if (e1000_init()) {
|
||||||
@@ -171,16 +123,22 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
|||||||
} else {
|
} else {
|
||||||
printk(ANSI_YELLOW "No NIC detected\n" ANSI_RESET);
|
printk(ANSI_YELLOW "No NIC detected\n" ANSI_RESET);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
virtio_net_init();
|
||||||
|
printk(ANSI_BRIGHT_GREEN "Online\n" ANSI_RESET);
|
||||||
|
#endif
|
||||||
|
|
||||||
// 8. Sound & Voice Synthesizer
|
// Sound & Voice Synthesizer
|
||||||
printk(KERN_INFO "[10/18] Initializing Sound Architecture, Melody Player & Formant TTS... ");
|
#if defined(__x86_64__)
|
||||||
|
printk(KERN_INFO "[7/14] Initializing Sound Architecture, Melody Player & Formant TTS... ");
|
||||||
sound_init();
|
sound_init();
|
||||||
hda_init();
|
hda_init();
|
||||||
melody_init();
|
melody_init();
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
#endif
|
||||||
|
|
||||||
// 9. Crypto, Certificates, LSM Security, Authentication & Namespaces
|
// Crypto, Certificates, LSM Security, Authentication & Namespaces
|
||||||
printk(KERN_INFO "[11/18] Initializing X.509 Keyring, Shadow Auth & Namespaces... ");
|
printk(KERN_INFO "[8/14] Initializing X.509 Keyring, Shadow Auth & Namespaces... ");
|
||||||
prng_seed(0, 0);
|
prng_seed(0, 0);
|
||||||
certs_init();
|
certs_init();
|
||||||
security_init();
|
security_init();
|
||||||
@@ -188,18 +146,18 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
|||||||
namespace_init();
|
namespace_init();
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
// 10. Inter-Process Communication
|
// Inter-Process Communication
|
||||||
printk(KERN_INFO "[12/18] Initializing IPC Engine (Pipes, MsgQueues, SHM, Semaphores)... ");
|
printk(KERN_INFO "[9/14] Initializing IPC Engine (Pipes, MsgQueues, SHM, Semaphores)... ");
|
||||||
ipc_init();
|
ipc_init();
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
// 11. Asynchronous I/O Engine
|
// Asynchronous I/O Engine
|
||||||
printk(KERN_INFO "[13/18] Initializing io_uring Async Ring Engine... ");
|
printk(KERN_INFO "[10/14] Initializing io_uring Async Ring Engine... ");
|
||||||
io_uring_init();
|
io_uring_init();
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
// 12. Virtual File System & Multi-Filesystem Support
|
// Virtual File System & Multi-Filesystem Support
|
||||||
printk(KERN_INFO "[14/18] Mounting Virtual File System (VFS, devfs, procfs, sysfs)... ");
|
printk(KERN_INFO "[11/14] Mounting Virtual File System (VFS, devfs, procfs, sysfs)... ");
|
||||||
vfs_init();
|
vfs_init();
|
||||||
sysfs_init();
|
sysfs_init();
|
||||||
kobject_subsystem_init();
|
kobject_subsystem_init();
|
||||||
@@ -208,8 +166,8 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
|||||||
initramfs_init();
|
initramfs_init();
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
// 13. Kernel Core: Signals, Modules, Syscalls, Tracing, Syslog, Metrics, Crond & Systemd
|
// Kernel Core: Signals, Modules, Syscalls, Tracing, Syslog, Metrics, Crond & Systemd
|
||||||
printk(KERN_INFO "[15/18] Initializing Syslog, Metrics, Cron, Tracing, BPF & Services... ");
|
printk(KERN_INFO "[12/14] Initializing Syslog, Metrics, Cron, Tracing, BPF & Services... ");
|
||||||
signal_init();
|
signal_init();
|
||||||
workqueue_init();
|
workqueue_init();
|
||||||
syscall_init();
|
syscall_init();
|
||||||
@@ -222,25 +180,82 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
|||||||
service_manager_init();
|
service_manager_init();
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
// 14. Preemptive Multi-Tasking & Userland
|
// Preemptive Multi-Tasking & Userland
|
||||||
printk(KERN_INFO "[16/18] Initializing Preemptive Task Scheduler & LazyBox... ");
|
printk(KERN_INFO "[13/14] Initializing Preemptive Task Scheduler & LazyBox... ");
|
||||||
sched_init();
|
sched_init();
|
||||||
lazybox_init();
|
lazybox_init();
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
// 15. Hardware Interrupts
|
// Hardware Interrupts
|
||||||
printk(KERN_INFO "[17/18] Enabling Hardware Interrupts... ");
|
printk(KERN_INFO "[14/14] Enabling Hardware Interrupts... ");
|
||||||
sti();
|
arch_enable_interrupts();
|
||||||
printk(ANSI_BRIGHT_GREEN "ACTIVE\n" ANSI_RESET);
|
printk(ANSI_BRIGHT_GREEN "ACTIVE\n" ANSI_RESET);
|
||||||
|
|
||||||
// 16. Welcome & Launch Shell
|
// Launch Shell
|
||||||
printk(KERN_INFO "[18/18] Launching Userland Shell on TTY1... ");
|
#if defined(__x86_64__)
|
||||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
|
||||||
|
|
||||||
tty_clear();
|
tty_clear();
|
||||||
|
#endif
|
||||||
shell_run();
|
shell_run();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
hlt();
|
arch_halt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
||||||
|
tty_init();
|
||||||
|
serial_init();
|
||||||
|
printk_init();
|
||||||
|
|
||||||
|
printk(ANSI_BRIGHT_CYAN "=================================================================\n" ANSI_RESET);
|
||||||
|
printk(ANSI_BRIGHT_CYAN " SUB-OS 64-Bit [%s] Modular Monolithic Kernel %s\n" ANSI_RESET, arch_get_name(), kernel_get_version());
|
||||||
|
printk(ANSI_BRIGHT_CYAN "=================================================================\n\n" ANSI_RESET);
|
||||||
|
|
||||||
|
init_early("root=/dev/sda console=tty1 init=/bin/lazybox quiet");
|
||||||
|
rtc_init();
|
||||||
|
|
||||||
|
printk(KERN_INFO "[1/14] Initializing 64-Bit GDT, IDT, PIC & PIT Timer... ");
|
||||||
|
arch_init();
|
||||||
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
|
printk(KERN_INFO "[2/14] Initializing PS/2 Keyboard, Mouse & ACPI... ");
|
||||||
|
keyboard_init();
|
||||||
|
mouse_init();
|
||||||
|
acpi_init();
|
||||||
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
|
printk(KERN_INFO "[3/14] Initializing Physical PMM, Dynamic Heap & SLAB Cache... ");
|
||||||
|
pmm_init(memory_map, memory_map_count);
|
||||||
|
heap_init();
|
||||||
|
slab_init();
|
||||||
|
vma_init();
|
||||||
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
|
subos_modular_core_boot();
|
||||||
|
}
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
void kernel_main_aarch64(void) {
|
||||||
|
arch_early_init();
|
||||||
|
printk_init();
|
||||||
|
|
||||||
|
printk(ANSI_BRIGHT_CYAN "=================================================================\n" ANSI_RESET);
|
||||||
|
printk(ANSI_BRIGHT_CYAN " SUB-OS 64-Bit [%s] Modular Monolithic Kernel %s\n" ANSI_RESET, arch_get_name(), kernel_get_version());
|
||||||
|
printk(ANSI_BRIGHT_CYAN "=================================================================\n\n" ANSI_RESET);
|
||||||
|
|
||||||
|
init_early("root=/dev/vda console=ttyAMA0 init=/bin/lazybox quiet");
|
||||||
|
|
||||||
|
printk(KERN_INFO "[1/14] Initializing AArch64 CPU, GICv2, Generic Timer & MMU... ");
|
||||||
|
arch_init();
|
||||||
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
|
printk(KERN_INFO "[2/14] Initializing Physical PMM, Dynamic Heap & SLAB Cache... ");
|
||||||
|
pmm_init(NULL, 0);
|
||||||
|
heap_init();
|
||||||
|
slab_init();
|
||||||
|
vma_init();
|
||||||
|
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||||
|
|
||||||
|
subos_modular_core_boot();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
+4
-4
@@ -1,10 +1,10 @@
|
|||||||
#include <kernel/panic.h>
|
#include <kernel/panic.h>
|
||||||
#include <kernel/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <drivers/tty.h>
|
#include <drivers/tty.h>
|
||||||
#include <arch/x86_64/io.h>
|
#include <arch/arch.h>
|
||||||
|
|
||||||
void panic_with_regs(const char* message, const registers_t* regs) {
|
void panic_with_regs(const char* message, const registers_t* regs) {
|
||||||
cli();
|
arch_disable_interrupts();
|
||||||
|
|
||||||
printk("\n" ANSI_BRIGHT_RED "================================================================================" ANSI_RESET "\n");
|
printk("\n" ANSI_BRIGHT_RED "================================================================================" ANSI_RESET "\n");
|
||||||
printk(ANSI_BRIGHT_RED " *** KERNEL PANIC - SYSTEM HALTED *** " ANSI_RESET "\n");
|
printk(ANSI_BRIGHT_RED " *** KERNEL PANIC - SYSTEM HALTED *** " ANSI_RESET "\n");
|
||||||
@@ -12,7 +12,7 @@ void panic_with_regs(const char* message, const registers_t* regs) {
|
|||||||
printk(ANSI_BRIGHT_WHITE "Reason: " ANSI_YELLOW "%s" ANSI_RESET "\n\n", message ? message : "Unknown Fault");
|
printk(ANSI_BRIGHT_WHITE "Reason: " ANSI_YELLOW "%s" ANSI_RESET "\n\n", message ? message : "Unknown Fault");
|
||||||
|
|
||||||
if (regs) {
|
if (regs) {
|
||||||
printk(ANSI_BRIGHT_CYAN "CPU Register State (x86_64 AMD64 ABI):" ANSI_RESET "\n");
|
printk(ANSI_BRIGHT_CYAN "CPU Register State:" ANSI_RESET "\n");
|
||||||
printk(" RIP: %016llx CS: %04llx RFLAGS: %016llx\n", regs->rip, regs->cs, regs->rflags);
|
printk(" RIP: %016llx CS: %04llx RFLAGS: %016llx\n", regs->rip, regs->cs, regs->rflags);
|
||||||
printk(" RSP: %016llx SS: %04llx RBP: %016llx\n", regs->rsp, regs->ss, regs->rbp);
|
printk(" RSP: %016llx SS: %04llx RBP: %016llx\n", regs->rsp, regs->ss, regs->rbp);
|
||||||
printk(" RAX: %016llx RBX: %016llx RCX: %016llx RDX: %016llx\n", regs->rax, regs->rbx, regs->rcx, regs->rdx);
|
printk(" RAX: %016llx RBX: %016llx RCX: %016llx RDX: %016llx\n", regs->rax, regs->rbx, regs->rcx, regs->rdx);
|
||||||
@@ -24,7 +24,7 @@ void panic_with_regs(const char* message, const registers_t* regs) {
|
|||||||
printk("\n" ANSI_BRIGHT_YELLOW "Please power off or reset your system." ANSI_RESET "\n");
|
printk("\n" ANSI_BRIGHT_YELLOW "Please power off or reset your system." ANSI_RESET "\n");
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
hlt();
|
arch_halt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -45,10 +45,17 @@ int vprintk(const char* fmt, va_list args) {
|
|||||||
// 1. Output to active TTY console
|
// 1. Output to active TTY console
|
||||||
tty_write(display_ptr, (size_t)len);
|
tty_write(display_ptr, (size_t)len);
|
||||||
|
|
||||||
// 2. Output to COM1 serial port for host debugging
|
// 2. Output to serial console (COM1 on x86, PL011 on AArch64)
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
extern void uart_pl011_putc(char c);
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
uart_pl011_putc(display_ptr[i]);
|
||||||
|
}
|
||||||
|
#else
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
serial_write_char(display_ptr[i]);
|
serial_write_char(display_ptr[i]);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// 3. Store in kernel dmesg ring buffer
|
// 3. Store in kernel dmesg ring buffer
|
||||||
dmesg_append(display_ptr, (size_t)len);
|
dmesg_append(display_ptr, (size_t)len);
|
||||||
|
|||||||
+2
-1
@@ -2,6 +2,7 @@
|
|||||||
#include <kernel/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <mm/kmalloc.h>
|
#include <mm/kmalloc.h>
|
||||||
#include <lib/string.h>
|
#include <lib/string.h>
|
||||||
|
#include <arch/arch.h>
|
||||||
|
|
||||||
static pid_t next_pid = 1;
|
static pid_t next_pid = 1;
|
||||||
static task_t* current_task = NULL;
|
static task_t* current_task = NULL;
|
||||||
@@ -55,7 +56,7 @@ void task_exit(int exit_code) {
|
|||||||
sched_yield();
|
sched_yield();
|
||||||
}
|
}
|
||||||
while (1) {
|
while (1) {
|
||||||
__asm__ volatile("hlt");
|
arch_halt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
#include <kernel/printk.h>
|
#include <kernel/printk.h>
|
||||||
|
|
||||||
#define HEAP_MAGIC 0x53554248 // "SUBH"
|
#define HEAP_MAGIC 0x53554248 // "SUBH"
|
||||||
#define HEAP_INITIAL_PAGES 1024 // 4 MB initial kernel heap
|
#define HEAP_INITIAL_PAGES 4096 // 16 MB initial kernel heap
|
||||||
|
|
||||||
typedef struct heap_block {
|
typedef struct heap_block {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
|
|||||||
@@ -49,18 +49,38 @@ void pmm_init(void* memory_map, uint64_t memory_map_count) {
|
|||||||
|
|
||||||
// Fallback if no E820 usable regions
|
// Fallback if no E820 usable regions
|
||||||
if (usable_memory_bytes == 0 || total_pages == 0) {
|
if (usable_memory_bytes == 0 || total_pages == 0) {
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
uint64_t dram_start = 0x40000000;
|
||||||
|
uint64_t dram_size = 128ULL * 1024 * 1024;
|
||||||
|
uint64_t start_page = dram_start / PMM_PAGE_SIZE;
|
||||||
|
uint64_t count_pages = dram_size / PMM_PAGE_SIZE;
|
||||||
|
|
||||||
|
total_pages = start_page + count_pages;
|
||||||
|
total_memory_bytes = dram_size;
|
||||||
|
usable_memory_bytes = dram_size;
|
||||||
|
|
||||||
|
for (uint64_t p = 0; p < count_pages; p++) {
|
||||||
|
bitmap_clear(page_bitmap, start_page + p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reserve kernel & boot area (0x40000000 - 0x40800000: 8MB / 2048 pages)
|
||||||
|
for (uint64_t p = start_page; p < start_page + 2048; p++) {
|
||||||
|
bitmap_set(page_bitmap, p);
|
||||||
|
}
|
||||||
|
#else
|
||||||
total_pages = 32768; // 128 MB
|
total_pages = 32768; // 128 MB
|
||||||
total_memory_bytes = 128ULL * 1024 * 1024;
|
total_memory_bytes = 128ULL * 1024 * 1024;
|
||||||
usable_memory_bytes = 128ULL * 1024 * 1024;
|
usable_memory_bytes = 128ULL * 1024 * 1024;
|
||||||
for (uint64_t p = 0; p < total_pages; p++) {
|
for (uint64_t p = 0; p < total_pages; p++) {
|
||||||
bitmap_clear(page_bitmap, p);
|
bitmap_clear(page_bitmap, p);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Reserve lower 4 MB (bootloader, page tables, kernel image)
|
// Reserve lower 4 MB (bootloader, page tables, kernel image)
|
||||||
size_t kernel_reserved_pages = (4 * 1024 * 1024) / PMM_PAGE_SIZE; // 1024 pages
|
size_t kernel_reserved_pages = (4 * 1024 * 1024) / PMM_PAGE_SIZE; // 1024 pages
|
||||||
for (size_t p = 0; p < kernel_reserved_pages; p++) {
|
for (size_t p = 0; p < kernel_reserved_pages; p++) {
|
||||||
bitmap_set(page_bitmap, p);
|
bitmap_set(page_bitmap, p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count actual used pages (bits set in bitmap up to total_pages)
|
// Count actual used pages (bits set in bitmap up to total_pages)
|
||||||
|
|||||||
+2
-2
@@ -5,7 +5,7 @@
|
|||||||
#include <lib/string.h>
|
#include <lib/string.h>
|
||||||
#include <lib/printf.h>
|
#include <lib/printf.h>
|
||||||
#include <mm/kmalloc.h>
|
#include <mm/kmalloc.h>
|
||||||
#include <arch/x86_64/pit.h>
|
#include <arch/arch.h>
|
||||||
#include <kernel/printk.h>
|
#include <kernel/printk.h>
|
||||||
|
|
||||||
#define MAX_ARP_ENTRIES 16
|
#define MAX_ARP_ENTRIES 16
|
||||||
@@ -288,7 +288,7 @@ int net_ping(uint32_t target_ip, uint32_t count, uint32_t timeout_ms) {
|
|||||||
if (wait_ticks == 0) wait_ticks = 100;
|
if (wait_ticks == 0) wait_ticks = 100;
|
||||||
|
|
||||||
while (!ping_received && (pit_get_ticks() - t_start < wait_ticks)) {
|
while (!ping_received && (pit_get_ticks() - t_start < wait_ticks)) {
|
||||||
__asm__ volatile ("hlt");
|
arch_halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ping_received && ping_id == p_id && ping_seq == seq) {
|
if (ping_received && ping_id == p_id && ping_seq == seq) {
|
||||||
|
|||||||
Executable
+386
@@ -0,0 +1,386 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
SUB-OS Linux-Style Interactive Kconfig Menuconfig (TUI)
|
||||||
|
Provides a full curses-based terminal configuration UI matching Linux menuconfig.
|
||||||
|
Generates .config and include/config/autoconf.h.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import curses
|
||||||
|
|
||||||
|
CONFIG_FILE = ".config"
|
||||||
|
AUTOCONF_HEADER = "include/config/autoconf.h"
|
||||||
|
|
||||||
|
DEFAULTS = {
|
||||||
|
# Architecture
|
||||||
|
"CONFIG_ARCH": "x86_64",
|
||||||
|
"CONFIG_ARCH_X86_64": True,
|
||||||
|
"CONFIG_ARCH_AARCH64": False,
|
||||||
|
"CONFIG_ARCH_ARMV8I": False,
|
||||||
|
|
||||||
|
# General Setup
|
||||||
|
"CONFIG_SUBOS_HOSTNAME": "sub-os",
|
||||||
|
"CONFIG_SUBOS_VERSION": "0.2.0-lts",
|
||||||
|
"CONFIG_SMP": True,
|
||||||
|
"CONFIG_PREEMPT": True,
|
||||||
|
"CONFIG_OPTIMIZATION": "-O2",
|
||||||
|
|
||||||
|
# Memory Management
|
||||||
|
"CONFIG_MM_PMM": True,
|
||||||
|
"CONFIG_MM_SLAB": True,
|
||||||
|
"CONFIG_MM_VMA": True,
|
||||||
|
|
||||||
|
# Filesystems
|
||||||
|
"CONFIG_FS_VFS": True,
|
||||||
|
"CONFIG_FS_FAT32": True,
|
||||||
|
"CONFIG_FS_EXT2": True,
|
||||||
|
"CONFIG_FS_RAMFS": True,
|
||||||
|
"CONFIG_FS_DEVFS": True,
|
||||||
|
"CONFIG_FS_PROCFS": True,
|
||||||
|
"CONFIG_FS_SYSFS": True,
|
||||||
|
|
||||||
|
# Storage Drivers
|
||||||
|
"CONFIG_DRV_NVME": True,
|
||||||
|
"CONFIG_DRV_AHCI": True,
|
||||||
|
"CONFIG_DRV_ATA": True,
|
||||||
|
"CONFIG_DRV_VIRTIO_BLK": True,
|
||||||
|
"CONFIG_DRV_RAMDISK": True,
|
||||||
|
|
||||||
|
# Network Drivers & Stack
|
||||||
|
"CONFIG_NET_STACK": True,
|
||||||
|
"CONFIG_DRV_E1000": True,
|
||||||
|
"CONFIG_DRV_RTL8139": True,
|
||||||
|
"CONFIG_DRV_VIRTIO_NET": True,
|
||||||
|
"CONFIG_NET_HTTPD": True,
|
||||||
|
"CONFIG_NET_SSHD": True,
|
||||||
|
"CONFIG_NET_FILTER": True,
|
||||||
|
|
||||||
|
# Audio & Display
|
||||||
|
"CONFIG_DRV_SOUND_HDA": True,
|
||||||
|
"CONFIG_DRV_SOUND_AC97": True,
|
||||||
|
"CONFIG_DRV_BOCHS_VBE": True,
|
||||||
|
"CONFIG_DRV_CANVAS_2D": True,
|
||||||
|
|
||||||
|
# Bus, Sensors & Crypto
|
||||||
|
"CONFIG_DRV_USB_XHCI": True,
|
||||||
|
"CONFIG_DRV_HWMON": True,
|
||||||
|
"CONFIG_DRV_VIRTIO_RNG": True,
|
||||||
|
"CONFIG_DRV_PTY": True,
|
||||||
|
|
||||||
|
# Security & Advanced
|
||||||
|
"CONFIG_SECURITY_LSM": True,
|
||||||
|
"CONFIG_SECURITY_KEYRING": True,
|
||||||
|
"CONFIG_BPF_VM": True,
|
||||||
|
"CONFIG_IO_URING": True,
|
||||||
|
"CONFIG_USERLAND_LAZYBOX": True,
|
||||||
|
}
|
||||||
|
|
||||||
|
MENU_STRUCTURE = [
|
||||||
|
{
|
||||||
|
"title": "Target Architecture Selection",
|
||||||
|
"type": "submenu",
|
||||||
|
"items": [
|
||||||
|
{"name": "CONFIG_ARCH_X86_64", "label": "x86_64 (64-Bit AMD64/Intel x86-64)", "type": "radio", "group": "arch", "val": "x86_64"},
|
||||||
|
{"name": "CONFIG_ARCH_AARCH64", "label": "aarch64 (ARMv8-A 64-Bit Cortex/Neoverse)", "type": "radio", "group": "arch", "val": "aarch64"},
|
||||||
|
{"name": "CONFIG_ARCH_ARMV8I", "label": "armv8i (ARMv8 Instruction Set Profile)", "type": "radio", "group": "arch", "val": "armv8i"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "General Kernel Setup",
|
||||||
|
"type": "submenu",
|
||||||
|
"items": [
|
||||||
|
{"name": "CONFIG_SMP", "label": "Symmetric Multi-Processing (SMP) Support", "type": "bool"},
|
||||||
|
{"name": "CONFIG_PREEMPT", "label": "Preemptive Kernel Scheduling Model", "type": "bool"},
|
||||||
|
{"name": "CONFIG_BPF_VM", "label": "In-Kernel eBPF Register Virtual Machine", "type": "bool"},
|
||||||
|
{"name": "CONFIG_IO_URING", "label": "High-Performance io_uring Ring Buffers", "type": "bool"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Virtual File Systems & Storage Drivers",
|
||||||
|
"type": "submenu",
|
||||||
|
"items": [
|
||||||
|
{"name": "CONFIG_FS_FAT32", "label": "FAT32 / VFAT File System Driver", "type": "bool"},
|
||||||
|
{"name": "CONFIG_FS_EXT2", "label": "Second Extended (EXT2) Linux File System", "type": "bool"},
|
||||||
|
{"name": "CONFIG_FS_SYSFS", "label": "Sysfs KObject Virtual Hierarchy (/sys)", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_NVME", "label": "NVM Express (NVMe PCIe SSD) Driver", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_AHCI", "label": "AHCI SATA 6Gb/s SSD/HDD Controller Driver", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_VIRTIO_BLK", "label": "VirtIO Paravirtualized Block Storage (/dev/vda)", "type": "bool"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Network Subsystem & Hardware Adapters",
|
||||||
|
"type": "submenu",
|
||||||
|
"items": [
|
||||||
|
{"name": "CONFIG_NET_STACK", "label": "TCP/IP Network Stack (IPv4, UDP, TCP)", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_E1000", "label": "Intel 82540EM Gigabit Ethernet NIC Driver", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_RTL8139", "label": "Realtek RTL8139 Fast Ethernet NIC Driver", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_VIRTIO_NET", "label": "VirtIO 10-Gigabit Paravirtualized NIC", "type": "bool"},
|
||||||
|
{"name": "CONFIG_NET_FILTER", "label": "NetFilter Stateful Packet Firewall (iptables)", "type": "bool"},
|
||||||
|
{"name": "CONFIG_NET_SSHD", "label": "In-Kernel Secure Shell (SSH) Daemon", "type": "bool"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Device Drivers & Multimedia",
|
||||||
|
"type": "submenu",
|
||||||
|
"items": [
|
||||||
|
{"name": "CONFIG_DRV_CANVAS_2D", "label": "2D TrueColor Rasterizer Canvas Graphics Engine", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_BOCHS_VBE", "label": "Bochs / VBE Dynamic Resolution Display Adapter", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_SOUND_HDA", "label": "Intel High Definition Audio (Azalia HDA) Driver", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_SOUND_AC97", "label": "Analog Devices AC'97 Sound Codec Driver", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_USB_XHCI", "label": "USB 3.0 Extensible Host Controller (xHCI)", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_HWMON", "label": "HWMON CPU CoreTemp & Fan Tachometer Sensors", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_VIRTIO_RNG", "label": "VirtIO True Hardware Random Generator (/dev/hwrng)", "type": "bool"},
|
||||||
|
{"name": "CONFIG_DRV_PTY", "label": "Unix98 Pseudo-Terminal (PTY) Subsystem (/dev/pts)", "type": "bool"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Security, LSM & Keyrings",
|
||||||
|
"type": "submenu",
|
||||||
|
"items": [
|
||||||
|
{"name": "CONFIG_SECURITY_LSM", "label": "Linux Security Module (LSM) Mandatory Access Control", "type": "bool"},
|
||||||
|
{"name": "CONFIG_SECURITY_KEYRING", "label": "X.509 Cryptographic Keyring & Certificates", "type": "bool"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Userland Core & LazyBox",
|
||||||
|
"type": "submenu",
|
||||||
|
"items": [
|
||||||
|
{"name": "CONFIG_USERLAND_LAZYBOX", "label": "LazyBox Multi-Call Userland Utility Suite (70+ Tools)", "type": "bool"},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
def load_config():
|
||||||
|
cfg = dict(DEFAULTS)
|
||||||
|
if os.path.exists(CONFIG_FILE):
|
||||||
|
with open(CONFIG_FILE, "r") as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if not line or line.startswith("#"):
|
||||||
|
continue
|
||||||
|
if "=" in line:
|
||||||
|
k, v = line.split("=", 1)
|
||||||
|
k = k.strip()
|
||||||
|
v = v.strip().strip('"')
|
||||||
|
if v == "y":
|
||||||
|
cfg[k] = True
|
||||||
|
elif v == "n":
|
||||||
|
cfg[k] = False
|
||||||
|
else:
|
||||||
|
cfg[k] = v
|
||||||
|
return cfg
|
||||||
|
|
||||||
|
def save_config(cfg):
|
||||||
|
os.makedirs(os.path.dirname(AUTOCONF_HEADER), exist_ok=True)
|
||||||
|
with open(CONFIG_FILE, "w") as f_cfg, open(AUTOCONF_HEADER, "w") as f_hdr:
|
||||||
|
f_cfg.write("# Automatically generated by SUB-OS Kconfig TUI Configurator\n# Do not edit directly\n\n")
|
||||||
|
f_hdr.write("/* Automatically generated by SUB-OS Kconfig. Do not edit. */\n#ifndef _AUTOCONF_H\n#define _AUTOCONF_H\n\n")
|
||||||
|
|
||||||
|
# Write Architecture
|
||||||
|
arch = cfg.get("CONFIG_ARCH", "x86_64")
|
||||||
|
f_cfg.write(f"CONFIG_ARCH={arch}\n")
|
||||||
|
f_hdr.write(f'#define CONFIG_ARCH "{arch}"\n')
|
||||||
|
|
||||||
|
for k, v in sorted(cfg.items()):
|
||||||
|
if k == "CONFIG_ARCH":
|
||||||
|
continue
|
||||||
|
if isinstance(v, bool):
|
||||||
|
if v:
|
||||||
|
f_cfg.write(f"{k}=y\n")
|
||||||
|
f_hdr.write(f"#define {k} 1\n")
|
||||||
|
else:
|
||||||
|
f_cfg.write(f"# {k} is not set\n")
|
||||||
|
elif isinstance(v, str):
|
||||||
|
f_cfg.write(f'{k}="{v}"\n')
|
||||||
|
f_hdr.write(f'#define {k} "{v}"\n')
|
||||||
|
elif isinstance(v, int):
|
||||||
|
f_cfg.write(f"{k}={v}\n")
|
||||||
|
f_hdr.write(f"#define {k} {v}\n")
|
||||||
|
|
||||||
|
f_hdr.write("\n#endif /* _AUTOCONF_H */\n")
|
||||||
|
|
||||||
|
def run_tui(stdscr):
|
||||||
|
curses.curs_set(0)
|
||||||
|
curses.use_default_colors()
|
||||||
|
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_CYAN) # Header / Bar
|
||||||
|
curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLUE) # Main background
|
||||||
|
curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLUE) # Highlight title
|
||||||
|
curses.init_pair(4, curses.COLOR_BLACK, curses.COLOR_WHITE) # Selected row
|
||||||
|
curses.init_pair(5, curses.COLOR_CYAN, curses.COLOR_BLUE) # Subtext
|
||||||
|
|
||||||
|
cfg = load_config()
|
||||||
|
current_menu = MENU_STRUCTURE
|
||||||
|
menu_stack = []
|
||||||
|
cursor_stack = [0]
|
||||||
|
|
||||||
|
while True:
|
||||||
|
stdscr.bkgd(' ', curses.color_pair(2))
|
||||||
|
stdscr.clear()
|
||||||
|
max_y, max_x = stdscr.getmaxyx()
|
||||||
|
|
||||||
|
# Top Banner
|
||||||
|
header = f" SUB-OS v{cfg.get('CONFIG_SUBOS_VERSION', '0.2.0-lts')} ({cfg.get('CONFIG_ARCH', 'x86_64')}) Linux-Style Kernel Configuration "
|
||||||
|
stdscr.attron(curses.color_pair(1) | curses.A_BOLD)
|
||||||
|
stdscr.addstr(0, 0, header.center(max_x - 1)[:max_x - 1])
|
||||||
|
stdscr.attroff(curses.color_pair(1) | curses.A_BOLD)
|
||||||
|
|
||||||
|
# Subtitle
|
||||||
|
stdscr.attron(curses.color_pair(3) | curses.A_BOLD)
|
||||||
|
title_text = "Main Menu" if not menu_stack else menu_stack[-1]["title"]
|
||||||
|
stdscr.addstr(2, 4, f"-> {title_text}")
|
||||||
|
stdscr.attroff(curses.color_pair(3) | curses.A_BOLD)
|
||||||
|
|
||||||
|
# Instructions
|
||||||
|
stdscr.attron(curses.color_pair(5))
|
||||||
|
stdscr.addstr(3, 4, "Use [UP/DOWN] arrows, [SPACE] to toggle [*], [ENTER] for submenu, [S] to Save, [Q] to Exit")
|
||||||
|
stdscr.attroff(curses.color_pair(5))
|
||||||
|
|
||||||
|
# Items list
|
||||||
|
items = current_menu if not menu_stack else menu_stack[-1]["items"]
|
||||||
|
cur_idx = cursor_stack[-1]
|
||||||
|
if cur_idx >= len(items):
|
||||||
|
cur_idx = len(items) - 1
|
||||||
|
if cur_idx < 0:
|
||||||
|
cur_idx = 0
|
||||||
|
cursor_stack[-1] = cur_idx
|
||||||
|
|
||||||
|
box_top = 5
|
||||||
|
box_height = max_y - 8
|
||||||
|
|
||||||
|
for i, item in enumerate(items):
|
||||||
|
if i >= box_height:
|
||||||
|
break
|
||||||
|
y = box_top + i
|
||||||
|
is_sel = (i == cur_idx)
|
||||||
|
|
||||||
|
if "items" in item: # Submenu
|
||||||
|
display = f" ---> {item['title']}"
|
||||||
|
elif item.get("type") == "bool":
|
||||||
|
val = cfg.get(item["name"], False)
|
||||||
|
mark = "[*]" if val else "[ ]"
|
||||||
|
display = f" {mark} {item['label']}"
|
||||||
|
elif item.get("type") == "radio":
|
||||||
|
group_val = cfg.get("CONFIG_ARCH", "x86_64")
|
||||||
|
mark = "(*)" if group_val == item["val"] else "( )"
|
||||||
|
display = f" {mark} {item['label']}"
|
||||||
|
else:
|
||||||
|
display = f" {item.get('label', item.get('title', ''))}"
|
||||||
|
|
||||||
|
if is_sel:
|
||||||
|
stdscr.attron(curses.color_pair(4) | curses.A_BOLD)
|
||||||
|
stdscr.addstr(y, 4, display.ljust(max_x - 10)[:max_x - 10])
|
||||||
|
stdscr.attroff(curses.color_pair(4) | curses.A_BOLD)
|
||||||
|
else:
|
||||||
|
stdscr.attron(curses.color_pair(2))
|
||||||
|
stdscr.addstr(y, 4, display[:max_x - 10])
|
||||||
|
stdscr.attroff(curses.color_pair(2))
|
||||||
|
|
||||||
|
# Footer Status Bar
|
||||||
|
footer = " <Select> <Exit / Return> <Save Configuration> <Help> "
|
||||||
|
stdscr.attron(curses.color_pair(1))
|
||||||
|
stdscr.addstr(max_y - 1, 0, footer.center(max_x - 1)[:max_x - 1])
|
||||||
|
stdscr.attroff(curses.color_pair(1))
|
||||||
|
|
||||||
|
stdscr.refresh()
|
||||||
|
|
||||||
|
key = stdscr.getch()
|
||||||
|
|
||||||
|
if key in [curses.KEY_UP, ord('k')]:
|
||||||
|
if cursor_stack[-1] > 0:
|
||||||
|
cursor_stack[-1] -= 1
|
||||||
|
elif key in [curses.KEY_DOWN, ord('j')]:
|
||||||
|
if cursor_stack[-1] < len(items) - 1:
|
||||||
|
cursor_stack[-1] += 1
|
||||||
|
elif key in [curses.KEY_ENTER, 10, 13]:
|
||||||
|
sel_item = items[cursor_stack[-1]]
|
||||||
|
if "items" in sel_item:
|
||||||
|
menu_stack.append(sel_item)
|
||||||
|
cursor_stack.append(0)
|
||||||
|
elif sel_item.get("type") == "bool":
|
||||||
|
name = sel_item["name"]
|
||||||
|
cfg[name] = not cfg.get(name, False)
|
||||||
|
elif sel_item.get("type") == "radio":
|
||||||
|
cfg["CONFIG_ARCH"] = sel_item["val"]
|
||||||
|
if sel_item["val"] == "x86_64":
|
||||||
|
cfg["CONFIG_ARCH_X86_64"] = True
|
||||||
|
cfg["CONFIG_ARCH_AARCH64"] = False
|
||||||
|
cfg["CONFIG_ARCH_ARMV8I"] = False
|
||||||
|
elif sel_item["val"] == "aarch64":
|
||||||
|
cfg["CONFIG_ARCH_X86_64"] = False
|
||||||
|
cfg["CONFIG_ARCH_AARCH64"] = True
|
||||||
|
cfg["CONFIG_ARCH_ARMV8I"] = False
|
||||||
|
elif sel_item["val"] == "armv8i":
|
||||||
|
cfg["CONFIG_ARCH_X86_64"] = False
|
||||||
|
cfg["CONFIG_ARCH_AARCH64"] = False
|
||||||
|
cfg["CONFIG_ARCH_ARMV8I"] = True
|
||||||
|
elif key == ord(' '):
|
||||||
|
sel_item = items[cursor_stack[-1]]
|
||||||
|
if sel_item.get("type") == "bool":
|
||||||
|
name = sel_item["name"]
|
||||||
|
cfg[name] = not cfg.get(name, False)
|
||||||
|
elif sel_item.get("type") == "radio":
|
||||||
|
cfg["CONFIG_ARCH"] = sel_item["val"]
|
||||||
|
if sel_item["val"] == "x86_64":
|
||||||
|
cfg["CONFIG_ARCH_X86_64"] = True
|
||||||
|
cfg["CONFIG_ARCH_AARCH64"] = False
|
||||||
|
cfg["CONFIG_ARCH_ARMV8I"] = False
|
||||||
|
elif sel_item["val"] == "aarch64":
|
||||||
|
cfg["CONFIG_ARCH_X86_64"] = False
|
||||||
|
cfg["CONFIG_ARCH_AARCH64"] = True
|
||||||
|
cfg["CONFIG_ARCH_ARMV8I"] = False
|
||||||
|
elif sel_item["val"] == "armv8i":
|
||||||
|
cfg["CONFIG_ARCH_X86_64"] = False
|
||||||
|
cfg["CONFIG_ARCH_AARCH64"] = False
|
||||||
|
cfg["CONFIG_ARCH_ARMV8I"] = True
|
||||||
|
elif key in [ord('s'), ord('S')]:
|
||||||
|
save_config(cfg)
|
||||||
|
stdscr.attron(curses.color_pair(1) | curses.A_BOLD)
|
||||||
|
stdscr.addstr(max_y - 2, 4, f" Saved configuration to {CONFIG_FILE} and {AUTOCONF_HEADER}! Press any key... ")
|
||||||
|
stdscr.attroff(curses.color_pair(1) | curses.A_BOLD)
|
||||||
|
stdscr.refresh()
|
||||||
|
stdscr.getch()
|
||||||
|
elif key in [ord('q'), ord('Q'), 27]: # Esc or Q
|
||||||
|
if menu_stack:
|
||||||
|
menu_stack.pop()
|
||||||
|
cursor_stack.pop()
|
||||||
|
else:
|
||||||
|
save_config(cfg)
|
||||||
|
break
|
||||||
|
|
||||||
|
def defconfig(arch="x86_64"):
|
||||||
|
cfg = dict(DEFAULTS)
|
||||||
|
cfg["CONFIG_ARCH"] = arch
|
||||||
|
if arch == "x86_64":
|
||||||
|
cfg["CONFIG_ARCH_X86_64"] = True
|
||||||
|
cfg["CONFIG_ARCH_AARCH64"] = False
|
||||||
|
cfg["CONFIG_ARCH_ARMV8I"] = False
|
||||||
|
elif arch in ["aarch64", "armv8", "armv8i"]:
|
||||||
|
cfg["CONFIG_ARCH_X86_64"] = False
|
||||||
|
cfg["CONFIG_ARCH_AARCH64"] = True
|
||||||
|
cfg["CONFIG_ARCH_ARMV8I"] = (arch == "armv8i")
|
||||||
|
save_config(cfg)
|
||||||
|
print(f"*** Default configuration for '{arch}' written to {CONFIG_FILE} and {AUTOCONF_HEADER} ***")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
cmd = sys.argv[1]
|
||||||
|
if cmd in ["--defconfig", "defconfig"]:
|
||||||
|
arch = sys.argv[2] if len(sys.argv) > 2 else "x86_64"
|
||||||
|
defconfig(arch)
|
||||||
|
return
|
||||||
|
elif cmd == "--x86_64":
|
||||||
|
defconfig("x86_64")
|
||||||
|
return
|
||||||
|
elif cmd in ["--aarch64", "--armv8", "--armv8i"]:
|
||||||
|
defconfig(cmd.lstrip("-"))
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
curses.wrapper(run_tui)
|
||||||
|
print(f"*** Configuration saved to {CONFIG_FILE} and {AUTOCONF_HEADER} ***")
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -28,9 +28,7 @@
|
|||||||
#include <ipc/ipc.h>
|
#include <ipc/ipc.h>
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <mm/kmalloc.h>
|
#include <mm/kmalloc.h>
|
||||||
#include <arch/x86_64/pit.h>
|
#include <arch/arch.h>
|
||||||
#include <arch/x86_64/cpuid.h>
|
|
||||||
#include <arch/x86_64/io.h>
|
|
||||||
#include <kernel/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <lib/string.h>
|
#include <lib/string.h>
|
||||||
#include <lib/printf.h>
|
#include <lib/printf.h>
|
||||||
@@ -662,7 +660,7 @@ static int applet_mouse(int argc, char** argv) {
|
|||||||
|
|
||||||
static int applet_uname(int argc, char** argv) {
|
static int applet_uname(int argc, char** argv) {
|
||||||
if (argc >= 2 && strcmp(argv[1], "-a") == 0) {
|
if (argc >= 2 && strcmp(argv[1], "-a") == 0) {
|
||||||
printk("SUB-OS sub-node %s #1 SMP PREEMPT Sun Aug 16 2026 x86_64 GNU/LazyBox\n", kernel_get_version());
|
printk("SUB-OS sub-node %s #1 SMP PREEMPT 2026 %s GNU/LazyBox\n", kernel_get_version(), arch_get_name());
|
||||||
} else {
|
} else {
|
||||||
printk("SUB-OS\n");
|
printk("SUB-OS\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
#include <drivers/tty.h>
|
#include <drivers/tty.h>
|
||||||
#include <drivers/keyboard.h>
|
#include <drivers/keyboard.h>
|
||||||
#include <drivers/speaker.h>
|
#include <drivers/speaker.h>
|
||||||
#include <arch/x86_64/pit.h>
|
#include <arch/arch.h>
|
||||||
#include <arch/x86_64/cpuid.h>
|
|
||||||
#include <arch/x86_64/io.h>
|
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <mm/kmalloc.h>
|
#include <mm/kmalloc.h>
|
||||||
#include <kernel/printk.h>
|
#include <kernel/printk.h>
|
||||||
@@ -101,13 +99,17 @@ static void cmd_neofetch(void) {
|
|||||||
secs %= 60;
|
secs %= 60;
|
||||||
mins %= 60;
|
mins %= 60;
|
||||||
|
|
||||||
const cpu_info_t* cpu = cpuid_get_info();
|
|
||||||
|
|
||||||
printk("\n");
|
printk("\n");
|
||||||
printk(ANSI_BRIGHT_CYAN " _____ _ _ ____ " ANSI_BRIGHT_GREEN "OS: " ANSI_RESET "SUB-OS v0.2.0-lts (Modular Monolithic)\n");
|
printk(ANSI_BRIGHT_CYAN " _____ _ _ ____ " ANSI_BRIGHT_GREEN "OS: " ANSI_RESET "SUB-OS v0.2.0-lts (Modular Monolithic)\n");
|
||||||
printk(ANSI_BRIGHT_CYAN " / ____| | | | _ \\ " ANSI_BRIGHT_GREEN "Arch: " ANSI_RESET "x86_64 (64-Bit Long Mode)\n");
|
printk(ANSI_BRIGHT_CYAN " / ____| | | | _ \\ " ANSI_BRIGHT_GREEN "Arch: " ANSI_RESET "%s\n", arch_get_name());
|
||||||
printk(ANSI_BRIGHT_CYAN " | (___ | | | | |_) | " ANSI_BRIGHT_GREEN "Kernel: " ANSI_RESET "Modular Drivers + VFS + Crypto + Net\n");
|
printk(ANSI_BRIGHT_CYAN " | (___ | | | | |_) | " ANSI_BRIGHT_GREEN "Kernel: " ANSI_RESET "Modular Drivers + VFS + Crypto + Net\n");
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
const cpu_info_t* cpu = cpuid_get_info();
|
||||||
printk(ANSI_BRIGHT_CYAN " \\___ \\| | | | _ < " ANSI_BRIGHT_GREEN "CPU: " ANSI_RESET "%s (%s)\n", cpu->model, cpu->vendor);
|
printk(ANSI_BRIGHT_CYAN " \\___ \\| | | | _ < " ANSI_BRIGHT_GREEN "CPU: " ANSI_RESET "%s (%s)\n", cpu->model, cpu->vendor);
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
const aarch64_cpu_info_t* cpu = aarch64_get_cpu_info();
|
||||||
|
printk(ANSI_BRIGHT_CYAN " \\___ \\| | | | _ < " ANSI_BRIGHT_GREEN "CPU: " ANSI_RESET "%s (EL%u)\n", cpu->model_name, cpu->current_el);
|
||||||
|
#endif
|
||||||
printk(ANSI_BRIGHT_CYAN " ____) | |__| | |_) | " ANSI_BRIGHT_GREEN "Memory: " ANSI_RESET "%llu MB / %llu MB (Free: %llu MB)\n", used_mb, total_mb, (free * 4096) / (1024 * 1024));
|
printk(ANSI_BRIGHT_CYAN " ____) | |__| | |_) | " ANSI_BRIGHT_GREEN "Memory: " ANSI_RESET "%llu MB / %llu MB (Free: %llu MB)\n", used_mb, total_mb, (free * 4096) / (1024 * 1024));
|
||||||
printk(ANSI_BRIGHT_CYAN " |_____/ \\____/|____/ " ANSI_BRIGHT_GREEN "Heap: " ANSI_RESET "%llu KB used / %llu KB total\n", heap_get_used_bytes() / 1024, (heap_get_used_bytes() + heap_get_free_bytes()) / 1024);
|
printk(ANSI_BRIGHT_CYAN " |_____/ \\____/|____/ " ANSI_BRIGHT_GREEN "Heap: " ANSI_RESET "%llu KB used / %llu KB total\n", heap_get_used_bytes() / 1024, (heap_get_used_bytes() + heap_get_free_bytes()) / 1024);
|
||||||
printk(ANSI_BRIGHT_CYAN " " ANSI_BRIGHT_GREEN "Uptime: " ANSI_RESET "%02llu:%02llu:%02llu\n", hours, mins, secs);
|
printk(ANSI_BRIGHT_CYAN " " ANSI_BRIGHT_GREEN "Uptime: " ANSI_RESET "%02llu:%02llu:%02llu\n", hours, mins, secs);
|
||||||
|
|||||||
Reference in new issue
Block a user