diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index ac39306..4134daa 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -1,10 +1,53 @@ cmake_minimum_required(VERSION 3.10) project(ksOSKernel LANGUAGES ASM C) -set(SWIFT_TOOLCHAIN "$ENV{HOME}/Library/Developer/Toolchains/swift-6.2.3-RELEASE.xctoolchain") -set(SWIFTC "${SWIFT_TOOLCHAIN}/usr/bin/swiftc") -set(SWIFT_RESOURCE_DIR "${SWIFT_TOOLCHAIN}/usr/lib/swift") +# --- 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= " + "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) set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld) @@ -16,7 +59,7 @@ add_link_options( ) set(SWIFT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Source/kernel.swift) -set(SWIFT_OBJ ${CMAKE_CURRENT_BINARY_DIR}/kernel_swift.o) +set(SWIFT_OBJ ${CMAKE_CURRENT_BINARY_DIR}/kernel_swift.o) add_custom_command( OUTPUT ${SWIFT_OBJ} @@ -30,6 +73,7 @@ add_custom_command( -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" ) diff --git a/Kernel/cmake/aarch64-bare.cmake b/Kernel/cmake/aarch64-bare.cmake index 4494c10..8c0c1d2 100644 --- a/Kernel/cmake/aarch64-bare.cmake +++ b/Kernel/cmake/aarch64-bare.cmake @@ -3,14 +3,26 @@ set(CMAKE_SYSTEM_PROCESSOR aarch64) set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) if(NOT LLVM_BIN) - execute_process(COMMAND brew --prefix llvm OUTPUT_VARIABLE LLVM_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE) - set(LLVM_BIN "${LLVM_PREFIX}/bin") + if(APPLE) + 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. Install: apt install clang lld / dnf install clang lld") + endif() + get_filename_component(LLVM_BIN "${_CLANG}" DIRECTORY) + endif() endif() -set(CMAKE_C_COMPILER "${LLVM_BIN}/clang") +set(CMAKE_C_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(CMAKE_C_COMPILER_TARGET ${TARGET_TRIPLE}) -set(CMAKE_ASM_COMPILER_TARGET ${TARGET_TRIPLE}) \ No newline at end of file +set(CMAKE_C_COMPILER_TARGET ${TARGET_TRIPLE}) +set(CMAKE_ASM_COMPILER_TARGET ${TARGET_TRIPLE}) diff --git a/Kernel/linker.ld b/Kernel/linker.ld index 9247fbe..22e97ea 100644 --- a/Kernel/linker.ld +++ b/Kernel/linker.ld @@ -11,4 +11,5 @@ SECTIONS { .rodata : { *(.rodata*) } .data : { *(.data*) } .bss : { *(.bss*) *(COMMON) } + } diff --git a/justfile b/justfile index 207c749..1120d3b 100644 --- a/justfile +++ b/justfile @@ -3,28 +3,38 @@ set quiet := true OS_NAME := os() ARCH_NAME := arch() -OVMF_ARM := if OS_NAME == "macos" { - if ARCH_NAME == "aarch64" { - "/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" { - if ARCH_NAME == "aarch64" { "-accel hvf" } else { "" } -} else { - "" -} - +# Homebrew prefix (arm64 mac vs x86_64 mac) HB_PREFIX := if ARCH_NAME == "aarch64" { "/opt/homebrew" } else { "/usr/local" } export PATH := HB_PREFIX + "/bin:" + HB_PREFIX + "/sbin:" + env_var("PATH") -ACCEL_INFO := if ACCEL == "" { "none (TCG)" } else { ACCEL } +# QEMU acceleration: HVF on Apple Silicon, KVM on aarch64 Linux, TCG otherwise +ACCEL := if OS_NAME == "macos" { + if ARCH_NAME == "aarch64" { "-accel hvf" } else { "" } +} else { + if ARCH_NAME == "aarch64" { "-accel kvm" } else { "" } +} -CPU := if ARCH_NAME == "aarch64" { "host" } else { "max" } +# CPU type: "host" with hardware virt, "max" for cross-arch TCG +CPU := if ARCH_NAME == "aarch64" { "host" } else { "max" } + +# AArch64 UEFI firmware +# Linux default is Fedora/RHEL path; override via OVMF_PATH env var: +# Debian/Ubuntu: /usr/share/qemu-efi-aarch64/QEMU_EFI.fd +# Arch: /usr/share/edk2-armvirt/aarch64/QEMU_CODE.fd +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 backend +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 } export BUILD_DIR := justfile_directory() + "/.build" export TEMP_DIR := BUILD_DIR + "/temp" @@ -56,18 +66,18 @@ _prep: @mcopy -i {{IMG_FILE}} {{BUILD_DIR}}/Kernel/ksOSKernel.bin ::/ksOSKernel.bin @run: _image - @echo "🚀 Launching..." + @echo "🚀 Launching (accel: {{ACCEL_INFO}})..." qemu-system-aarch64 {{ACCEL}} \ -machine virt,acpi=off \ -cpu {{CPU}} \ -m 512M \ -device ramfb \ - -display cocoa,show-cursor=on \ + {{DISPLAY_FLAGS}} \ -drive if=pflash,format=raw,readonly=on,file={{OVMF_ARM}} \ -drive file={{IMG_FILE}},format=raw,if=none,id=hd0 \ -device virtio-blk-device,drive=hd0 \ -serial stdio \ -monitor telnet:127.0.0.1:5555,server,nowait - + @clean: - rm -rf {{BUILD_DIR}} \ No newline at end of file + rm -rf {{BUILD_DIR}}