+75
-2
@@ -1,6 +1,53 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(ksOSKernel LANGUAGES ASM C)
|
project(ksOSKernel LANGUAGES ASM C)
|
||||||
|
|
||||||
|
# --- Locate Swift toolchain with Embedded Swift stdlib ---
|
||||||
|
# Priority: cmake var > env var > auto-detect
|
||||||
|
if(NOT SWIFT_TOOLCHAIN AND DEFINED ENV{SWIFT_TOOLCHAIN})
|
||||||
|
set(SWIFT_TOOLCHAIN "$ENV{SWIFT_TOOLCHAIN}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(SWIFT_TOOLCHAIN)
|
||||||
|
set(SWIFTC "${SWIFT_TOOLCHAIN}/usr/bin/swiftc")
|
||||||
|
set(SWIFT_RESOURCE_DIR "${SWIFT_TOOLCHAIN}/usr/lib/swift")
|
||||||
|
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
|
# Scan for a swift.org toolchain that ships the embedded stdlib.
|
||||||
|
# APPLE is false here (target is Generic), so we check the HOST OS.
|
||||||
|
file(GLOB _tc_candidates
|
||||||
|
"$ENV{HOME}/Library/Developer/Toolchains/*.xctoolchain"
|
||||||
|
"/Library/Developer/Toolchains/*.xctoolchain"
|
||||||
|
)
|
||||||
|
foreach(_tc ${_tc_candidates})
|
||||||
|
if(EXISTS "${_tc}/usr/lib/swift/embedded")
|
||||||
|
set(SWIFTC "${_tc}/usr/bin/swiftc")
|
||||||
|
set(SWIFT_RESOURCE_DIR "${_tc}/usr/lib/swift")
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
else()
|
||||||
|
# Linux: find swiftc in PATH, derive resource dir from its location
|
||||||
|
find_program(_SWIFTC_EXE swiftc)
|
||||||
|
if(_SWIFTC_EXE)
|
||||||
|
get_filename_component(_SWIFTC_BIN "${_SWIFTC_EXE}" DIRECTORY)
|
||||||
|
get_filename_component(_SWIFTC_USR "${_SWIFTC_BIN}" DIRECTORY)
|
||||||
|
if(EXISTS "${_SWIFTC_USR}/lib/swift/embedded")
|
||||||
|
set(SWIFTC "${_SWIFTC_EXE}")
|
||||||
|
set(SWIFT_RESOURCE_DIR "${_SWIFTC_USR}/lib/swift")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT SWIFTC OR NOT EXISTS "${SWIFT_RESOURCE_DIR}/embedded")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Swift toolchain with Embedded Swift not found.\n"
|
||||||
|
"Install a swift.org toolchain and pass -DSWIFT_TOOLCHAIN=<root> "
|
||||||
|
"or set the SWIFT_TOOLCHAIN env var.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Swift: ${SWIFTC}")
|
||||||
|
message(STATUS "Swift resource dir: ${SWIFT_RESOURCE_DIR}")
|
||||||
|
|
||||||
|
# --- Build ---
|
||||||
add_compile_options(-ffreestanding -nostdlib -O0 -g)
|
add_compile_options(-ffreestanding -nostdlib -O0 -g)
|
||||||
|
|
||||||
set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld)
|
set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld)
|
||||||
@@ -11,8 +58,34 @@ add_link_options(
|
|||||||
-Wl,-T,${LINKER_SCRIPT}
|
-Wl,-T,${LINKER_SCRIPT}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(kernel.elf Source/entry.S)
|
set(SWIFT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Source/kernel.swift)
|
||||||
|
set(SWIFT_OBJ ${CMAKE_CURRENT_BINARY_DIR}/kernel_swift.o)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${SWIFT_OBJ}
|
||||||
|
COMMAND ${SWIFTC}
|
||||||
|
-target aarch64-none-none-elf
|
||||||
|
-enable-experimental-feature Embedded
|
||||||
|
-parse-as-library
|
||||||
|
-wmo
|
||||||
|
-O
|
||||||
|
-Xcc -fno-stack-protector
|
||||||
|
-resource-dir ${SWIFT_RESOURCE_DIR}
|
||||||
|
-c ${SWIFT_SOURCES}
|
||||||
|
-o ${SWIFT_OBJ}
|
||||||
|
COMMAND ${LLVM_OBJCOPY} --remove-section=.swift_modhash ${SWIFT_OBJ}
|
||||||
|
DEPENDS ${SWIFT_SOURCES}
|
||||||
|
COMMENT "Compiling Swift kernel"
|
||||||
|
)
|
||||||
|
|
||||||
|
set_source_files_properties(${SWIFT_OBJ} PROPERTIES
|
||||||
|
EXTERNAL_OBJECT TRUE
|
||||||
|
GENERATED TRUE
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(kernel.elf Source/entry.S Source/stubs.c ${SWIFT_OBJ})
|
||||||
|
|
||||||
add_custom_command(TARGET kernel.elf POST_BUILD
|
add_custom_command(TARGET kernel.elf POST_BUILD
|
||||||
COMMAND ${LLVM_OBJCOPY} -O binary kernel.elf kernel.bin
|
COMMAND ${LLVM_OBJCOPY} -O binary kernel.elf kernel.bin
|
||||||
COMMENT "kernel.elf -> kernel.bin"
|
COMMENT "kernel.elf -> kernel.bin"
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-56
@@ -2,59 +2,6 @@
|
|||||||
.global _start
|
.global _start
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
add x1, x0, #64
|
bl kmain
|
||||||
ldr x2, [x1] // base
|
.hang:
|
||||||
ldr x3, [x1, #16] // width
|
b .hang
|
||||||
ldr x4, [x1, #24] // height
|
|
||||||
|
|
||||||
mul x5, x3, x4
|
|
||||||
mov x7, #5
|
|
||||||
udiv x10, x5, x7 // stripe size
|
|
||||||
|
|
||||||
// 0x00RRGGBB
|
|
||||||
// lblue: 5B CE FA
|
|
||||||
mov w11, #0xCEFA
|
|
||||||
movk w11, #0x5B, lsl #16
|
|
||||||
|
|
||||||
// pink: F5 A7 B8
|
|
||||||
mov w12, #0xA7B8
|
|
||||||
movk w12, #0xF5, lsl #16
|
|
||||||
|
|
||||||
// white: FF FF FF
|
|
||||||
mov w13, #0xFFFF
|
|
||||||
movk w13, #0xFF, lsl #16
|
|
||||||
|
|
||||||
mov x14, #0 // pixels in curr stripe
|
|
||||||
mov x15, #0 // stripe index
|
|
||||||
|
|
||||||
fill_loop:
|
|
||||||
cbz x5, done
|
|
||||||
|
|
||||||
cmp x15, #0
|
|
||||||
b.eq set_blue
|
|
||||||
cmp x15, #1
|
|
||||||
b.eq set_pink
|
|
||||||
cmp x15, #2
|
|
||||||
b.eq set_white
|
|
||||||
cmp x15, #3
|
|
||||||
b.eq set_pink
|
|
||||||
b set_blue
|
|
||||||
|
|
||||||
set_blue: mov w6, w11; b draw
|
|
||||||
set_pink: mov w6, w12; b draw
|
|
||||||
set_white: mov w6, w13
|
|
||||||
|
|
||||||
draw:
|
|
||||||
str w6, [x2], #4
|
|
||||||
sub x5, x5, #1
|
|
||||||
add x14, x14, #1
|
|
||||||
|
|
||||||
cmp x14, x10
|
|
||||||
b.lt fill_loop
|
|
||||||
|
|
||||||
mov x14, #0
|
|
||||||
add x15, x15, #1
|
|
||||||
b fill_loop
|
|
||||||
|
|
||||||
done:
|
|
||||||
b done
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
@_cdecl("kmain")
|
||||||
|
public func kernelMain(_ bootInfo: UInt) {
|
||||||
|
// Bootinfo offsets: fb starts at 64, then base(8), baseSize(8), width(8), height(8)
|
||||||
|
let fbBase = UnsafePointer<UInt>(bitPattern: bootInfo &+ 64)!.pointee
|
||||||
|
let width = UnsafePointer<UInt64>(bitPattern: bootInfo &+ 80)!.pointee
|
||||||
|
let height = UnsafePointer<UInt64>(bitPattern: bootInfo &+ 88)!.pointee
|
||||||
|
|
||||||
|
let pixels = UnsafeMutablePointer<UInt32>(bitPattern: fbBase)!
|
||||||
|
let total = Int(width) &* Int(height)
|
||||||
|
let stripe = total / 5
|
||||||
|
|
||||||
|
var i = 0
|
||||||
|
while i < total {
|
||||||
|
let s = i / stripe
|
||||||
|
let color: UInt32
|
||||||
|
if s == 0 || s >= 4 { color = 0x5BCEFA }
|
||||||
|
else if s == 2 { color = 0xFFFFFF }
|
||||||
|
else { color = 0xF5A7B8 }
|
||||||
|
pixels[i] = color
|
||||||
|
i &+= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void* memmove(void* dest, const void* src, unsigned long n) {
|
||||||
|
unsigned char* d = (unsigned char*)dest;
|
||||||
|
const unsigned char* s = (const unsigned char*)src;
|
||||||
|
if (d < s) {
|
||||||
|
while (n--) *d++ = *s++;
|
||||||
|
} else {
|
||||||
|
d += n; s += n;
|
||||||
|
while (n--) *--d = *--s;
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memcpy(void* dest, const void* src, unsigned long n) {
|
||||||
|
return memmove(dest, src, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memset(void* dest, int c, unsigned long n) {
|
||||||
|
unsigned char* d = (unsigned char*)dest;
|
||||||
|
while (n--) *d++ = (unsigned char)c;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack protection
|
||||||
|
long __stack_chk_guard = (long)0xDEADBEEFCAFEBABEULL;
|
||||||
|
void __stack_chk_fail(void) { while (1); }
|
||||||
|
|
||||||
|
// Swift embedded uses putchar for print(); stub so it links but does nothing
|
||||||
|
int putchar(int c) { return c; }
|
||||||
|
|
||||||
|
// Swift runtime allocator stubs — should never be called in embedded mode
|
||||||
|
int posix_memalign(void** ptr, unsigned long align, unsigned long size) {
|
||||||
|
(void)ptr; (void)align; (void)size;
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void* ptr) { (void)ptr; }
|
||||||
@@ -3,14 +3,26 @@ set(CMAKE_SYSTEM_PROCESSOR aarch64)
|
|||||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||||
|
|
||||||
if(NOT LLVM_BIN)
|
if(NOT LLVM_BIN)
|
||||||
execute_process(COMMAND brew --prefix llvm OUTPUT_VARIABLE LLVM_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
|
if(APPLE)
|
||||||
set(LLVM_BIN "${LLVM_PREFIX}/bin")
|
execute_process(
|
||||||
|
COMMAND brew --prefix llvm
|
||||||
|
OUTPUT_VARIABLE LLVM_PREFIX
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
set(LLVM_BIN "${LLVM_PREFIX}/bin")
|
||||||
|
else()
|
||||||
|
find_program(_CLANG clang)
|
||||||
|
if(NOT _CLANG)
|
||||||
|
message(FATAL_ERROR "clang not found.")
|
||||||
|
endif()
|
||||||
|
get_filename_component(LLVM_BIN "${_CLANG}" DIRECTORY)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_C_COMPILER "${LLVM_BIN}/clang")
|
set(CMAKE_C_COMPILER "${LLVM_BIN}/clang")
|
||||||
set(CMAKE_ASM_COMPILER "${LLVM_BIN}/clang")
|
set(CMAKE_ASM_COMPILER "${LLVM_BIN}/clang")
|
||||||
set(LLVM_OBJCOPY "${LLVM_BIN}/llvm-objcopy")
|
set(LLVM_OBJCOPY "${LLVM_BIN}/llvm-objcopy")
|
||||||
|
|
||||||
set(TARGET_TRIPLE aarch64-none-elf)
|
set(TARGET_TRIPLE aarch64-none-elf)
|
||||||
set(CMAKE_C_COMPILER_TARGET ${TARGET_TRIPLE})
|
set(CMAKE_C_COMPILER_TARGET ${TARGET_TRIPLE})
|
||||||
set(CMAKE_ASM_COMPILER_TARGET ${TARGET_TRIPLE})
|
set(CMAKE_ASM_COMPILER_TARGET ${TARGET_TRIPLE})
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = 0;
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
*(.text.boot)
|
||||||
|
*(.text*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : { *(.rodata*) }
|
||||||
|
.data : { *(.data*) }
|
||||||
|
.bss : { *(.bss*) *(COMMON) }
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,29 +3,31 @@ set quiet := true
|
|||||||
OS_NAME := os()
|
OS_NAME := os()
|
||||||
ARCH_NAME := arch()
|
ARCH_NAME := arch()
|
||||||
|
|
||||||
OVMF_ARM := if OS_NAME == "macos" {
|
HB_PREFIX := if ARCH_NAME == "aarch64" { "/opt/homebrew" } else { "/usr/local" }
|
||||||
if ARCH_NAME == "aarch64" {
|
export PATH := HB_PREFIX + "/bin:" + HB_PREFIX + "/sbin:" + env_var("PATH")
|
||||||
"/opt/homebrew/share/qemu/edk2-aarch64-code.fd"
|
|
||||||
} else {
|
|
||||||
"/usr/local/share/qemu/edk2-aarch64-code.fd"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
"/usr/share/edk2/aarch64/QEMU_EFI.fd"
|
|
||||||
}
|
|
||||||
|
|
||||||
ACCEL := if OS_NAME == "macos" {
|
ACCEL := if OS_NAME == "macos" {
|
||||||
if ARCH_NAME == "aarch64" { "-accel hvf" } else { "" }
|
if ARCH_NAME == "aarch64" { "-accel hvf" } else { "" }
|
||||||
} else {
|
} else {
|
||||||
""
|
if ARCH_NAME == "aarch64" { "-accel kvm" } else { "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
HB_PREFIX := if ARCH_NAME == "aarch64" { "/opt/homebrew" } else { "/usr/local" }
|
CPU := if ARCH_NAME == "aarch64" { "host" } else { "max" }
|
||||||
export PATH := HB_PREFIX + "/bin:" + HB_PREFIX + "/sbin:" + env_var("PATH")
|
|
||||||
|
OVMF_ARM := if OS_NAME == "macos" {
|
||||||
|
HB_PREFIX + "/share/qemu/edk2-aarch64-code.fd"
|
||||||
|
} else {
|
||||||
|
env_var_or_default("OVMF_PATH", "/usr/share/edk2/aarch64/QEMU_EFI.fd")
|
||||||
|
}
|
||||||
|
|
||||||
|
DISPLAY_FLAGS := if OS_NAME == "macos" {
|
||||||
|
"-display cocoa,show-cursor=on"
|
||||||
|
} else {
|
||||||
|
env_var_or_default("QEMU_DISPLAY", "-display sdl")
|
||||||
|
}
|
||||||
|
|
||||||
ACCEL_INFO := if ACCEL == "" { "none (TCG)" } else { ACCEL }
|
ACCEL_INFO := if ACCEL == "" { "none (TCG)" } else { ACCEL }
|
||||||
|
|
||||||
CPU := if ARCH_NAME == "aarch64" { "host" } else { "max" }
|
|
||||||
|
|
||||||
export BUILD_DIR := justfile_directory() + "/.build"
|
export BUILD_DIR := justfile_directory() + "/.build"
|
||||||
export TEMP_DIR := BUILD_DIR + "/temp"
|
export TEMP_DIR := BUILD_DIR + "/temp"
|
||||||
export BOOT_BIN := BUILD_DIR + "/Bootloader/BOOTAA64.EFI"
|
export BOOT_BIN := BUILD_DIR + "/Bootloader/BOOTAA64.EFI"
|
||||||
@@ -56,18 +58,18 @@ _prep:
|
|||||||
@mcopy -i {{IMG_FILE}} {{BUILD_DIR}}/Kernel/ksOSKernel.bin ::/ksOSKernel.bin
|
@mcopy -i {{IMG_FILE}} {{BUILD_DIR}}/Kernel/ksOSKernel.bin ::/ksOSKernel.bin
|
||||||
|
|
||||||
@run: _image
|
@run: _image
|
||||||
@echo "🚀 Launching..."
|
@echo "🚀 Launching (accel: {{ACCEL_INFO}})..."
|
||||||
qemu-system-aarch64 {{ACCEL}} \
|
qemu-system-aarch64 {{ACCEL}} \
|
||||||
-machine virt,acpi=off \
|
-machine virt,acpi=off \
|
||||||
-cpu {{CPU}} \
|
-cpu {{CPU}} \
|
||||||
-m 512M \
|
-m 512M \
|
||||||
-device ramfb \
|
-device ramfb \
|
||||||
-display cocoa,show-cursor=on \
|
{{DISPLAY_FLAGS}} \
|
||||||
-drive if=pflash,format=raw,readonly=on,file={{OVMF_ARM}} \
|
-drive if=pflash,format=raw,readonly=on,file={{OVMF_ARM}} \
|
||||||
-drive file={{IMG_FILE}},format=raw,if=none,id=hd0 \
|
-drive file={{IMG_FILE}},format=raw,if=none,id=hd0 \
|
||||||
-device virtio-blk-device,drive=hd0 \
|
-device virtio-blk-device,drive=hd0 \
|
||||||
-serial stdio \
|
-serial stdio \
|
||||||
-monitor telnet:127.0.0.1:5555,server,nowait
|
-monitor telnet:127.0.0.1:5555,server,nowait
|
||||||
|
|
||||||
@clean:
|
@clean:
|
||||||
rm -rf {{BUILD_DIR}}
|
rm -rf {{BUILD_DIR}}
|
||||||
|
|||||||
Reference in New Issue
Block a user