From e63983c95d40e8eb065e8f80c3ab205b33304f25 Mon Sep 17 00:00:00 2001 From: Karina Date: Sat, 31 Jan 2026 01:40:10 +0400 Subject: [PATCH] full refactor in kernel/: now its apple-styled; im so fucking tired --- bootloader/src/main.c | 16 +- common/bootinfo.h | 40 +-- common/hot_header.h | 38 +-- kernel/CMakeLists.txt | 16 +- .../{data/font8x16.c => inc/Data/VGAFont.h} | 8 +- kernel/{data => inc/Data}/cats.h | 0 kernel/{data => inc/Data}/logo.h | 11 +- kernel/inc/FS/CPIO.h | 9 + kernel/inc/FS/VFS.h | 42 +++ kernel/inc/IO/IOConsole.h | 36 +++ kernel/inc/IO/IOGraphics.h | 50 +++ kernel/inc/IO/IOKeyboard.h | 19 ++ kernel/inc/IO/IOSerial.h | 8 + kernel/inc/IO/IOTimer.h | 9 + kernel/inc/{mm/heap.h => MM/Heap.h} | 18 +- .../inc/{core/hot.h => OS/Exec/HOTLoader.h} | 4 +- .../inc/{core/loader.h => OS/Exec/OSLoader.h} | 2 +- kernel/inc/OS/OSPanic.h | 8 + kernel/inc/OS/OSScheduler.h | 44 +++ kernel/inc/OS/Services/OSServiceIO.h | 8 + .../mem.h => OS/Services/OSServiceMemory.h} | 2 +- kernel/inc/OS/Services/OSServiceProcess.h | 10 + kernel/inc/VM/Heap.h | 28 ++ kernel/inc/VM/PMM.h | 49 +++ kernel/inc/{mm/vmm.h => VM/VMM.h} | 12 +- kernel/inc/arch/x86_64/GDT.h | 45 +++ kernel/inc/arch/x86_64/IDT.h | 22 ++ kernel/inc/arch/x86_64/IO.h | 44 +++ kernel/inc/arch/x86_64/OSCPU.h | 42 +++ kernel/inc/arch/x86_64/{pic.h => PIC.h} | 2 +- kernel/inc/arch/x86_64/cpuinfo.h | 40 --- kernel/inc/arch/x86_64/gdt.h | 42 --- kernel/inc/arch/x86_64/idt.h | 22 -- kernel/inc/arch/x86_64/io.h | 39 --- kernel/inc/arch/x86_64/syscall.h | 22 +- kernel/inc/core/panic.h | 10 - kernel/inc/core/scheduler.h | 42 --- kernel/inc/core/string.h | 10 - kernel/inc/drivers/console.h | 22 -- kernel/inc/drivers/font.h | 4 - kernel/inc/drivers/keyboard.h | 16 - kernel/inc/drivers/serial.h | 8 - kernel/inc/drivers/shitgui.h | 33 -- kernel/inc/drivers/timer.h | 10 - kernel/inc/fs/cpio.h | 8 - kernel/inc/fs/vfs.h | 38 --- kernel/inc/{core/math.h => lib/Math.h} | 2 +- kernel/inc/{core/rand.h => lib/Rand.h} | 4 +- kernel/inc/{core/splash.h => lib/Splash.h} | 4 +- kernel/inc/lib/String.h | 12 + kernel/inc/mm/memory.h | 8 - kernel/inc/mm/pmm.h | 22 -- kernel/inc/shell/builtins.h | 18 +- kernel/inc/shell/dbgcmd.h | 2 +- kernel/inc/shell/ksh.h | 1 - kernel/inc/syscalls/io.h | 8 - kernel/inc/syscalls/proc.h | 10 - kernel/inc/types.h | 61 +--- kernel/src/FS/CPIO.c | 122 +++++++ kernel/src/FS/VFS.c | 53 +++ kernel/src/IO/IOConsole.c | 276 ++++++++++++++++ kernel/src/IO/IOGraphics.c | 82 +++++ .../{drivers/keyboard.c => IO/IOKeyboard.c} | 35 +- kernel/src/IO/IOSerial.c | 33 ++ kernel/src/IO/IOTimer.c | 36 +++ kernel/src/OS/Exec/HOTLoader.c | 48 +++ kernel/src/OS/Exec/OSLoader.c | 78 +++++ kernel/src/OS/OSPanic.c | 168 ++++++++++ kernel/src/OS/OSScheduler.c | 146 +++++++++ kernel/src/OS/Services/OSServiceIO.c | 27 ++ kernel/src/OS/Services/OSServiceMemory.c | 30 ++ kernel/src/OS/Services/OSServiceProcess.c | 24 ++ kernel/src/VM/Heap.c | 103 ++++++ kernel/src/VM/PMM.c | 115 +++++++ kernel/src/VM/VMM.c | 177 ++++++++++ kernel/src/arch/x86_64/GDT.c | 77 +++++ kernel/src/arch/x86_64/IDT.c | 82 +++++ kernel/src/arch/x86_64/OSCPU.c | 72 +++++ kernel/src/arch/x86_64/PIC.c | 34 ++ kernel/src/arch/x86_64/cpuinfo.c | 72 ----- kernel/src/arch/x86_64/gdt.c | 78 ----- kernel/src/arch/x86_64/idt.c | 82 ----- kernel/src/arch/x86_64/interrupts.c | 60 ++-- kernel/src/arch/x86_64/pic.c | 34 -- kernel/src/arch/x86_64/syscall.c | 66 ++-- kernel/src/core/hot.c | 49 --- kernel/src/core/loader.c | 67 ---- kernel/src/core/panic.c | 168 ---------- kernel/src/core/rand.c | 45 --- kernel/src/core/scheduler.c | 147 --------- kernel/src/core/splash.c | 16 - kernel/src/drivers/console.c | 305 ------------------ kernel/src/drivers/serial.c | 31 -- kernel/src/drivers/shitgui.c | 85 ----- kernel/src/drivers/timer.c | 40 --- kernel/src/fs/cpio.c | 113 ------- kernel/src/fs/vfs.c | 41 --- kernel/src/kmain.c | 143 ++++---- kernel/src/lib/Rand.c | 45 +++ kernel/src/lib/Splash.c | 18 ++ kernel/src/{core/string.c => lib/String.c} | 35 +- kernel/src/mm/heap.c | 105 ------ kernel/src/mm/memory.c | 32 -- kernel/src/mm/pmm.c | 101 ------ kernel/src/mm/vmm.c | 174 ---------- kernel/src/shell/builtins.c | 148 ++++----- kernel/src/shell/dbgcmd.c | 4 +- kernel/src/shell/ksh.c | 71 ++-- kernel/src/syscalls/io.c | 27 -- kernel/src/syscalls/mem.c | 32 -- kernel/src/syscalls/proc.c | 26 -- userspace/debug/src/main.c | 20 +- userspace/init/src/main.c | 2 +- userspace/libterm/inc/malloc.h | 8 +- userspace/libterm/inc/process.h | 4 +- userspace/libterm/inc/stdio.h | 4 +- userspace/libterm/inc/string.h | 12 +- userspace/libterm/inc/types.h | 22 +- userspace/libterm/src/malloc.c | 22 +- userspace/libterm/src/process.c | 8 +- userspace/libterm/src/stdio.c | 28 +- userspace/libterm/src/string.c | 26 +- userspace/termosh/src/handlers/spawn.c | 2 +- 123 files changed, 2822 insertions(+), 2774 deletions(-) rename kernel/{data/font8x16.c => inc/Data/VGAFont.h} (99%) rename kernel/{data => inc/Data}/cats.h (100%) rename kernel/{data => inc/Data}/logo.h (99%) create mode 100644 kernel/inc/FS/CPIO.h create mode 100644 kernel/inc/FS/VFS.h create mode 100644 kernel/inc/IO/IOConsole.h create mode 100644 kernel/inc/IO/IOGraphics.h create mode 100644 kernel/inc/IO/IOKeyboard.h create mode 100644 kernel/inc/IO/IOSerial.h create mode 100644 kernel/inc/IO/IOTimer.h rename kernel/inc/{mm/heap.h => MM/Heap.h} (56%) rename kernel/inc/{core/hot.h => OS/Exec/HOTLoader.h} (59%) rename kernel/inc/{core/loader.h => OS/Exec/OSLoader.h} (62%) create mode 100644 kernel/inc/OS/OSPanic.h create mode 100644 kernel/inc/OS/OSScheduler.h create mode 100644 kernel/inc/OS/Services/OSServiceIO.h rename kernel/inc/{syscalls/mem.h => OS/Services/OSServiceMemory.h} (74%) create mode 100644 kernel/inc/OS/Services/OSServiceProcess.h create mode 100644 kernel/inc/VM/Heap.h create mode 100644 kernel/inc/VM/PMM.h rename kernel/inc/{mm/vmm.h => VM/VMM.h} (84%) create mode 100644 kernel/inc/arch/x86_64/GDT.h create mode 100644 kernel/inc/arch/x86_64/IDT.h create mode 100644 kernel/inc/arch/x86_64/IO.h create mode 100644 kernel/inc/arch/x86_64/OSCPU.h rename kernel/inc/arch/x86_64/{pic.h => PIC.h} (71%) delete mode 100644 kernel/inc/arch/x86_64/cpuinfo.h delete mode 100644 kernel/inc/arch/x86_64/gdt.h delete mode 100644 kernel/inc/arch/x86_64/idt.h delete mode 100644 kernel/inc/arch/x86_64/io.h delete mode 100644 kernel/inc/core/panic.h delete mode 100644 kernel/inc/core/scheduler.h delete mode 100644 kernel/inc/core/string.h delete mode 100644 kernel/inc/drivers/console.h delete mode 100644 kernel/inc/drivers/font.h delete mode 100644 kernel/inc/drivers/keyboard.h delete mode 100644 kernel/inc/drivers/serial.h delete mode 100644 kernel/inc/drivers/shitgui.h delete mode 100644 kernel/inc/drivers/timer.h delete mode 100644 kernel/inc/fs/cpio.h delete mode 100644 kernel/inc/fs/vfs.h rename kernel/inc/{core/math.h => lib/Math.h} (88%) rename kernel/inc/{core/rand.h => lib/Rand.h} (75%) rename kernel/inc/{core/splash.h => lib/Splash.h} (51%) create mode 100644 kernel/inc/lib/String.h delete mode 100644 kernel/inc/mm/memory.h delete mode 100644 kernel/inc/mm/pmm.h delete mode 100644 kernel/inc/syscalls/io.h delete mode 100644 kernel/inc/syscalls/proc.h create mode 100644 kernel/src/FS/CPIO.c create mode 100644 kernel/src/FS/VFS.c create mode 100644 kernel/src/IO/IOConsole.c create mode 100644 kernel/src/IO/IOGraphics.c rename kernel/src/{drivers/keyboard.c => IO/IOKeyboard.c} (75%) create mode 100644 kernel/src/IO/IOSerial.c create mode 100644 kernel/src/IO/IOTimer.c create mode 100644 kernel/src/OS/Exec/HOTLoader.c create mode 100644 kernel/src/OS/Exec/OSLoader.c create mode 100644 kernel/src/OS/OSPanic.c create mode 100644 kernel/src/OS/OSScheduler.c create mode 100644 kernel/src/OS/Services/OSServiceIO.c create mode 100644 kernel/src/OS/Services/OSServiceMemory.c create mode 100644 kernel/src/OS/Services/OSServiceProcess.c create mode 100644 kernel/src/VM/Heap.c create mode 100644 kernel/src/VM/PMM.c create mode 100644 kernel/src/VM/VMM.c create mode 100644 kernel/src/arch/x86_64/GDT.c create mode 100644 kernel/src/arch/x86_64/IDT.c create mode 100644 kernel/src/arch/x86_64/OSCPU.c create mode 100644 kernel/src/arch/x86_64/PIC.c delete mode 100644 kernel/src/arch/x86_64/cpuinfo.c delete mode 100644 kernel/src/arch/x86_64/gdt.c delete mode 100644 kernel/src/arch/x86_64/idt.c delete mode 100644 kernel/src/arch/x86_64/pic.c delete mode 100644 kernel/src/core/hot.c delete mode 100644 kernel/src/core/loader.c delete mode 100644 kernel/src/core/panic.c delete mode 100644 kernel/src/core/rand.c delete mode 100644 kernel/src/core/scheduler.c delete mode 100644 kernel/src/core/splash.c delete mode 100644 kernel/src/drivers/console.c delete mode 100644 kernel/src/drivers/serial.c delete mode 100644 kernel/src/drivers/shitgui.c delete mode 100644 kernel/src/drivers/timer.c delete mode 100644 kernel/src/fs/cpio.c delete mode 100644 kernel/src/fs/vfs.c create mode 100644 kernel/src/lib/Rand.c create mode 100644 kernel/src/lib/Splash.c rename kernel/src/{core/string.c => lib/String.c} (52%) delete mode 100644 kernel/src/mm/heap.c delete mode 100644 kernel/src/mm/memory.c delete mode 100644 kernel/src/mm/pmm.c delete mode 100644 kernel/src/mm/vmm.c delete mode 100644 kernel/src/syscalls/io.c delete mode 100644 kernel/src/syscalls/mem.c delete mode 100644 kernel/src/syscalls/proc.c diff --git a/bootloader/src/main.c b/bootloader/src/main.c index 6a1c4dd..8d55b89 100644 --- a/bootloader/src/main.c +++ b/bootloader/src/main.c @@ -82,7 +82,7 @@ int main() if (EFI_ERROR(status)) { print_initramfs_warning(L"initramfs.cpio is missing"); - boot_info->initramfs.addr = nullptr; + boot_info->initramfs.address = nullptr; boot_info->initramfs.size = 0; } else { status = initramfs_file->GetInfo(initramfs_file, &fi_guid, &iinfo_size, nullptr); @@ -105,14 +105,14 @@ int main() // just fucking kill me uintn_t initramfs_size_read = (uintn_t)initramfs_size; initramfs_file->Read(initramfs_file, &initramfs_size_read, (void*)initramfs_addr); - boot_info->initramfs.addr = (void*)initramfs_addr; + boot_info->initramfs.address = (void*)initramfs_addr; boot_info->initramfs.size = initramfs_size; } } } boot_info->framebuffer.base = (uint32_t*)gop->Mode->FrameBufferBase; - boot_info->framebuffer.base_size = gop->Mode->FrameBufferSize; + boot_info->framebuffer.baseSize = gop->Mode->FrameBufferSize; boot_info->framebuffer.height = gop->Mode->Information->VerticalResolution; boot_info->framebuffer.width = gop->Mode->Information->HorizontalResolution; boot_info->framebuffer.pitch = gop->Mode->Information->PixelsPerScanLine; @@ -139,11 +139,11 @@ int main() break; } - boot_info->mem.descriptor_size = desc_size; - boot_info->mem.descriptor_version = desc_version; - boot_info->mem.map_size = map_size; - boot_info->mem.map_key = map_key; - boot_info->mem.map = map; + boot_info->memoryMap.descriptorSize = desc_size; + boot_info->memoryMap.descriptorVersion = desc_version; + boot_info->memoryMap.mapSize = map_size; + boot_info->memoryMap.mapKey = map_key; + boot_info->memoryMap.map = map; status = gBS->ExitBootServices(IM, map_key); if (status == EFI_SUCCESS) { diff --git a/common/bootinfo.h b/common/bootinfo.h index 83b123b..6936962 100644 --- a/common/bootinfo.h +++ b/common/bootinfo.h @@ -3,35 +3,35 @@ #pragma once -typedef unsigned int bi_u32; -typedef unsigned long long bi_u64; +typedef unsigned int BIUInt32; +typedef unsigned long long BIUInt64; typedef struct { - bi_u32* base; - bi_u64 base_size; - bi_u64 width; - bi_u64 height; - bi_u64 pitch; -} BI_Framebuffer; + BIUInt32* base; + BIUInt64 baseSize; + BIUInt64 width; + BIUInt64 height; + BIUInt64 pitch; +} BIFramebuffer; typedef struct { void* map; - bi_u64 map_size; - bi_u64 descriptor_size; - bi_u32 map_key; - bi_u32 descriptor_version; -} BI_MemoryMap; + BIUInt64 mapSize; + BIUInt64 descriptorSize; + BIUInt32 mapKey; + BIUInt32 descriptorVersion; +} BIMemoryMap; typedef struct { - void* addr; - bi_u64 size; -} BI_Initramfs; + void* address; + BIUInt64 size; +} BIInitramfs; typedef struct { - bi_u64 magic; - BI_Framebuffer framebuffer; - BI_MemoryMap mem; - BI_Initramfs initramfs; + BIUInt64 magic; + BIFramebuffer framebuffer; + BIMemoryMap memoryMap; + BIInitramfs initramfs; } Bootinfo; #define BOOTINFO_MAGIC 0x7465726D // term \ No newline at end of file diff --git a/common/hot_header.h b/common/hot_header.h index 4f12b47..06b9080 100644 --- a/common/hot_header.h +++ b/common/hot_header.h @@ -1,23 +1,23 @@ -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef unsigned long long u64; +typedef unsigned char UInt8; +typedef unsigned short UInt16; +typedef unsigned int UInt32; +typedef unsigned long long UInt64; #define HOT_MAGIC 0x21544F48 -typedef struct hot_segment { - u64 type; // 1 = rx 2 = rw - u64 vaddr; - u64 offset; - u64 filesz; - u64 memsz; -} hot_segment; +typedef struct HOTSegment { + UInt64 type; // 1 = rx 2 = rw + UInt64 vaddr; + UInt64 offset; + UInt64 filesz; + UInt64 memsz; +} HOTSegment; -typedef struct hot_header { - u32 magic; // "HOT!" - u8 version; // 1 - u8 reserved_pad[3]; - u64 entry_point; - u64 segments_count; - u64 reserved; -} hot_header; +typedef struct HOTHeader { + UInt32 magic; // "HOT!" + UInt8 version; // 1 + UInt8 reserved_pad[3]; + UInt64 entry_point; + UInt64 segments_count; + UInt64 reserved; +} HOTHeader; diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index b8f8e0e..411bb59 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -18,14 +18,16 @@ file(GLOB_RECURSE KERNEL_SOURCES CMAKE_CONFIGURE_DEPENDS "src/arch/${ARCH}/*.c" "src/arch/${ARCH}/*.asm" - "src/core/*.c" - "src/drivers/*.c" - "src/mm/*.c" + "src/OS/*.c" + "src/OS/Exec/*.c" + "src/OS/Services/*.c" + "src/lib/*.c" + "src/IO/*.c" + "src/VM/*.c" "src/shell/*.c" - "src/fs/*.c" - "src/syscalls/*.c" + "src/FS/*.c" - "data/*.c" + "Data/*.c" ) add_executable(kernel ${KERNEL_SOURCES}) @@ -34,7 +36,7 @@ target_include_directories(kernel PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../common" "${CMAKE_CURRENT_SOURCE_DIR}/inc" "${CMAKE_CURRENT_SOURCE_DIR}/inc/arch/${ARCH}" - "${CMAKE_CURRENT_SOURCE_DIR}/data" + "${CMAKE_CURRENT_SOURCE_DIR}/Data" ) target_compile_options(kernel PRIVATE diff --git a/kernel/data/font8x16.c b/kernel/inc/Data/VGAFont.h similarity index 99% rename from kernel/data/font8x16.c rename to kernel/inc/Data/VGAFont.h index d005f58..788e101 100644 --- a/kernel/data/font8x16.c +++ b/kernel/inc/Data/VGAFont.h @@ -1,8 +1,8 @@ -// font8x16 bitmap font -// Source: https://github.com/hubenchang0515/font8x16 -// License: MIT +#pragma once +#include -unsigned char font8x16[][16] = { + +unsigned char VGAFont[][16] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, //0x00, { 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD, 0x99, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00, }, //0x01, { 0x00, 0x00, 0x7E, 0xFF, 0xDB, 0xFF, 0xFF, 0xC3, 0xE7, 0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00, }, //0x02, diff --git a/kernel/data/cats.h b/kernel/inc/Data/cats.h similarity index 100% rename from kernel/data/cats.h rename to kernel/inc/Data/cats.h diff --git a/kernel/data/logo.h b/kernel/inc/Data/logo.h similarity index 99% rename from kernel/data/logo.h rename to kernel/inc/Data/logo.h index a39fbad..b302ca5 100644 --- a/kernel/data/logo.h +++ b/kernel/inc/Data/logo.h @@ -3,12 +3,12 @@ // Copyright (c) 2025 0xKarinyash #pragma once -#include +#include #define LOGO_TRANSPARENCY_KEY 0xFF00FF // Image: 100x100 -static const u32 logo_data[] = { +static const UInt32 logo_data[] = { 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, @@ -1261,8 +1261,7 @@ static const u32 logo_data[] = { 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, }; -static SG_Image logo_img = { - .width = 100, - .height = 100, - .buffer = (u32*)logo_data +static IOGraphicsImage logoImage = { + .size = {100, 100}, + .buffer = (UInt32*)logo_data }; \ No newline at end of file diff --git a/kernel/inc/FS/CPIO.h b/kernel/inc/FS/CPIO.h new file mode 100644 index 0000000..66bc080 --- /dev/null +++ b/kernel/inc/FS/CPIO.h @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#pragma once +#include +#include + +UInt64 FSCPIORead(FSVNode* node, UInt64 offset, UInt64 size, UInt8* buffer); +FSVNode* FSCPIOMount(void* baseAddress, UInt64 totalSize); \ No newline at end of file diff --git a/kernel/inc/FS/VFS.h b/kernel/inc/FS/VFS.h new file mode 100644 index 0000000..8a91e7c --- /dev/null +++ b/kernel/inc/FS/VFS.h @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#pragma once +#include + +typedef enum FSVNodeFlags { + kFSVNodeFlagFile = 0x01, + kFSVNodeFlagDirectory = 0x02, +} FSVNodeFlags; + +typedef struct FSVNode FSVNode; + +typedef struct FSVNodeOperations { + UInt64 (*read)(FSVNode* node, UInt64 offset, UInt64 size, UInt8* buffer); + UInt64 (*write)(FSVNode* node, UInt64 offset, UInt64 size, UInt8* buffer); + void (*open)(FSVNode* node); + void (*close)(FSVNode* node); + FSVNode* (*findDirectory)(FSVNode* node, char* name); +} FSVNodeOperations; + +typedef struct FSVNode { + char name[256]; + UInt32 protectionMask; + UInt32 ownerIdentifier; + UInt32 groupIdentifier; + UInt32 flags; + UInt32 inodeIdentifier; + UInt64 dataLength; + + FSVNodeOperations* operations; + void* implementationData; + + struct FSVNode* mountPoint; + struct FSVNode* childNode; + struct FSVNode* nextNode; +} FSVNode; + +void FSVirtualFileSystemInitialize(FSVNode* rootNode); +UInt64 FSVNodeRead(FSVNode* node, UInt64 offset, UInt64 size, UInt8* buffer); +FSVNode* FSVirtualFileSystemOpenPath(const char* path); +void FSVNodeClose(FSVNode* node); \ No newline at end of file diff --git a/kernel/inc/IO/IOConsole.h b/kernel/inc/IO/IOConsole.h new file mode 100644 index 0000000..74f23b2 --- /dev/null +++ b/kernel/inc/IO/IOConsole.h @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once +#include + +enum { + kIOConsoleColorRed = 0xFF5555, + kIOConsoleColorVeryRed = 0xFF0000, + kIOConsoleColorGreen = 0x08bf39, + kIOConsoleColorVeryGreen = 0x00FF00, + kIOConsoleColorTurqoise = 0x5effaf, + kIOConsoleColorBlue = 0x5555FF, + kIOConsoleColorVeryBlue = 0x0000FF, + kIOConsoleColorLightBlue = 0x3890e8, + kIOConsoleColorYellow = 0xFFFF55, + kIOConsoleColorCyan = 0x55FFFF, + kIOConsoleColorMagneta = 0xFF55FF, + kIOConsoleColorBlack = 0x000000, + kIOConsoleColorWhite = 0xFFFFFF, + kIOConsoleColorPink = 0xFFA3B1, +}; + +void IOConsoleInit(IOGraphicsContext* context); +UInt64 IOConsoleGetColors(); +void IOConsoleClear(IOGraphicsColor color); +IOGraphicsContext* IOConsoleGetGraphicsContext(); +IOGraphicsSize IOConsoleGetDimensions(); +void IOConsoleSetForegroundColor(IOGraphicsColor color); +void IOConsoleSetDefaultForegroundColor(UInt32 color); +void IOConsoleSetCursorPosition(IOGraphicsPoint* point); +char IOConsoleGetCharacter(); +void IOConsoleReadLine(char* buffer, UInt32 limit); +void IOConsolePutcharacter(char character); +void IOConsolePrint(const char *string); +void IOConsoleLog(const char *fmt, ...); \ No newline at end of file diff --git a/kernel/inc/IO/IOGraphics.h b/kernel/inc/IO/IOGraphics.h new file mode 100644 index 0000000..4acb3a9 --- /dev/null +++ b/kernel/inc/IO/IOGraphics.h @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash +// RIP shitgui -- you started it all + +#pragma once +#include + +typedef UInt32 IOGraphicsColor; + +typedef struct { + UInt32 x; + UInt32 y; +} IOGraphicsPoint; + +typedef struct { + UInt32 width; + UInt32 height; +} IOGraphicsSize; + +typedef struct { + volatile UInt32* framebuffer; + IOGraphicsSize dimensions; + UInt32 pixelsPerScanLine; +} IOGraphicsContext; + +typedef struct { + IOGraphicsColor* buffer; + IOGraphicsSize size; +} IOGraphicsImage; + +typedef struct { + IOGraphicsSize size; + const unsigned char* baseAddress; +} IOGraphicsFont; + + +UInt32 IOGraphicsGetPixel(IOGraphicsContext* context, IOGraphicsPoint* point); + +void IOGraphicsDrawImage(IOGraphicsContext* context, IOGraphicsPoint* point, IOGraphicsImage* image); + +void IOGraphicsDrawRectangle(IOGraphicsContext* context, IOGraphicsPoint* point, + IOGraphicsSize* size, IOGraphicsColor color); + +void IOGraphicsDrawCharacter( + IOGraphicsContext* context, + IOGraphicsPoint* point, + char character, + IOGraphicsColor color, + IOGraphicsFont* font +); \ No newline at end of file diff --git a/kernel/inc/IO/IOKeyboard.h b/kernel/inc/IO/IOKeyboard.h new file mode 100644 index 0000000..59579a0 --- /dev/null +++ b/kernel/inc/IO/IOKeyboard.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once +#include + +enum { + kIOKeyboardBufferSize = 256, +}; + +typedef struct { + char buffer[kIOKeyboardBufferSize]; + UInt16 head; + UInt16 tail; +} IOKeyboardBuffer; + +extern IOKeyboardBuffer gIOKeyboardInputBuffer; + +void IOKeyboardInterruptsHandler(); diff --git a/kernel/inc/IO/IOSerial.h b/kernel/inc/IO/IOSerial.h new file mode 100644 index 0000000..e95c50a --- /dev/null +++ b/kernel/inc/IO/IOSerial.h @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once + +int IOSerialInit(); +void IOSerialWriteChar(char character); +void IOSerialWrite(const char *string); diff --git a/kernel/inc/IO/IOTimer.h b/kernel/inc/IO/IOTimer.h new file mode 100644 index 0000000..5a6038c --- /dev/null +++ b/kernel/inc/IO/IOTimer.h @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once +#include + +void IOTimerInitialize(UInt32 freq); +UInt64 IOTimerInterruptsHandler(CPURegisters *regs); +UInt64 IOTimerGetTicks(); \ No newline at end of file diff --git a/kernel/inc/mm/heap.h b/kernel/inc/MM/Heap.h similarity index 56% rename from kernel/inc/mm/heap.h rename to kernel/inc/MM/Heap.h index 8c3c0cf..b433d4d 100644 --- a/kernel/inc/mm/heap.h +++ b/kernel/inc/MM/Heap.h @@ -10,15 +10,15 @@ #define HEADER_MAGIC 0x1CE -typedef struct block_header { - u64 magic; - struct block_header* next; - struct block_header* prev; - u64 size; - bool is_free; +typedef struct VMHeapBlockHeader { + UInt64 magic; + struct VMHeapBlockHeader* next; + struct VMHeapBlockHeader* previous; + UInt64 size; + bool isFree; } block_header; -void heap_init(); -void* malloc(u64 size); +void VMHeapInitialize(); +void* malloc(UInt64 size); void free(void* ptr); -void* realloc(void* ptr, u64 new_size); +void* realloc(void* ptr, UInt64 new_size); diff --git a/kernel/inc/core/hot.h b/kernel/inc/OS/Exec/HOTLoader.h similarity index 59% rename from kernel/inc/core/hot.h rename to kernel/inc/OS/Exec/HOTLoader.h index b8456cb..0d082af 100644 --- a/kernel/inc/core/hot.h +++ b/kernel/inc/OS/Exec/HOTLoader.h @@ -3,6 +3,6 @@ #pragma once #include -#include +#include -u64 load_hot(process* proc, u8* data); \ No newline at end of file +UInt64 HOTLoad(OSProcess* process, UInt8* data); \ No newline at end of file diff --git a/kernel/inc/core/loader.h b/kernel/inc/OS/Exec/OSLoader.h similarity index 62% rename from kernel/inc/core/loader.h rename to kernel/inc/OS/Exec/OSLoader.h index 3b46941..4ae260d 100644 --- a/kernel/inc/core/loader.h +++ b/kernel/inc/OS/Exec/OSLoader.h @@ -5,5 +5,5 @@ #include -i32 process_spawn(const char* path, const char* name); +Int32 OSLoaderProcessSpawn(const char* executablePath, const char* processName); void init_task_entry(); \ No newline at end of file diff --git a/kernel/inc/OS/OSPanic.h b/kernel/inc/OS/OSPanic.h new file mode 100644 index 0000000..c51d296 --- /dev/null +++ b/kernel/inc/OS/OSPanic.h @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once +#include + +__attribute__((noreturn)) void OSPanicException(CPURegisters* frame); +__attribute__((noreturn)) void OSPanic(const char* msg); diff --git a/kernel/inc/OS/OSScheduler.h b/kernel/inc/OS/OSScheduler.h new file mode 100644 index 0000000..03bc67b --- /dev/null +++ b/kernel/inc/OS/OSScheduler.h @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once +#include + +typedef enum OSProcessState { + kOSProcessStateDead, + kOSProcessStateRunning, + kOSProcessStateReady, + kOSProcessStateBlocked, + kOSProcessStateSleeping, +} OSProcessState; + +typedef struct OSProcess { + UInt64 processId; + OSProcessState state; + UInt64 physicalPML4; + struct OSProcess* parent; + char name[32]; + UInt64 heapStartPointer; + UInt64 heapCurrentPointer; +} OSProcess; + +typedef struct OSTask { + UInt64 stackPointer; + struct OSTask* next; + UInt32 id; + UInt32 sleepTicks; + OSProcessState taskState; // reusing process_state cuz wn + UInt64 kernelStackTop; + OSProcess* process; + Int32 waitingForProcess; +} OSTask; + +void OSSchedulerInitialize(); +OSTask* OSSchedulerSpawn(void(*entry)(), OSProcess* owner, Boolean isUser, UInt64 fixedUserStackPointer); +UInt64 OSSchedulerNext(UInt64 currentStackPointer); +void OSSchedulerYield(UInt64 ticks); +void OSSchedulerBlock(UInt32 processID); +void OSSchedulerWakeup(UInt32 processID); +void OSSchedulerTerminate(); // suicide + +extern OSTask* gOSSchedulerCurrentTask; \ No newline at end of file diff --git a/kernel/inc/OS/Services/OSServiceIO.h b/kernel/inc/OS/Services/OSServiceIO.h new file mode 100644 index 0000000..98f96bf --- /dev/null +++ b/kernel/inc/OS/Services/OSServiceIO.h @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#pragma once +#include + +UInt64 OSServiceWrite(UInt64 fileDescriptor, UInt64 buffer, UInt64 length); +UInt64 OSServiceRead(UInt64 fileDescriptor, UInt64 buffer, UInt64 count); \ No newline at end of file diff --git a/kernel/inc/syscalls/mem.h b/kernel/inc/OS/Services/OSServiceMemory.h similarity index 74% rename from kernel/inc/syscalls/mem.h rename to kernel/inc/OS/Services/OSServiceMemory.h index 6d6d396..c1d71d6 100644 --- a/kernel/inc/syscalls/mem.h +++ b/kernel/inc/OS/Services/OSServiceMemory.h @@ -4,4 +4,4 @@ #pragma once #include -u64 sys_mem(u64 size); \ No newline at end of file +UInt64 OSServiceMemoryGet(UInt64 size); \ No newline at end of file diff --git a/kernel/inc/OS/Services/OSServiceProcess.h b/kernel/inc/OS/Services/OSServiceProcess.h new file mode 100644 index 0000000..580a522 --- /dev/null +++ b/kernel/inc/OS/Services/OSServiceProcess.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#pragma once + +#include + +Int32 OSServiceProcessExit(Int32 code); +Int32 OSServiceProcessSpawn(const char* path); +Int32 OSServiceProcessWait(UInt64 pid); \ No newline at end of file diff --git a/kernel/inc/VM/Heap.h b/kernel/inc/VM/Heap.h new file mode 100644 index 0000000..666c8f3 --- /dev/null +++ b/kernel/inc/VM/Heap.h @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once +#include + +enum { + kVMKernelHeapStart = 0xFFFFFFFFC0000000, + kVMHeapSizePages = 1024 +}; + +#define PHYS_TO_HEAP(phys) ((phys) + KERNEL_HEAP_START) +#define HEAP_TO_PHYS(phys) ((phys) - KERNEL_HEAP_START) + +#define HEADER_MAGIC 0x1CE + +typedef struct VMHeapBlockHeader { + UInt64 magic; + struct VMHeapBlockHeader* next; + struct VMHeapBlockHeader* previous; + UInt64 size; + bool isFree; +} VMHeapBlockHeader; + +void VMHeapInitialize(); +void* malloc(UInt64 size); +void free(void* ptr); +void* realloc(void* ptr, UInt64 newSize); diff --git a/kernel/inc/VM/PMM.h b/kernel/inc/VM/PMM.h new file mode 100644 index 0000000..f4b1e41 --- /dev/null +++ b/kernel/inc/VM/PMM.h @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once +#include "bootinfo.h" +#include + +#define kVMPageSize 4096 +#define kVMSafeSpaceStartAddress 0x100000 +#define kVMBlocksPerByte 8 + +#define BITMAP_BYTE_INDEX(address) ((address / kVMPageSize) / kVMBlocksPerByte) +#define BITMAP_BIT_OFFSET(address) ((address / kVMPageSize) % kVMBlocksPerByte) +#define BITMAP_TEST(bitmap, address) (bitmap[BITMAP_BYTE_INDEX(address)] & (1 << BITMAP_BIT_OFFSET(address))) +#define BITMAP_SET(bitmap, address) (bitmap[BITMAP_BYTE_INDEX(address)] |= (1 << BITMAP_BIT_OFFSET(address))) +#define BITMAP_UNSET(bitmap, address) (bitmap[BITMAP_BYTE_INDEX(address)] &= ~(1 << BITMAP_BIT_OFFSET(address))) + +typedef struct { + UInt32 type; + UInt32 padding; + UInt64 physicalStart; + UInt64 virtualStart; + UInt64 pageCount; + UInt64 attributes; +} __attribute__((packed)) OSMemoryDescriptor; + +typedef enum { + kOSMemoryTypeReserved, + kOSMemoryTypeLoaderCode, + kOSMemoryTypeLoaderData, + kOSMemoryTypeBootServicesCode, + kOSMemoryTypeBootServicesData, + kOSMemoryTypeRuntimeServicesCode, + kOSMemoryTypeRuntimeServicesData, + kOSMemoryTypeConventional, + kOSMemoryTypeUnusable, + kOSMemoryTypeACPIReclaim, + kOSMemoryTypeACPINonVolatile, + kOSMemoryTypeMappedIO, + kOSMemoryTypeMappedIOPortSpace, + kOSMemoryTypePalCode, + kOSMemoryTypePersistent, + kOSMemoryTypeMax +} OSMemoryType; + +UInt64 VMPhysicalMemoryGetTotalMemorySize(); +void VMPhysicalMemoryInitialize(BIMemoryMap* mmap); +void* VMPhysicalMemoryAllocatePage(); +void VMPhysicalMemoryFreePage(void* addr); diff --git a/kernel/inc/mm/vmm.h b/kernel/inc/VM/VMM.h similarity index 84% rename from kernel/inc/mm/vmm.h rename to kernel/inc/VM/VMM.h index 3be5cc4..7743f59 100644 --- a/kernel/inc/mm/vmm.h +++ b/kernel/inc/VM/VMM.h @@ -35,9 +35,9 @@ #define HHDM_TO_PHYS(virt) ((virt) - HHDM_OFFSET) -void vmm_init(Bootinfo* info); -u64* vmm_map_page(u64* pml4, u64 phys, u64 virt, u64 flags); -u64 vmm_create_address_space(); -u64 vmm_get_current_cr3(); -void load_cr3(u64 pml4_addr); -void vmm_setup_user_stack(u64* pml4_phys); \ No newline at end of file +void VMVirtualMemoryInitialize(Bootinfo* info); +UInt64* VMVirtualMemoryMapPage(UInt64* PML4, UInt64 physical, UInt64 virtual, UInt64 flags); +UInt64 VMVirtualMemoryCreateAddressSpace(); +UInt64 VMGetCurrentCR3(); +void VMLoadCR3(UInt64 PML4Address); +void VMVirtualMemorySetupUserStack(UInt64* physicalPML4); \ No newline at end of file diff --git a/kernel/inc/arch/x86_64/GDT.h b/kernel/inc/arch/x86_64/GDT.h new file mode 100644 index 0000000..afc242d --- /dev/null +++ b/kernel/inc/arch/x86_64/GDT.h @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once +#include + +#define kHALGDTEntries 7 + +typedef struct { + UInt16 limitLow; + UInt16 baseLow; + UInt8 baseMiddle; + UInt8 access; + UInt8 granularity; + UInt8 baseHigh; +} __attribute__((packed)) HALGlobalDescriptorTable; + + +typedef struct { + UInt16 limit; + UInt64 base; +} __attribute__((packed)) HALGlobalDescriptorTablePointer; + +typedef struct { + UInt32 reserved0; + UInt64 rsp0; + UInt64 rsp1; + UInt64 rsp2; + UInt64 reserved1; + UInt64 ist1; + UInt64 ist2; + UInt64 ist3; + UInt64 ist4; + UInt64 ist5; + UInt64 ist6; + UInt64 ist7; + UInt64 reserved2; + UInt16 reserved3; + UInt16 iomapBase; +} __attribute__((packed)) HALTaskStateSegment; + + +extern HALTaskStateSegment gHALTaskStateSegment; + +void HALGlobalDescriptorTableInitialize(); diff --git a/kernel/inc/arch/x86_64/IDT.h b/kernel/inc/arch/x86_64/IDT.h new file mode 100644 index 0000000..982a372 --- /dev/null +++ b/kernel/inc/arch/x86_64/IDT.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once +#include + +typedef struct { + UInt16 offsetLow; + UInt16 selector; + UInt8 ist; + UInt8 attributes; + UInt16 offsetMid; + UInt32 offsetHigh; + UInt32 reserved; +} __attribute__((packed)) HALInterruptsDescriptorTableEntry; + +typedef struct { + UInt16 limit; + UInt64 base; +} __attribute__((packed)) HALInterruptsDescriptorTablePointer; + +void HALInterruptsDescriptorTableInitialize(); diff --git a/kernel/inc/arch/x86_64/IO.h b/kernel/inc/arch/x86_64/IO.h new file mode 100644 index 0000000..512d36a --- /dev/null +++ b/kernel/inc/arch/x86_64/IO.h @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once + +#include + +enum { + kIOMasterCommand = 0x20, + kIOMasterData = 0x21, + kIOSlaveCommand = 0xA0, + kIOSlaveData = 0xA1, + kIOPortWaitAddress = 0x80 +}; + +static inline void IOPortWrite8(UInt16 port, UInt8 val) { + __asm__ volatile( + "outb %0, %1" + : + : "a"(val), + "Nd"(port) ); +} + +static inline unsigned char IOPortRead8(UInt16 port) { + unsigned char ret; + __asm__ volatile( + "inb %1, %0" + : "=a"(ret) + : "Nd"(port) + ); + + return ret; +} + +// sending junk to 0x80 (unused) to skip few tacts +// not ideal i know +static inline void IOSynchronizeBus() { + IOPortWrite8(kIOPortWaitAddress, 0x0); +} + +static inline void IOPortWrite8WithWait(UInt16 port, UInt8 val) { + IOPortWrite8(port, val); + IOSynchronizeBus(); +} diff --git a/kernel/inc/arch/x86_64/OSCPU.h b/kernel/inc/arch/x86_64/OSCPU.h new file mode 100644 index 0000000..82b759a --- /dev/null +++ b/kernel/inc/arch/x86_64/OSCPU.h @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash +#pragma once +#include + +typedef enum { + kCPUFeatureFPU = (1ULL << 0), + kCPUFeatureTSC = (1ULL << 1), + kCPUFeatureMSR = (1ULL << 2), + kCPUFeatureAPIC = (1ULL << 3), + kCPUFeatureMTRR = (1ULL << 4), + kCPUFeaturePAE = (1ULL << 5), + + kCPUFeatureSSE = (1ULL << 10), + kCPUFeatureSSE2 = (1ULL << 11), + kCPUFeatureSSE3 = (1ULL << 12), + kCPUFeatureSSSE3 = (1ULL << 13), + kCPUFeatureSSE4_1 = (1ULL << 14), + kCPUFeatureSSE4_2 = (1ULL << 15), + + kCPUFeatureAVX = (1ULL << 20), + kCPUFeatureF16C = (1ULL << 21), + kCPUFeatureRDRAND = (1ULL << 22), + + kCPUFeatureHypervisor = (1ULL << 30) +} OSCPUFeature; + +typedef struct { + UInt64 userStackPointer; + UInt64 kernelStackPointer; + UInt64 selfAddress; + + UInt64 features; + char vendorID[13]; + UInt32 family; + UInt32 model; +} OSCPUData; + +extern OSCPUData gOSBootCPU; + +void OSCPUInitialize(UInt64 kernelStackTop); +Boolean OSCPUHasFeature(OSCPUFeature feature); \ No newline at end of file diff --git a/kernel/inc/arch/x86_64/pic.h b/kernel/inc/arch/x86_64/PIC.h similarity index 71% rename from kernel/inc/arch/x86_64/pic.h rename to kernel/inc/arch/x86_64/PIC.h index 0b3fa3e..23f282b 100644 --- a/kernel/inc/arch/x86_64/pic.h +++ b/kernel/inc/arch/x86_64/PIC.h @@ -3,4 +3,4 @@ #pragma once #include -u16 pic_remap(); +UInt16 HALLegacyInterruptControllerRemap(); diff --git a/kernel/inc/arch/x86_64/cpuinfo.h b/kernel/inc/arch/x86_64/cpuinfo.h deleted file mode 100644 index 98acf32..0000000 --- a/kernel/inc/arch/x86_64/cpuinfo.h +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash -#pragma once -#include - -#define CPU_FEAT_FPU (1ULL << 0) -#define CPU_FEAT_TSC (1ULL << 1) -#define CPU_FEAT_MSR (1ULL << 2) -#define CPU_FEAT_APIC (1ULL << 3) -#define CPU_FEAT_MTRR (1ULL << 4) -#define CPU_FEAT_PAE (1ULL << 5) - -#define CPU_FEAT_SSE (1ULL << 10) -#define CPU_FEAT_SSE2 (1ULL << 11) -#define CPU_FEAT_SSE3 (1ULL << 12) -#define CPU_FEAT_SSSE3 (1ULL << 13) -#define CPU_FEAT_SSE4_1 (1ULL << 14) -#define CPU_FEAT_SSE4_2 (1ULL << 15) - -#define CPU_FEAT_AVX (1ULL << 20) -#define CPU_FEAT_F16C (1ULL << 21) -#define CPU_FEAT_RDRAND (1ULL << 22) - -#define CPU_FEAT_HYPERVISOR (1ULL << 30) - -typedef struct { - u64 user_rsp; - u64 kernel_rsp; - u64 self; - - u64 features; - char vendor[13]; - u32 family; - u32 model; -} cpu_info; - -extern cpu_info g_cpu; - -void cpuinfo_init(u64 kernel_stack_top); -bool cpu_has(u64 feature); \ No newline at end of file diff --git a/kernel/inc/arch/x86_64/gdt.h b/kernel/inc/arch/x86_64/gdt.h deleted file mode 100644 index 9367b4c..0000000 --- a/kernel/inc/arch/x86_64/gdt.h +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once -#include - -typedef struct { - u16 limit_low; - u16 base_low; - u8 base_middle; - u8 access; - u8 granularity; - u8 base_high; -} __attribute__((packed)) GDTDescriptor; - - -typedef struct { - u16 limit; - u64 base; -} __attribute__((packed)) GDTPtr; - -typedef struct { - u32 reserved0; - u64 rsp0; - u64 rsp1; - u64 rsp2; - u64 reserved1; - u64 ist1; - u64 ist2; - u64 ist3; - u64 ist4; - u64 ist5; - u64 ist6; - u64 ist7; - u64 reserved2; - u16 reserved3; - u16 iomap_base; -} __attribute__((packed)) TSS; - -extern TSS tss; - -void gdt_init(); diff --git a/kernel/inc/arch/x86_64/idt.h b/kernel/inc/arch/x86_64/idt.h deleted file mode 100644 index 587f59c..0000000 --- a/kernel/inc/arch/x86_64/idt.h +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once -#include - -typedef struct { - u16 offset_low; - u16 selector; - u8 ist; - u8 attributes; - u16 offset_mid; - u32 offset_high; - u32 reserved; -} __attribute__((packed)) IDTEntry; - -typedef struct { - u16 limit; - u64 base; -} __attribute__((packed)) IDTPtr; - -void idt_init(); diff --git a/kernel/inc/arch/x86_64/io.h b/kernel/inc/arch/x86_64/io.h deleted file mode 100644 index ff68c7a..0000000 --- a/kernel/inc/arch/x86_64/io.h +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once - -#define MASTER_COMMAND 0x20 -#define MASTER_DATA 0x21 -#define SLAVE_COMMAND 0xA0 -#define SLAVE_DATA 0xA1 - -static inline void outb(unsigned short port, unsigned char val) { - __asm__ volatile( - "outb %0, %1" - : - : "a"(val), - "Nd"(port) ); -} - -static inline unsigned char inb(unsigned short port) { - unsigned char ret; - __asm__ volatile( - "inb %1, %0" - : "=a"(ret) - : "Nd"(port) - ); - - return ret; -} - -// sending junk to 0x80 (unused) to skip few tacts -// not ideal i know -static inline void io_wait() { - outb(0x80, 0x0); -} - -static inline void outb_wait(unsigned short port, unsigned char val) { - outb(port, val); - io_wait(); -} diff --git a/kernel/inc/arch/x86_64/syscall.h b/kernel/inc/arch/x86_64/syscall.h index 5ec0394..5a4150e 100644 --- a/kernel/inc/arch/x86_64/syscall.h +++ b/kernel/inc/arch/x86_64/syscall.h @@ -3,14 +3,18 @@ #pragma once -#define MSR_EFER 0xC0000080 -#define MSR_STAR 0xC0000081 -#define MSR_LSTAR 0xC0000082 -#define MSR_FMASK 0xC0000084 -#define MSR_GS_BASE 0xC0000101 -#define MSR_KERNEL_GS_BASE 0xC0000102 +enum { + kHALModelSpecificRegisterExtendedFeatureEnable = 0xC0000080, // EFER + kHALModelSpecificRegisterSystemCallTarget = 0xC0000081, // STAR + kHALModelSpecificRegisterLongSystemCallTarget = 0xC0000082, // LSTAR + kHALModelSpecificRegisterSystemCallFlagMask = 0xC0000084, // FMASK + kHALModelSpecificRegisterGSBase = 0xC0000101, // GS_BASE + kHALModelSpecificRegisterKernelGSBase = 0xC0000102 // KERNEL_GS_BASE +}; -#define EFER_SCE 0x01 // System Call Enable +enum { + kHALEFERSystemCallExtensionsEnable = 0x01 // SCE +}; typedef enum { SYS_EXIT, @@ -19,6 +23,6 @@ typedef enum { SYS_WRITE, SYS_READ, SYS_WAIT, -} syscalls; +} Services; -void syscall_init(); \ No newline at end of file +void OSServicesInitialize(); \ No newline at end of file diff --git a/kernel/inc/core/panic.h b/kernel/inc/core/panic.h deleted file mode 100644 index 6c66ba8..0000000 --- a/kernel/inc/core/panic.h +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once -#include - -__attribute__((noreturn)) void panic_exception(Registers *regs); -__attribute__((noreturn)) void panic(const char* msg); - -extern const char* exception_messages[]; diff --git a/kernel/inc/core/scheduler.h b/kernel/inc/core/scheduler.h deleted file mode 100644 index ede8e03..0000000 --- a/kernel/inc/core/scheduler.h +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once -#include - -typedef enum process_state { - DEAD, - RUNNING, - READY, - BLOCKED, - SLEEPING, -} process_state; - -typedef struct process { - u64 pid; - process_state state; - u64 pml4_phys; - struct process* parent; - char name[32]; - u64 heap_start; - u64 heap_cur; -} process; - -typedef struct task { - u64 rsp; - struct task* next; - u32 id; - u32 sleep_ticks; - process_state task_state; // reusing process_state cuz wn - u64 kernel_stack_top; - process* proc; - i32 waiting_on_pid; -} task; - -void sched_init(); -task* sched_spawn(void(*entry)(), process* owner, bool is_user, u64 fixed_user_stack); -u64 sched_next(u64 curr_rsp); -void yield(u64 ticks); -void sched_block(u32 pid); -void sched_wakeup(u32 pid); -void sched_exit(); // suicide \ No newline at end of file diff --git a/kernel/inc/core/string.h b/kernel/inc/core/string.h deleted file mode 100644 index 82128fc..0000000 --- a/kernel/inc/core/string.h +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once -#include - -i32 strcmp(const char* s1, const char* s2); -i32 strncmp(const char* s1, const char* s2, u64 n); -char* strcpy(char* dest, const char* src); -char* strncpy(char* dest, const char* src, u64 n); \ No newline at end of file diff --git a/kernel/inc/drivers/console.h b/kernel/inc/drivers/console.h deleted file mode 100644 index 11bbd49..0000000 --- a/kernel/inc/drivers/console.h +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once -#include - -void console_init(SG_Context *ctx); -u64 console_get_colors(); -void console_clear(u32 color); -SG_Context* console_get_context(); -SG_Point console_get_dimensions(); -void console_set_color(u32 color); -void console_set_default_color(u32 color); -void console_set_cursor_pos(SG_Point *p); -char console_getc(); -void console_putc(char c); -void kprint(const char *str); -void kprintf(const char *fmt, ...); -void kgets(char* buff, u32 lim); -void cursor_blink(); -void cursor_blinker_sched_task(); -void console_toggle_cursor_blink(); diff --git a/kernel/inc/drivers/font.h b/kernel/inc/drivers/font.h deleted file mode 100644 index ccc3009..0000000 --- a/kernel/inc/drivers/font.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include - -extern u8 font8x16[128][16]; diff --git a/kernel/inc/drivers/keyboard.h b/kernel/inc/drivers/keyboard.h deleted file mode 100644 index 24278bf..0000000 --- a/kernel/inc/drivers/keyboard.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once -#include - -#define KB_BUFF_SIZE 256 -typedef struct { - char buffer[KB_BUFF_SIZE]; - u16 head; - u16 tail; -} kb_buffer; - -extern kb_buffer kb_buf; - -void kb_handler(); diff --git a/kernel/inc/drivers/serial.h b/kernel/inc/drivers/serial.h deleted file mode 100644 index 1264e75..0000000 --- a/kernel/inc/drivers/serial.h +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once - -int serial_init(); -void serial_writec(char chr); -void serial_write(const char *str); diff --git a/kernel/inc/drivers/shitgui.h b/kernel/inc/drivers/shitgui.h deleted file mode 100644 index 2a334fe..0000000 --- a/kernel/inc/drivers/shitgui.h +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once -#include - -typedef struct { - volatile u32 *fb; - u32 width; - u32 height; - u32 pitch; -} SG_Context; -typedef struct { - u32 x; - u32 y; -} SG_Point; -typedef struct { - u32 *buffer; - u32 height; - u32 width; -} SG_Image; - -typedef struct { - u32 w; - u32 h; - const unsigned char* base; -} SG_Font; - -void sg_init(SG_Context *ctx); -u32 sg_get_pixel(SG_Context *ctx, SG_Point *p); -void sg_put_img(SG_Context *ctx, SG_Point *p, SG_Image *img); -void sg_draw_rect(SG_Context *ctx, SG_Point *p, u32 w, u32 h, u32 color); -void sg_draw_char_bitmap(SG_Context *ctx, SG_Point *p, char c, u32 color, SG_Font *font); \ No newline at end of file diff --git a/kernel/inc/drivers/timer.h b/kernel/inc/drivers/timer.h deleted file mode 100644 index c51eea2..0000000 --- a/kernel/inc/drivers/timer.h +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once -#include - -void timer_init(u32 freq); -u64 timer_handler(Registers *regs); -void sleep(u64 ms); -u64 get_uptime(); \ No newline at end of file diff --git a/kernel/inc/fs/cpio.h b/kernel/inc/fs/cpio.h deleted file mode 100644 index 3275c25..0000000 --- a/kernel/inc/fs/cpio.h +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash -#pragma once -#include -#include - -u64 cpio_read(fs_node* node, u64 offset, u64 size, u8* buff); -fs_node* cpio_mount(void* base, u64 size); \ No newline at end of file diff --git a/kernel/inc/fs/vfs.h b/kernel/inc/fs/vfs.h deleted file mode 100644 index 179c19d..0000000 --- a/kernel/inc/fs/vfs.h +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash -#pragma once -#include - -#define FS_FILE 0x01 -#define FS_DIR 0x02 - -struct fs_node; -typedef struct fs_node fs_node; - -typedef struct { - u64 (*read)(struct fs_node* node, u64 offset, u64 size, u8* buff); - u64 (*write)(struct fs_node* node, u64 offset, u64 size, u8* buff); - void (*open)(struct fs_node* node); - void (*close)(struct fs_node* node); - - struct fs_node* (*finddir)(struct fs_node* node, char* name); -} fs_ops; - -struct fs_node { - char name[256]; - u32 mask; - u32 uid; - u32 gid; - u32 flags; - u32 inode; - u64 len; - fs_ops* ops; - void* impl_data; - struct fs_node* ptr; - struct fs_node* next; -}; - -void vfs_init(fs_node* root_node); -u64 vfs_read(fs_node* node, u64 offset, u64 size, u8* buff); -fs_node* vfs_open(const char* path); -void vfs_close(fs_node* node); \ No newline at end of file diff --git a/kernel/inc/core/math.h b/kernel/inc/lib/Math.h similarity index 88% rename from kernel/inc/core/math.h rename to kernel/inc/lib/Math.h index b8c6b99..11e7671 100644 --- a/kernel/inc/core/math.h +++ b/kernel/inc/lib/Math.h @@ -13,7 +13,7 @@ static inline int abs(int n) { return (n < 0) ? -n : n; } -static inline i64 i64abs(i64 n) { +static inline Int64 i64abs(Int64 n) { return (n < 0) ? -n : n; } diff --git a/kernel/inc/core/rand.h b/kernel/inc/lib/Rand.h similarity index 75% rename from kernel/inc/core/rand.h rename to kernel/inc/lib/Rand.h index c7d83cc..573a4ce 100644 --- a/kernel/inc/core/rand.h +++ b/kernel/inc/lib/Rand.h @@ -4,5 +4,5 @@ #pragma once #include -void rng_init(); -u64 krand(); \ No newline at end of file +void RandInitialize(); +UInt64 Rand(); \ No newline at end of file diff --git a/kernel/inc/core/splash.h b/kernel/inc/lib/Splash.h similarity index 51% rename from kernel/inc/core/splash.h rename to kernel/inc/lib/Splash.h index c7f1606..2851841 100644 --- a/kernel/inc/core/splash.h +++ b/kernel/inc/lib/Splash.h @@ -2,7 +2,7 @@ // Copyright (c) 2025 0xKarinyash #pragma once -#include +#include -void show_splash(SG_Context *sg_ctx); +void SplashShow(IOGraphicsContext* IOGraphicsContextPointer); diff --git a/kernel/inc/lib/String.h b/kernel/inc/lib/String.h new file mode 100644 index 0000000..f715d3a --- /dev/null +++ b/kernel/inc/lib/String.h @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#pragma once +#include + +Int32 strcmp(const char* s1, const char* s2); +Int32 strncmp(const char* s1, const char* s2, UInt64 n); +char* strcpy(char* dest, const char* src); +char* strncpy(char* dest, const char* src, UInt64 n); +void *memset(void *ptr, int value, Size num); +void* memcpy(void* dest, const void* src, UInt64 n); \ No newline at end of file diff --git a/kernel/inc/mm/memory.h b/kernel/inc/mm/memory.h deleted file mode 100644 index 52ae35f..0000000 --- a/kernel/inc/mm/memory.h +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once -#include - -void* memset(void* ptr, int value, usize num); -void* memcpy(void* dest, const void* src, u64 n); diff --git a/kernel/inc/mm/pmm.h b/kernel/inc/mm/pmm.h deleted file mode 100644 index ca454bb..0000000 --- a/kernel/inc/mm/pmm.h +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#pragma once -#include "bootinfo.h" -#include - -#define PAGE_SIZE 4096 -#define BLOCKS_PER_BYTE 8 - -#define SAFE_SPACE_START_ADDR 0x100000 - -#define BITMAP_BYTE_INDEX(addr) ((addr / PAGE_SIZE) / BLOCKS_PER_BYTE) -#define BITMAP_BIT_OFFSET(addr) ((addr / PAGE_SIZE) % BLOCKS_PER_BYTE) -#define BITMAP_TEST(bitmap, addr) (bitmap[BITMAP_BYTE_INDEX(addr)] & (1 << BITMAP_BIT_OFFSET(addr))) -#define BITMAP_SET(bitmap, addr) (bitmap[BITMAP_BYTE_INDEX(addr)] |= (1 << BITMAP_BIT_OFFSET(addr))) -#define BITMAP_UNSET(bitmap, addr) (bitmap[BITMAP_BYTE_INDEX(addr)] &= ~(1 << BITMAP_BIT_OFFSET(addr))) - -u64 pmm_get_total_mem(); -void pmm_init(BI_MemoryMap* mmap); -void* pmm_alloc_page(); -void pmm_free_page(void* addr); diff --git a/kernel/inc/shell/builtins.h b/kernel/inc/shell/builtins.h index af2c384..09b06b2 100644 --- a/kernel/inc/shell/builtins.h +++ b/kernel/inc/shell/builtins.h @@ -3,13 +3,11 @@ #pragma once -void cmd_kfetch(); -void cmd_meow(); -void cmd_help(); -void cmd_regs(); -void print_regs(); -void cmd_sleep(); -void cmd_debug(); -void cmd_rand(); -void cmd_ver(); -void cmd_userspace(); \ No newline at end of file +void KSHCommandKernelFetch(); +void KSHCommandMeow(); +void KSHCommandHelp(); +void KSHCommandRegisters(); +void KSHCommandSleep(); +void KSHCommandDebug(); +void KSHCommandRand(); +void KSHCommandVer(); \ No newline at end of file diff --git a/kernel/inc/shell/dbgcmd.h b/kernel/inc/shell/dbgcmd.h index 049ea93..460fadb 100644 --- a/kernel/inc/shell/dbgcmd.h +++ b/kernel/inc/shell/dbgcmd.h @@ -4,4 +4,4 @@ #pragma once #include -u64 debug(); +UInt64 KSHDebug(); diff --git a/kernel/inc/shell/ksh.h b/kernel/inc/shell/ksh.h index 2283499..516d54b 100644 --- a/kernel/inc/shell/ksh.h +++ b/kernel/inc/shell/ksh.h @@ -2,6 +2,5 @@ // Copyright (c) 2025 0xKarinyash #pragma once -#include void ksh(); diff --git a/kernel/inc/syscalls/io.h b/kernel/inc/syscalls/io.h deleted file mode 100644 index 5ab5626..0000000 --- a/kernel/inc/syscalls/io.h +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#pragma once -#include - -u64 sys_write(u64 fd, u64 buff, u64 len); -u64 sys_read(u64 fd, u64 buff, u64 count); \ No newline at end of file diff --git a/kernel/inc/syscalls/proc.h b/kernel/inc/syscalls/proc.h deleted file mode 100644 index 525fea6..0000000 --- a/kernel/inc/syscalls/proc.h +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#pragma once - -#include - -i32 sys_exit(i32 code); -i32 sys_spawn(const char* path); -i32 sys_wait(u64 pid); \ No newline at end of file diff --git a/kernel/inc/types.h b/kernel/inc/types.h index 383ed27..ca30041 100644 --- a/kernel/inc/types.h +++ b/kernel/inc/types.h @@ -3,55 +3,24 @@ #pragma once -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef unsigned long long u64; +typedef unsigned char UInt8; +typedef unsigned short UInt16; +typedef unsigned int UInt32; +typedef unsigned long long UInt64; -typedef signed char i8; -typedef signed short i16; -typedef signed int i32; -typedef signed long long i64; +typedef signed char Int8; +typedef signed short Int16; +typedef signed int Int32; +typedef signed long long Int64; -typedef u64 usize; -typedef u64 uintptr_t; +typedef UInt64 Size; +typedef UInt64 uintptr_t; typedef struct { - u64 rax, rbx, rcx, rdx, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15; // Pushed by us - u64 int_no, err_code; // Pushed by macro - u64 rip, cs, rflags, rsp, ss; // Pushed by CPU -} Registers; + UInt64 rax, rbx, rcx, rdx, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15; // Pushed by us + UInt64 interruptNumber, errorCode; // Pushed by macro + UInt64 rip, cs, rflags, rsp, ss; // Pushed by CPU +} CPURegisters; -typedef struct { - u32 type; - u32 pad; - u64 physical_start; - u64 virtual_start; - u64 number_of_pages; - u64 attribute; -} __attribute__((packed)) efi_memory_descriptor_k; -typedef enum { - EfiReservedMemoryType, - EfiLoaderCode, - EfiLoaderData, - EfiBootServicesCode, - EfiBootServicesData, - EfiRuntimeServicesCode, - EfiRuntimeServicesData, - EfiConventionalMemory, - EfiUnusableMemory, - EfiACPIReclaimMemory, - EfiACPIMemoryNVS, - EfiMemoryMappedIO, - EfiMemoryMappedIOPortSpace, - EfiPalCode, - EfiPersistentMemory, - EfiMaxMemoryType -} EFI_MEMORY_TYPE; - -#ifndef __cplusplus - #define bool _Bool - #define true 1 - #define false 0 -#endif +#define Boolean _Bool diff --git a/kernel/src/FS/CPIO.c b/kernel/src/FS/CPIO.c new file mode 100644 index 0000000..eb59834 --- /dev/null +++ b/kernel/src/FS/CPIO.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include +#include +#include +#include +#include +#include +#include + +#define FSCPIO_ALIGN4(x) (((x) + 3) & ~3) + +typedef struct FSCPIOHeader { + char magic[6]; + char inode[8]; + char mode[8]; + char userIdentifier[8]; + char groupIdentifier[8]; + char linkCount[8]; + char modificationTime[8]; + char fileLength[8]; + char deviceMajor[8]; + char deviceMinor[8]; + char remoteDeviceMajor[8]; + char remoteDeviceMinor[8]; + char nameLength[8]; + char checkSum[8]; +} FSCPIOHeader; + +static FSVNodeOperations gFSCPIOOperations = { + .read = FSCPIORead, + .write = nullptr, + .open = nullptr, + .close = nullptr, +}; + +static UInt64 sFSCPIOHexadecimalToUInt64(const char* string, Int32 length) { + UInt64 result = 0; + for (Int32 i = 0; i < length; i++) { + char character = string[i]; + result <<= 4; + if (character >= '0' && character <= '9') result += (character - '0'); + else if (character >= 'A' && character <= 'F') result += (character - 'A' + 10); + else if (character >= 'a' && character <= 'f') result += (character - 'a' + 10); + } + return result; +} + +UInt64 FSCPIORead(FSVNode* node, UInt64 offset, UInt64 size, UInt8* buffer) { + if (offset > node->dataLength) return 0; + if ((offset + size) > node->dataLength) size = node->dataLength - offset; + + memcpy(buffer, (char*)node->implementationData + offset, size); + return size; +} + +FSVNode* FSCPIOMount(void* baseAddress, UInt64 totalSize) { + UInt8* currentPointer = (UInt8*)baseAddress; + UInt8* endPointer = currentPointer + totalSize; + + FSVNode* rootNode = (FSVNode*)malloc(sizeof(FSVNode)); + if (!rootNode) OSPanic("CPIO: Failed to allocate memory for root node"); + + memset(rootNode, 0, sizeof(FSVNode)); + strcpy(rootNode->name, "/"); + rootNode->flags = kFSVNodeFlagDirectory; + rootNode->operations = &gFSCPIOOperations; + + FSVNode* tailNode = nullptr; + + while (currentPointer < endPointer) { + FSCPIOHeader* header = (FSCPIOHeader*)currentPointer; + + if (strncmp(header->magic, "070701", 6) != 0) { + OSPanic("CPIO: Invalid magic detected in initramfs"); + } + + UInt64 nameSize = sFSCPIOHexadecimalToUInt64(header->nameLength, 8); + UInt64 fileSize = sFSCPIOHexadecimalToUInt64(header->fileLength, 8); + + char* fileName = (char*)(currentPointer + sizeof(FSCPIOHeader)); + if (strcmp(fileName, "TRAILER!!!") == 0) break; + + UInt64 headerAndNameLength = sizeof(FSCPIOHeader) + nameSize; + UInt64 offsetToData = FSCPIO_ALIGN4(headerAndNameLength); + void* fileContent = (void*)(currentPointer + offsetToData); + + FSVNode* newNode = (FSVNode*)malloc(sizeof(FSVNode)); + if (!newNode) OSPanic("CPIO: Failed to allocate memory for new node"); + + memset(newNode, 0, sizeof(FSVNode)); + strncpy(newNode->name, fileName, sizeof(newNode->name) - 1); + + newNode->dataLength = fileSize; + newNode->inodeIdentifier = sFSCPIOHexadecimalToUInt64(header->inode, 8); + newNode->operations = &gFSCPIOOperations; + newNode->implementationData = fileContent; + + UInt64 mode = sFSCPIOHexadecimalToUInt64(header->mode, 8); + if ((mode & 0xF000) == 0x4000) { + newNode->flags = kFSVNodeFlagDirectory; + } else { + newNode->flags = kFSVNodeFlagFile; + } + + if (rootNode->childNode == nullptr) { + rootNode->childNode = newNode; + } else if (tailNode) { + tailNode->nextNode = newNode; + } + + tailNode = newNode; + + IOConsoleLog("^bCPIO^!: Found object '^y%s^!' (size: ^y%d^!) at ^y0x%x^!\n", fileName, fileSize, fileContent); + + UInt64 dataLengthAligned = FSCPIO_ALIGN4(fileSize); + currentPointer += offsetToData + dataLengthAligned; + } + + return rootNode; +} \ No newline at end of file diff --git a/kernel/src/FS/VFS.c b/kernel/src/FS/VFS.c new file mode 100644 index 0000000..336bc74 --- /dev/null +++ b/kernel/src/FS/VFS.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include +#include + +FSVNode* gFSVirtualFileSystemRoot = nullptr; + +void FSVirtualFileSystemInitialize(FSVNode* rootNode) { + gFSVirtualFileSystemRoot = rootNode; +} + +UInt64 FSVNodeRead(FSVNode* node, UInt64 offset, UInt64 size, UInt8* buffer) { + if (!node || !node->operations || !node->operations->read) { + return 0; + } + + return node->operations->read(node, offset, size, buffer); +} + +FSVNode* FSVirtualFileSystemOpenPath(const char* path) { + if (!gFSVirtualFileSystemRoot) { + return nullptr; + } + + if (strcmp(path, "/") == 0) { + return gFSVirtualFileSystemRoot; + } + + const char* searchName = path; + if (path[0] == '/') { + searchName++; + } + + FSVNode* nodeIterator = gFSVirtualFileSystemRoot->childNode; + while (nodeIterator != nullptr) { + if (strcmp(nodeIterator->name, searchName) == 0) { + if (nodeIterator->operations && nodeIterator->operations->open) { + nodeIterator->operations->open(nodeIterator); + } + return nodeIterator; + } + nodeIterator = nodeIterator->nextNode; + } + + return nullptr; +} + +void FSVNodeClose(FSVNode* node) { + if (node && node->operations && node->operations->close) { + node->operations->close(node); + } +} \ No newline at end of file diff --git a/kernel/src/IO/IOConsole.c b/kernel/src/IO/IOConsole.c new file mode 100644 index 0000000..6e2d291 --- /dev/null +++ b/kernel/src/IO/IOConsole.c @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include + +static IOGraphicsContext* sIOGraphicsContextPointer = nullptr; +static IOGraphicsPoint sIOConsoleCursorPosition = {0}; +static IOGraphicsFont sIOConsoleFont = {0}; +static IOGraphicsColor sIOConsoleForegroundColor = kIOConsoleColorWhite; +static IOGraphicsColor sIOConsoleDefaultForegroundColor = kIOConsoleColorWhite; +static IOGraphicsColor sIOConsoleBackgroundColor = kIOConsoleColorBlack; + +void IOConsoleInit(IOGraphicsContext *context) { + sIOGraphicsContextPointer = context; + sIOConsoleCursorPosition.x = 0; + sIOConsoleCursorPosition.y = 0; + + sIOConsoleFont.size.height = 16; + sIOConsoleFont.size.width = 8; + sIOConsoleFont.baseAddress = (const unsigned char*)VGAFont; +} + +UInt64 IOConsoleGetColors() { + return ((UInt64) sIOConsoleForegroundColor << 32) | sIOConsoleBackgroundColor; +} + +void IOConsoleClear(IOGraphicsColor color) { + if (!sIOGraphicsContextPointer) return; + + IOGraphicsPoint point = {0, 0}; + IOGraphicsDrawRectangle( + sIOGraphicsContextPointer, + &point, + &sIOGraphicsContextPointer->dimensions, + color + ); + + sIOConsoleCursorPosition.x = 0; + sIOConsoleCursorPosition.y = 0; + sIOConsoleBackgroundColor = color; +} + +IOGraphicsContext* IOConsoleGetGraphicsContext() { + return sIOGraphicsContextPointer; +} + +IOGraphicsSize IOConsoleGetDimensions() { + return sIOGraphicsContextPointer->dimensions; +} + +void IOConsoleSetCursorPosition(IOGraphicsPoint* point) { + if (!point) return; + sIOConsoleCursorPosition.x = point->x; + sIOConsoleCursorPosition.y = point->y; +} + +void IOConsolePutcharacter(char character) { + IOSerialWriteChar(character); + if (!sIOGraphicsContextPointer) return; + if (character == '\n') { + sIOConsoleCursorPosition.x = 0; + sIOConsoleCursorPosition.y += sIOConsoleFont.size.height; + } else if (character == '\t') { + sIOConsoleCursorPosition.x += sIOConsoleFont.size.width * 4; + } else if (character == '\b') { + sIOConsoleCursorPosition.x -= sIOConsoleFont.size.width; + IOGraphicsDrawRectangle( + sIOGraphicsContextPointer, + &sIOConsoleCursorPosition, + &sIOConsoleFont.size, + sIOConsoleBackgroundColor + ); + } else { + IOGraphicsDrawCharacter( + sIOGraphicsContextPointer, + &sIOConsoleCursorPosition, + character, + sIOConsoleForegroundColor, + &sIOConsoleFont + ); + sIOConsoleCursorPosition.x += sIOConsoleFont.size.width; + } + + if (sIOConsoleCursorPosition.x >= sIOGraphicsContextPointer->dimensions.width) { + sIOConsoleCursorPosition.x = 0; + sIOConsoleCursorPosition.y += sIOConsoleFont.size.height; + } + if (sIOConsoleCursorPosition.y >= sIOGraphicsContextPointer->dimensions.height) { + IOConsoleClear(sIOConsoleBackgroundColor); // TODO: do scrolling + } +} + +void IOConsolePrint(const char *string) { + for (Int32 i = 0; string[i] != '\0'; i++) IOConsolePutcharacter(string[i]); +} + +static void sIOConsolePrintDecimal(const Int64 number) { + if (number < 0) IOConsolePutcharacter('-'); + UInt64 unsignedNumber = abs(number); + char buffer[32]; + Int32 i = 0; + + do { + buffer[i] = (unsignedNumber % 10) + '0'; + unsignedNumber /= 10; + i++; + } while (unsignedNumber > 0); + + while (--i >= 0) { + IOConsolePutcharacter(buffer[i]); + } +} + +static void sIOConsolePrintHexadecimal(UInt64 unsignedNumber, UInt8 padding) { + IOConsolePutcharacter('0'); + IOConsolePutcharacter('x'); + + if (unsignedNumber == 0) { + IOConsolePutcharacter('0'); + for (Int32 i = 1; i < padding; i++) IOConsolePutcharacter('0'); + return; + } + + char buffer[16] = {0}; + Int32 i = 0; + + do { + Int32 digit = unsignedNumber % 16; + if (digit < 10) buffer[i++] = digit + '0'; + else buffer[i++] = digit - 10 + 'A'; + unsignedNumber /= 16; + } while (unsignedNumber > 0); + + while(i < padding) { + IOConsolePutcharacter('0'); + padding--; + } + + while (--i >= 0) { + IOConsolePutcharacter(buffer[i]); + } +} + + +void IOConsoleLog(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + + for (Int32 i = 0; fmt[i] != '\0'; i++) { + if (fmt[i] == '%') { + i++; + switch (fmt[i]) { + case 's': { + const char *string = va_arg(args, const char*); + if (!string) string = "undefined"; + IOConsolePrint(string); + break; + } + case 'c': { + char character = (char)va_arg(args, int); + IOConsolePutcharacter(character); + break; + } + case 'd': { + Int32 number = va_arg(args, Int32); + sIOConsolePrintDecimal(number); + break; + } + case 'x': { + UInt64 number = va_arg(args, UInt64); + sIOConsolePrintHexadecimal(number, 0); + break; + } + case 'X' : { + UInt64 number = va_arg(args, UInt64); + sIOConsolePrintHexadecimal(number, 16); + break; + } + default: { + IOConsolePutcharacter(fmt[i]); + break; + } + } + } else if (fmt[i] == '^') { + i++; + switch (fmt[i]) { + case 'r': IOConsoleSetForegroundColor(kIOConsoleColorRed); break; + case 'R': IOConsoleSetForegroundColor(kIOConsoleColorVeryRed); break; + case 'g': IOConsoleSetForegroundColor(kIOConsoleColorGreen); break; + case 'G': IOConsoleSetForegroundColor(kIOConsoleColorVeryGreen); break; + case 't': IOConsoleSetForegroundColor(kIOConsoleColorTurqoise); break; + case 'b': IOConsoleSetForegroundColor(kIOConsoleColorBlue); break; + case 'B': IOConsoleSetForegroundColor(kIOConsoleColorVeryBlue); break; + case 'l': IOConsoleSetForegroundColor(kIOConsoleColorLightBlue); break; + case 'y': IOConsoleSetForegroundColor(kIOConsoleColorYellow); break; + case 'c': IOConsoleSetForegroundColor(kIOConsoleColorCyan); break; + case 'm': IOConsoleSetForegroundColor(kIOConsoleColorMagneta); break; + case 'p': IOConsoleSetForegroundColor(kIOConsoleColorPink); break; + case '0': IOConsoleSetForegroundColor(kIOConsoleColorBlack); break; + case 'w': IOConsoleSetForegroundColor(kIOConsoleColorWhite); break; + + case '!': IOConsoleSetForegroundColor(sIOConsoleDefaultForegroundColor); break; + case '~': IOConsoleSetForegroundColor(~sIOConsoleBackgroundColor); break; + + case '^': IOConsolePutcharacter('^'); break; + + default: { + IOConsolePutcharacter('^'); + IOConsolePutcharacter(fmt[i]); + break; + } + } + } else { + IOConsolePutcharacter(fmt[i]); + } + } + + va_end(args); +} + +void IOConsoleSetForegroundColor(UInt32 color) { + sIOConsoleForegroundColor = color; +} + +void IOConsoleSetDefaultForegroundColor(UInt32 color) { + sIOConsoleDefaultForegroundColor = color; +} + +char IOConsoleGetCharacter() { + while (gIOKeyboardInputBuffer.head == gIOKeyboardInputBuffer.tail) { __asm__ volatile ("sti"); OSSchedulerYield(1); } + __asm__ volatile ("cli"); + char temp = gIOKeyboardInputBuffer.buffer[gIOKeyboardInputBuffer.tail]; + gIOKeyboardInputBuffer.tail = (gIOKeyboardInputBuffer.tail + 1) % kIOKeyboardBufferSize; + __asm__ volatile ("sti"); + return temp; +} + +void IOConsoleReadLine(char* buffer, UInt32 limit) { + UInt32 i = 0; + while (true) { + char character = IOConsoleGetCharacter(); + switch (character) { + case '\n': { + buffer[i] = '\0'; + IOConsoleLog("\n"); + return; + } + case '\b': { + if (i > 0) { + i--; + IOConsoleLog("\b \b"); + } + break; + } + default: { + if (i < limit - 1) { + buffer[i] = character; + IOConsoleLog("%c", character); + i++; + } + } + } + } +} \ No newline at end of file diff --git a/kernel/src/IO/IOGraphics.c b/kernel/src/IO/IOGraphics.c new file mode 100644 index 0000000..9a71013 --- /dev/null +++ b/kernel/src/IO/IOGraphics.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash +// RIP shitgui -- you started it all + +#include +#include +#include +#include +#include + +enum { + kIOGraphicsTransparencyKey = 0xFF00FF +}; + +UInt32 IOGraphicsGetPixel(IOGraphicsContext* context, IOGraphicsPoint* point) { + if (!context->framebuffer || !point || point->x >= context->dimensions.width || point->y >= context->dimensions.height) return 0; + return context->framebuffer[point->y * context->pixelsPerScanLine + point->x]; +} + +void IOGraphicsDrawImage(IOGraphicsContext* context, IOGraphicsPoint* point, IOGraphicsImage* image) { + if (!context->framebuffer || !image) return; + + UInt32 startX = point->x; + UInt32 startY = point->y; + UInt32 drawW = image->size.width; + UInt32 drawH = image->size.height; + + if (startX >= context->dimensions.width || startY >= context->dimensions.height) return; + if (startX + drawW > context->dimensions.width) drawW = context->dimensions.width - startX; + if (startY + drawH > context->dimensions.height) drawH = context->dimensions.height - startY; + + for (UInt32 y = 0; y < drawH; y++) { + volatile UInt32 *destinationPointer = &context->framebuffer[(startY + y) * context->pixelsPerScanLine + startX]; + UInt32 *sourcePointer = &image->buffer[y * image->size.width]; + for (UInt32 x = 0; x < drawW; x++) { + UInt32 color = sourcePointer[x]; + if (color != kIOGraphicsTransparencyKey) destinationPointer[x] = color; + } + } +} + +void IOGraphicsDrawRectangle(IOGraphicsContext* context, IOGraphicsPoint* point, IOGraphicsSize* size, IOGraphicsColor color) { + if (!context->framebuffer) return; + + UInt32 startX = point->x; + UInt32 startY = point->y; + UInt32 drawW = size->width; + UInt32 drawH = size->height; + + if (startX >= context->dimensions.width || startY >= context->dimensions.height) return; + if (startX + drawW > context->dimensions.width) drawW = context->dimensions.width - startX; + if (startY + drawH > context->dimensions.height) drawH = context->dimensions.height - startY; + + + for (UInt32 y = 0; y < drawH; y++) { + volatile UInt32* rowPointer = &context->framebuffer[(startY + y) * context->pixelsPerScanLine + startX]; + for (UInt32 x = 0; x < drawW; x++) rowPointer[x] = color; + } +} + +void IOGraphicsDrawCharacter(IOGraphicsContext* context, IOGraphicsPoint* point, char c, IOGraphicsColor color, IOGraphicsFont* font) { + if (!context->framebuffer) return; + + UInt32 startX = point->x; + UInt32 startY = point->y; + UInt32 drawW = font->size.width; + UInt32 drawH = font->size.height; + + if (startX >= context->dimensions.width || startY >= context->dimensions.height) return; + if (startX + drawW > context->dimensions.width) drawW = context->dimensions.width - startX; + if (startY + drawH > context->dimensions.height) drawH = context->dimensions.height - startY; + + for (UInt32 y = 0; y < drawH; y++) { + UInt8 bitmapRow = font->baseAddress[(unsigned char)c * font->size.height + y]; + volatile UInt32 *rowPointer = &context->framebuffer[(startY + y) * context->pixelsPerScanLine + startX]; + for (UInt32 x = 0; x < drawW; x++) { + if (bitmapRow & (1 << (7 - x))) { + rowPointer[x] = color; + } + } + } +} \ No newline at end of file diff --git a/kernel/src/drivers/keyboard.c b/kernel/src/IO/IOKeyboard.c similarity index 75% rename from kernel/src/drivers/keyboard.c rename to kernel/src/IO/IOKeyboard.c index d2da2d3..23cb4b2 100644 --- a/kernel/src/drivers/keyboard.c +++ b/kernel/src/IO/IOKeyboard.c @@ -1,13 +1,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2025 0xKarinyash -#include -#include +#include +#include -#include +#include #include -unsigned char keyboard_map[128] = { +static unsigned char sIOKeyboardMap[128] = { 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 0x00 - 0x09 */ '9', '0', '-', '=', '\b', /* Backspace */ '\t', /* Tab */ @@ -46,7 +46,7 @@ unsigned char keyboard_map[128] = { 0, /* All other keys are undefined */ }; -unsigned char keyboard_map_shifted[128] = { +static unsigned char sIOKeyboardMapShifted[128] = { 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', /* 0x00 - 0x09 */ '(', ')', '_', '+', '\b', /* Backspace */ '\t', /* Tab */ @@ -85,29 +85,30 @@ unsigned char keyboard_map_shifted[128] = { 0, /* All other keys */ }; -bool shift_pressed = false; -kb_buffer kb_buf = {0}; +static Boolean sIOKeyboardIsShiftPressed = false; -void kb_handler() { - u16 next_head = (kb_buf.head + 1) % KB_BUFF_SIZE; +IOKeyboardBuffer gIOKeyboardInputBuffer = {0}; - u8 scancode = inb(0x60); +void IOKeyboardInterruptsHandler() { + UInt16 nextHead = (gIOKeyboardInputBuffer.head + 1) % kIOKeyboardBufferSize; + + UInt8 scancode = IOPortRead8(0x60); // make code 0x00 - 0x7F; break code = make code + 0x80 if (scancode < 0x80) { - unsigned char* arr = shift_pressed ? keyboard_map_shifted : keyboard_map; - char ascii = arr[scancode]; - if (ascii && next_head != kb_buf.tail) { - kb_buf.buffer[kb_buf.head] = ascii; - kb_buf.head = next_head; + unsigned char* keyMap = sIOKeyboardIsShiftPressed ? sIOKeyboardMapShifted : sIOKeyboardMap; + char ascii = keyMap[scancode]; + if (ascii && nextHead != gIOKeyboardInputBuffer.tail) { + gIOKeyboardInputBuffer.buffer[gIOKeyboardInputBuffer.head] = ascii; + gIOKeyboardInputBuffer.head = nextHead; } else { switch (scancode) { - case 0x2A: shift_pressed = true; break; + case 0x2A: sIOKeyboardIsShiftPressed = true; break; default: break; } } } else { switch (scancode) { - case 0xAA: shift_pressed = false; break; + case 0xAA: sIOKeyboardIsShiftPressed = false; break; default: break; } } diff --git a/kernel/src/IO/IOSerial.c b/kernel/src/IO/IOSerial.c new file mode 100644 index 0000000..bd33145 --- /dev/null +++ b/kernel/src/IO/IOSerial.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#include +#include + +enum { + kIOCom1Port = 0x3F8, +}; + +int IOSerialInit() { + IOPortWrite8(kIOCom1Port + 1, 0x00); // interrupt enable register (+1) / disable interruptions + IOPortWrite8(kIOCom1Port + 3, 0x80); // line control register (+3) + IOPortWrite8(kIOCom1Port + 0, 0x03); // speed : low byte + IOPortWrite8(kIOCom1Port + 1, 0x00); // speed : high byte + IOPortWrite8(kIOCom1Port + 3, 0x03); // line control register (+3) / reset DLAB / no parity / 1 stop bit / (8N1) + IOPortWrite8(kIOCom1Port + 2, 0xC7); // FIFO Control register (+2) / 1100 0111 / last ones are enable FIFO buff / first ones to clean noise + IOPortWrite8(kIOCom1Port + 4, 0x0B); // ready :3 + return 0; +} + +static int IOCheckIsTransmitEmpty() { + return IOPortRead8(kIOCom1Port + 5) & 0x20; // checking 5th bit LSR +} + +void IOSerialWriteChar(char character) { + while (IOCheckIsTransmitEmpty() == 0); // waiting for buffer to flush (spinlock) + IOPortWrite8(kIOCom1Port, character); +} + +void IOSerialWrite(const char* string) { + for (int i = 0; string[i] != '\0'; i++) IOSerialWriteChar(string[i]); +} \ No newline at end of file diff --git a/kernel/src/IO/IOTimer.c b/kernel/src/IO/IOTimer.c new file mode 100644 index 0000000..b25b6d2 --- /dev/null +++ b/kernel/src/IO/IOTimer.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#include +#include +#include +#include + +enum { + kIOTimerPitBaseClock = 1193180, + kIOTimerPitCommand = 0x43, + kIOTimerPitData = 0x40, +}; + +static volatile UInt64 sIOTimerTicks = 0; + +void IOTimerInitialize(UInt32 frequency) { + UInt32 divisor = kIOTimerPitBaseClock / frequency; + + IOPortWrite8(kIOTimerPitCommand, 0x36); // 0x36 = 00110110 = channel 0, LOHI byte access, Mode 3, binary + IOPortWrite8(kIOTimerPitData, divisor & 0xFF); + IOPortWrite8(kIOTimerPitData, (divisor >> 8) & 0xFF); + + UInt8 mask = IOPortRead8(0x21); + mask &= ~(1 << 0); + IOPortWrite8(0x21, mask); +} + +UInt64 IOTimerInterruptsHandler(CPURegisters *registers) { + sIOTimerTicks++; + return OSSchedulerNext((UInt64)registers); +} + +UInt64 IOTimerGetTicks() { + return sIOTimerTicks; +} \ No newline at end of file diff --git a/kernel/src/OS/Exec/HOTLoader.c b/kernel/src/OS/Exec/HOTLoader.c new file mode 100644 index 0000000..a9cbe60 --- /dev/null +++ b/kernel/src/OS/Exec/HOTLoader.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include +#include +#include + +#include +#include +#include + +#include "../../common/hot_header.h" + +UInt64 HOTLoad(OSProcess* process, UInt8* data) { + HOTHeader* header = (HOTHeader*)data; + if (header->magic != HOT_MAGIC) { + return -1; + } + + HOTSegment* segments = (HOTSegment*)(data + sizeof(HOTHeader)); + for (UInt64 i = 0; i < header->segments_count; i++) { + HOTSegment* segment = &segments[i]; + if (segment->memsz == 0) continue; + + UInt64 start = segment->vaddr & ~(0xFFFULL); + UInt64 end = (segment->vaddr + segment->memsz + 0xFFF) & ~(0xFFFULL); + + for (UInt64 address = start; address < end; address += kVMPageSize) { + void* physicalPage = VMPhysicalMemoryAllocatePage(); + VMVirtualMemoryMapPage((UInt64*)process->physicalPML4, (UInt64)physicalPage, address, PTE_USER | PTE_RW | PTE_PRESENT); + void* kernelVirtAddress = (void*)((UInt64)physicalPage + HHDM_OFFSET); + memset(kernelVirtAddress, 0, kVMPageSize); + UInt64 pageOverleapStart = (address > segment->vaddr) ? address : segment->vaddr; + UInt64 pageOverleapEnd = (address + kVMPageSize < segment->vaddr + segment->filesz) + ? (address + kVMPageSize) + : (segment->vaddr + segment->filesz); + if (pageOverleapStart < pageOverleapEnd) { + UInt64 copySize = pageOverleapEnd - pageOverleapStart; + UInt64 sourceOffset = segment->offset + (pageOverleapStart - segment->vaddr); + UInt64 destinationOffset = pageOverleapStart - address; + + memcpy((UInt8*)kernelVirtAddress + destinationOffset, data + sourceOffset, copySize); + } + } + } + + return header->entry_point; +} \ No newline at end of file diff --git a/kernel/src/OS/Exec/OSLoader.c b/kernel/src/OS/Exec/OSLoader.c new file mode 100644 index 0000000..6c4204e --- /dev/null +++ b/kernel/src/OS/Exec/OSLoader.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include +#include +#include +#include +#include + + +#include +#include +#include + +#include + +#include +#include + +extern UInt32 gOSSchedulerNextProcessID; + +enum { + kOSUserStackTop = 0x70000000, + kOSHeapStart = 0x40000000 +}; + + +Int32 OSLoaderProcessSpawn(const char* executablePath, const char* processName) { + FSVNode* executableFile = FSVirtualFileSystemOpenPath(executablePath); + if (!executableFile) { + return -1; + } + + OSProcess* newProcess = (OSProcess*)malloc(sizeof(OSProcess)); + if (!newProcess) { + return -2; + } + + memset(newProcess, 0, sizeof(OSProcess)); + newProcess->processId = gOSSchedulerNextProcessID++; + newProcess->state = kOSProcessStateRunning; + newProcess->physicalPML4 = VMVirtualMemoryCreateAddressSpace(); + newProcess->heapStartPointer = kOSHeapStart; + newProcess->heapCurrentPointer = kOSHeapStart; + strncpy(newProcess->name, processName, 31); + + UInt8* imageBuffer = (UInt8*)malloc(executableFile->dataLength); + if (!imageBuffer) { + free(newProcess); + return -3; + } + + FSVNodeRead(executableFile, 0, executableFile->dataLength, imageBuffer); + + UInt64 entryPoint = HOTLoad(newProcess, imageBuffer); + if (!entryPoint) { + free(imageBuffer); + free(newProcess); + return -4; + } + + free(imageBuffer); + + VMVirtualMemorySetupUserStack((UInt64*)newProcess->physicalPML4); + + OSSchedulerSpawn((void(*)())entryPoint, newProcess, true, kOSUserStackTop); + + return newProcess->processId; +} + +void init_task_entry() { + Int32 pid = OSLoaderProcessSpawn("/bin/init", "init"); + if (pid < 0) { + OSPanic("FATAL: Failed to spawn /bin/init"); + } + + while (1) { __asm__("sti; hlt"); } +} \ No newline at end of file diff --git a/kernel/src/OS/OSPanic.c b/kernel/src/OS/OSPanic.c new file mode 100644 index 0000000..1a266da --- /dev/null +++ b/kernel/src/OS/OSPanic.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#include +#include + +#include +#include + +#include + +static const char* sOSPanicFunMessages[] = { + "Execution finished abnormally with code: 0x_x", + "It's definitely your fault.", + "No more Roblox!", + "Call your mom 4 help!", + "2bad4u", + "Touch grass", + "Skill issue", + "You should just go outside actually", + "Perfect opportunity to take a shower", + "404 not found", + "Windows is locked! Password:___ Time left: 5:45:41", + "GOOOOOAL", + "\"NAM PIZDA\": hackers dropped our registry", + "geeked vs locked in", + "HEEEELP!", + "LET ME GO!", + "You little asshole, make it better", + "Go and read books for programming u idiot", + "TIME TO BRAKE! :3 Take a tea and try again later cutie", + "Code have been eaten by Aliens", + "That's all, folks!", + "Raiden, answer me, Raiden, respond! Raiden?! RAIDEEEEEEEEEN!", + "I'll be back", + "Hastla la vista, baby", + "Ti chego mne tut nagovoril...", + "Your access has been denied because of your region.\n\t\t\t\tPlease, use Chultem VPN and try again later.", + "Fatal error has been occurred. \n\t\t\t\tYour device will be transformed into Niva in a few seconds.", + "Have you tried turning it off and on again?", + "Put it in rice maybe?", + "Just hit the monitor, it usually helps", + "I think it needs a rest. Come back tomorrow", + "You clicked something wrong, didn't you?", + "You hacked it too hard, bro", + "I think you deleted the internet", + "Stop downloading RAM", + "Pro tip: dont crash", + "Stop ricing the kernel you loonixtard, TermOS is NOT Loonix", + "Attaboy, Jack. He's good. Really good.", + "Zhenih priehal", + "YOUR PC WAS BLOCKED BY FBI FOR WATCHING PORNOGRAPHY SEND 20 US DOLLARS", + "fuck off", + "Your GPU is now mining Ethereum for me. Thanks.", + "Your PC is locked!\n\t\t\t\tPay a fee of 0.019082006 bitcoins to a wallet 1KtoProchitalTotSosal to get decryption key!", +}; + + +static const char* sOSPanicExceptionMessages[] = { + "Division By Zero", + "Debug", + "Non Maskable Interrupt", + "Breakpoint", + "Into Detected Overflow", + "Out of Bounds", + "Invalid Opcode", + "Device Not Available", + "Double Fault", + "Coprocessor Segment Overrun", + "Bad TSS", + "Segment Not Present", + "Stack Fault", + "General Protection Fault", + "Page Fault", + "Reserved", + "x87 Floating-Point Exception", + "Alignment Check", + "Machine Check", + "SIMD Floating-Point Exception", + "Virtualization Exception", + "Control Protection Exception", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Hypervisor Injection Exception", + "VMM Communication Exception", + "Security Exception", + "Reserved" +}; + +__attribute__((noreturn)) static void die() { + while (1) { + __asm__ volatile ("cli; hlt"); + } +} + +static void sOSPanicDrawPanicBackground() { + IOConsoleClear(0x000000); + IOConsoleSetForegroundColor(0xFFFFFF); + IOConsoleSetDefaultForegroundColor(0xFFFFFF); + + UInt64 funMessagesCount = sizeof(sOSPanicFunMessages) / sizeof(sOSPanicFunMessages[0]); + UInt8 randNum = Rand() % funMessagesCount; + + IOConsoleLog("\n\n"); + IOConsoleLog("\t\t\t\t^bKERNEL PANIC^! :( \n"); + IOConsoleLog("\t\t--------------------------------\n"); + IOConsoleLog("\t\t^y%s^!\n", sOSPanicFunMessages[randNum]); + IOConsoleLog("\t\t--------------------------------\n"); +} + +__attribute__((noreturn)) void OSPanicException(CPURegisters* frame) { + sOSPanicDrawPanicBackground(); + + IOConsoleLog("\t\t^yCPU EXCEPTION^!: ^b%s^! (%d)\n", sOSPanicExceptionMessages[frame->interruptNumber], frame->interruptNumber); + if (frame->errorCode) IOConsoleLog("\t\t^yError Code^!: %X\n", frame->errorCode); + IOConsoleLog("\t\t^yInstruction Pointer^! (^yRIP^!): %X\n", frame->rip); + IOConsoleLog("\t\t^yCode Segment^! (^yCS^!): %X\n", frame->cs); + IOConsoleLog("\t\t^yFlags^! (^yRFLAGS^!): %X\n", frame->rflags); + IOConsoleLog("\t\t^yStack Pointer^! (^yRSP^!): %X\n", frame->rsp); + if (frame->interruptNumber == 14) { + IOConsoleLog("\t\t--------------------------------\n"); + IOConsoleLog("\t\t ^yPage Fault Helper^! \n"); + IOConsoleLog("\t\t--------------------------------\n"); + UInt64 cr2; + __asm__ volatile("mov %%cr2, %0" : "=r"(cr2)); + IOConsoleLog("\t\t^yFaulting Address^! (^yCR2^!): %X\n", cr2); + IOConsoleLog("\t\t^yERRCode^!: %X\n", frame->errorCode); + UInt64 present = (frame->errorCode & (1 << 0)) != 0; + UInt64 write = (frame->errorCode & (1 << 1)) != 0; + UInt64 user = (frame->errorCode & (1 << 2)) != 0; + UInt64 reserved = (frame->errorCode & (1 << 3)) != 0; + UInt64 instruction = (frame->errorCode & (1 << 4)) != 0; + IOConsoleLog("\t\t\t[^bP^!] ^yReason^!: %s\n", present ? "Page Protection violation" : "Non-present page"); + IOConsoleLog("\t\t\t[^bW^!] ^yCaused by^! %s\n", write ? "WRITE" : "READ"); + IOConsoleLog("\t\t\t[^bU^!] ^yRing^! %s\n", user ? "3" : "0"); + if (reserved) IOConsoleLog("\t\t\t[^bR^!] CPU Wrote 1 to a reserved field in page table entry. ^rCorrupt page table?^!\n"); + if (instruction) IOConsoleLog("\t\t\t[^bI^!] ^yTried to^! execute ^ycode from^! NX ^ymemory^!\n"); + } + IOConsoleLog("\t\t--------------------------------\n"); + IOConsoleLog("\t\t\t\t^yREGISTERS^!\n"); + IOConsoleLog("\t\t--------------------------------\n"); + IOConsoleLog("\t\t^yRAX^!=%X, ^yRBX^!=%X\n", frame->rax, frame->rbx); + IOConsoleLog("\t\t^yRCX^!=%X, ^yRDX^!=%X\n", frame->rcx, frame->rdx); + IOConsoleLog("\t\t^yRSI^!=%X, ^yRDI^!=%X\n", frame->rsi, frame->rdi); + IOConsoleLog("\t\t^yRBP^!=%X, ^yR8^! =%X\n", frame->rbp, frame->r8); + IOConsoleLog("\t\t^yR9^! =%X, ^yR10^!=%X \n", frame->r9, frame->r10); + IOConsoleLog("\t\t^yR11^!=%X, ^yR12^!=%X\n", frame->r11, frame->r12); + IOConsoleLog("\t\t^yR13^!=%X, ^yR14^!=%X\n", frame->r13, frame->r14); + IOConsoleLog("\t\t^yR15^!=%X\n",frame->r15); + IOConsoleLog("\t\t--------------------------------\n"); + IOConsoleLog("\t\t\t\t^bSystem halted.^!\n"); + + die(); +} + +__attribute__((noreturn)) void OSPanic(const char* message) { + sOSPanicDrawPanicBackground(); + + IOConsoleLog("\t\t^yReason^!: %s\n", message); + IOConsoleLog("\t\t--------------------------------\n"); + IOConsoleLog("\t\t\t\t^bSystem halted.^!\n"); + + die(); +} \ No newline at end of file diff --git a/kernel/src/OS/OSScheduler.c b/kernel/src/OS/OSScheduler.c new file mode 100644 index 0000000..611d85f --- /dev/null +++ b/kernel/src/OS/OSScheduler.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#include +#include +#include +#include +#include +#include +#include + +OSTask* gOSSchedulerCurrentTask = nullptr; +UInt32 gOSSchedulerNextProcessID = 1; + +extern void irq0_handler(); +extern UInt64 gVMKernelPML4Physical; + +static OSProcess sOSSchedulerKernelProcess; + +void idle_task() { + while (1) { + __asm__ volatile ("hlt"); + } +} + +void OSSchedulerInitialize() { + sOSSchedulerKernelProcess.processId = 0; + sOSSchedulerKernelProcess.state = kOSProcessStateRunning; + sOSSchedulerKernelProcess.physicalPML4 = gVMKernelPML4Physical; + strcpy(sOSSchedulerKernelProcess.name, "kernel"); + + OSTask* kernelTask = (OSTask*)malloc(sizeof(OSTask)); + memset(kernelTask, 0, sizeof(OSTask)); + kernelTask->id = 0; + kernelTask->process = &sOSSchedulerKernelProcess; + kernelTask->sleepTicks = 0; + kernelTask->next = kernelTask; + kernelTask->taskState = kOSProcessStateRunning; + kernelTask->waitingForProcess = -1; + + gOSSchedulerCurrentTask = kernelTask; + OSSchedulerSpawn(idle_task, &sOSSchedulerKernelProcess, false, 0); +} + +OSTask* OSSchedulerSpawn(void(*entry)(), OSProcess* owner, Boolean isUser, UInt64 fixedUserStackPointer) { + OSTask* task = (OSTask*)malloc(sizeof(OSTask)); + if (!task) return nullptr; + if (!owner) owner = &sOSSchedulerKernelProcess; + + UInt64 stackSize = 16384; + UInt8* stackBaseAddress = (UInt8*)malloc(stackSize); + if (!stackBaseAddress) OSPanic("OOM for task stack"); + UInt64* rsp = (UInt64*)(stackBaseAddress + stackSize); + + UInt64 cs = isUser ? 0x23 : 0x08; + UInt64 ss = isUser ? 0x1b : 0x10; + UInt64 rflags = 0x202; + UInt64 targetStackPointer = 0; + if (isUser) targetStackPointer = fixedUserStackPointer; + else targetStackPointer = (UInt64)stackBaseAddress + stackSize; + + *--rsp = ss; // SS -- Kernel data + *--rsp = targetStackPointer; // rsp + *--rsp = rflags; // RFLAGS -- Interrupts Enabled | Reserved bit; + *--rsp = cs; // CS -- Kernel Code; + *--rsp = (UInt64)entry; // RIP + + *--rsp = 0; // int no + *--rsp = 0; // err code + + for (UInt8 i = 0; i < 15; i++) *--rsp = 0; // R15 .. RAX + + task->stackPointer = (UInt64)rsp; + task->process = owner; + task->id = owner->processId; + task->sleepTicks = 0; + task->next = gOSSchedulerCurrentTask->next; + task->kernelStackTop = (UInt64)stackBaseAddress + stackSize; + task->taskState = kOSProcessStateRunning; + task->waitingForProcess = -1; + gOSSchedulerCurrentTask->next = task; + return task; +} + +UInt64 OSSchedulerNext(UInt64 currentStackPointer) { + if (!gOSSchedulerCurrentTask) return currentStackPointer; + + gOSSchedulerCurrentTask->stackPointer = currentStackPointer; + OSTask* taskIterator = gOSSchedulerCurrentTask->next; + + do { + if (taskIterator->sleepTicks > 0) taskIterator->sleepTicks--; + taskIterator = taskIterator->next; + } while (taskIterator != gOSSchedulerCurrentTask->next); + + if (gOSSchedulerCurrentTask->sleepTicks > 0) gOSSchedulerCurrentTask->sleepTicks--; + + OSTask* nextTask = gOSSchedulerCurrentTask; + while (1) { + // TODO: add gc here; + nextTask = nextTask->next; + if (nextTask->taskState == kOSProcessStateSleeping && nextTask->sleepTicks == 0) nextTask->taskState = kOSProcessStateRunning; + if (nextTask->taskState == kOSProcessStateRunning) break; + if (nextTask == gOSSchedulerCurrentTask) { + if (gOSSchedulerCurrentTask->taskState == kOSProcessStateRunning) break; + OSPanic("no running tasks"); + } + } + + if (nextTask->process->physicalPML4 != gOSSchedulerCurrentTask->process->physicalPML4) VMLoadCR3(nextTask->process->physicalPML4); + gOSSchedulerCurrentTask = nextTask; + gHALTaskStateSegment.rsp0 = gOSSchedulerCurrentTask->kernelStackTop; + gOSBootCPU.kernelStackPointer = gOSSchedulerCurrentTask->kernelStackTop; + return gOSSchedulerCurrentTask->stackPointer; +} + +void OSSchedulerBlock(UInt32 processID) { + gOSSchedulerCurrentTask->taskState = kOSProcessStateBlocked; + gOSSchedulerCurrentTask->waitingForProcess = processID; + __asm__ volatile("int $32"); +} + +void OSSchedulerWakeup(UInt32 processID) { + OSTask* iteratorTask = gOSSchedulerCurrentTask; + do { + if (iteratorTask->taskState == kOSProcessStateBlocked && iteratorTask->waitingForProcess == (Int32)processID) { + iteratorTask->taskState = kOSProcessStateRunning; + iteratorTask->waitingForProcess = -1; + } + iteratorTask = iteratorTask->next; + } while (iteratorTask != gOSSchedulerCurrentTask); +} + +void OSSchedulerTerminate() { + UInt32 processID = gOSSchedulerCurrentTask->id; + gOSSchedulerCurrentTask->taskState = kOSProcessStateDead; + + OSSchedulerWakeup(processID); + __asm__ volatile("int $32"); +} + +void OSSchedulerYield(UInt64 ticks) { + gOSSchedulerCurrentTask->sleepTicks = ticks; + gOSSchedulerCurrentTask->taskState = kOSProcessStateSleeping; + __asm__ volatile("hlt"); +} \ No newline at end of file diff --git a/kernel/src/OS/Services/OSServiceIO.c b/kernel/src/OS/Services/OSServiceIO.c new file mode 100644 index 0000000..18411d5 --- /dev/null +++ b/kernel/src/OS/Services/OSServiceIO.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include +#include + +UInt64 OSServiceWrite(UInt64 fileDescriptor, UInt64 buffer, UInt64 length) { + if (fileDescriptor == 1 || fileDescriptor == 2) { + char* string = (char*)buffer; + for (UInt64 i = 0; i < length; i++) { + IOConsolePutcharacter(string[i]); + } + return length; + } + return 0; +} + +UInt64 OSServiceRead(UInt64 fileDescriptor, UInt64 buffer, UInt64 count) { + char* readBuffer = (char*)buffer; + if (fileDescriptor == 0) { + for (UInt64 i = 0; i < count; i++) { + readBuffer[i] = IOConsoleGetCharacter(); + } + return count; + } + return 0; +} \ No newline at end of file diff --git a/kernel/src/OS/Services/OSServiceMemory.c b/kernel/src/OS/Services/OSServiceMemory.c new file mode 100644 index 0000000..5fae4ca --- /dev/null +++ b/kernel/src/OS/Services/OSServiceMemory.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include + +#include + +#include +#include +#include + +UInt64 OSServiceMemoryGet(UInt64 size) { + if (size == 0) return 0; + OSProcess* currentProcess = gOSSchedulerCurrentTask->process; + UInt64 addressToReturn = currentProcess->heapCurrentPointer; + + UInt64 pages_needed = (size + (kVMPageSize-1)) / kVMPageSize; + + for (UInt64 i = 0; i < pages_needed; i++) { + void* phycialAddress = VMPhysicalMemoryAllocatePage(); + if (!phycialAddress) return 0; + + VMVirtualMemoryMapPage((UInt64*)currentProcess->physicalPML4, (UInt64)phycialAddress, currentProcess->heapCurrentPointer, PTE_PRESENT | PTE_RW | PTE_USER); + memset((void*)PHYS_TO_HHDM((UInt64)phycialAddress), 0, kVMPageSize); + + currentProcess->heapCurrentPointer += kVMPageSize; + } + + return addressToReturn; +} diff --git a/kernel/src/OS/Services/OSServiceProcess.c b/kernel/src/OS/Services/OSServiceProcess.c new file mode 100644 index 0000000..f6afd7b --- /dev/null +++ b/kernel/src/OS/Services/OSServiceProcess.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include +#include +#include +#include +#include + +Int32 OSServiceProcessExit(Int32 code) { + IOConsoleLog("\n[Dewar] process \"%s\" exited with code %d\n", gOSSchedulerCurrentTask->process->name, code); + OSSchedulerTerminate(); + return code; +} + + +Int32 OSServiceProcessSpawn(const char* path) { + return OSLoaderProcessSpawn(path, path); +} + +Int32 OSServiceProcessWait(UInt64 processID) { + OSSchedulerBlock(processID); + return processID; +} diff --git a/kernel/src/VM/Heap.c b/kernel/src/VM/Heap.c new file mode 100644 index 0000000..e7612b7 --- /dev/null +++ b/kernel/src/VM/Heap.c @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#include +#include +#include +#include +#include +#include + +extern UInt64* gVMKernelPML4; +static VMHeapBlockHeader* sVMHeapListHead = nullptr; + +void combine_forward(VMHeapBlockHeader* current) { + if (!current->next || !current->next->isFree) return; + current->size += sizeof(VMHeapBlockHeader) + current->next->size; + current->next = current->next->next; + if (current->next) current->next->previous = current; // what the fuck +} + +void VMHeapInitialize() { + UInt64 heapStart = kVMKernelHeapStart; + + for (UInt64 i = 0; i < kVMHeapSizePages; i++) { + UInt64 physical = (UInt64)VMPhysicalMemoryAllocatePage(); + if (!physical) OSPanic("OOM during heap init"); + + UInt64 virtual = heapStart + (i * kVMPageSize); + VMVirtualMemoryMapPage(gVMKernelPML4, physical, virtual, PTE_PRESENT | PTE_RW); + } + + sVMHeapListHead = (VMHeapBlockHeader*)heapStart; + sVMHeapListHead->magic = HEADER_MAGIC; + sVMHeapListHead->size = (kVMHeapSizePages * kVMPageSize) - sizeof(VMHeapBlockHeader); + sVMHeapListHead->isFree = true; + sVMHeapListHead->next = nullptr; + sVMHeapListHead->previous = nullptr; +} + +void* malloc(UInt64 size) { + if (size == 0) return nullptr; + UInt64 alignedSize = (size + 15) & ~15; + + VMHeapBlockHeader* current = sVMHeapListHead; + while (current) { + if (current->isFree && current->size >= alignedSize) { + if (current->size > alignedSize + sizeof(VMHeapBlockHeader) + 16) { + VMHeapBlockHeader* new_block = (VMHeapBlockHeader*)((UInt64)current + sizeof(VMHeapBlockHeader) + alignedSize); + new_block->size = current->size - alignedSize - sizeof(VMHeapBlockHeader); + new_block->isFree = true; + new_block->next = current->next; + new_block->previous = current; + new_block->magic = HEADER_MAGIC; + + if (current->next) current->next->previous = new_block; + current->next = new_block; + current->size = alignedSize; + } + current->isFree = false; + return (void*)((UInt64)current + sizeof(VMHeapBlockHeader)); + } + current = current->next; + } + + return nullptr; +} + +void free(void* pointer) { + if (!pointer) return; + + VMHeapBlockHeader* current = (VMHeapBlockHeader*)((UInt64)pointer - sizeof(VMHeapBlockHeader)); + if (current->magic != HEADER_MAGIC) return; + + current->isFree = true; + if (current->next && current->next->isFree) combine_forward(current); + if (current->previous && current->previous->isFree) combine_forward(current->previous); +} + +void* realloc(void* pointer, UInt64 newSize) { + if (!pointer) return malloc(newSize); + if (newSize == 0) { + free(pointer); + return nullptr; + } + + VMHeapBlockHeader* current = (VMHeapBlockHeader*)((UInt64)pointer - sizeof(VMHeapBlockHeader)); + if (current->size >= newSize) return pointer; + + if (current->next && + current->next->isFree && + (current->size + sizeof(VMHeapBlockHeader) + current->next->size) >= newSize) { // why ts so fucking unreadable + combine_forward(current); + return pointer; + } + + void* newPointer = malloc(newSize); + if (!newPointer) return nullptr; + + memcpy(newPointer, pointer, current->size); + free(pointer); + + return newPointer; +} \ No newline at end of file diff --git a/kernel/src/VM/PMM.c b/kernel/src/VM/PMM.c new file mode 100644 index 0000000..179f691 --- /dev/null +++ b/kernel/src/VM/PMM.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include +#include +#include +#include + +#include +#include + +#include "bootinfo.h" + + +UInt8* gVMPhycalMemoryBitmap = nullptr; +UInt64 gVMPhycalMemoryBitmapSize = 0; +UInt64 gVMPhycalMemoryTotalMemorySize = 0; + +extern UInt64 _kernel_start; +extern UInt64 _kernel_end; + +UInt64 VMPhysicalMemoryGetTotalMemorySize() { + return gVMPhycalMemoryTotalMemorySize; +} + +void VMPhysicalMemoryInitialize(BIMemoryMap *memoryMap) { + UInt64 descriptorCount = memoryMap->mapSize / memoryMap->descriptorSize; + UInt64 maxPhysicalAddress = 0; + + for (UInt64 i = 0; i < descriptorCount; i++) { + OSMemoryDescriptor* descriptor = (OSMemoryDescriptor*)((UInt8*)memoryMap->map + (i * memoryMap->descriptorSize)); + + if (descriptor->type == kOSMemoryTypeMappedIO || + descriptor->type == kOSMemoryTypeMappedIOPortSpace || + descriptor->type == kOSMemoryTypeUnusable || + descriptor->type == kOSMemoryTypeReserved || + descriptor->type == kOSMemoryTypePalCode) { + continue; + } + + UInt64 nominee = descriptor->physicalStart + (descriptor->pageCount * kVMPageSize); + if (nominee > maxPhysicalAddress) { + maxPhysicalAddress = nominee; + } + } + gVMPhycalMemoryTotalMemorySize = maxPhysicalAddress; + + UInt64 totalPageCount = maxPhysicalAddress / kVMPageSize; + UInt64 bitmapSize = (totalPageCount + 7) / 8; + OSMemoryDescriptor *bitmapHostDescriptor = nullptr; + + for (UInt64 i = 0; i < descriptorCount; i++) { + OSMemoryDescriptor *descriptor = (OSMemoryDescriptor*)((UInt8*)memoryMap->map + (i * memoryMap->descriptorSize)); + + if ((descriptor->type == kOSMemoryTypeConventional) && + ((descriptor->pageCount * kVMPageSize) >= bitmapSize) && + (descriptor->physicalStart >= kVMSafeSpaceStartAddress)) { + bitmapHostDescriptor = descriptor; + break; + } + } + + if (bitmapHostDescriptor == nullptr) { + OSPanic("PMM: Not enough RAM for memory bitmap!"); + } + + gVMPhycalMemoryBitmap = (UInt8*)bitmapHostDescriptor->physicalStart; + gVMPhycalMemoryBitmapSize = bitmapSize; + + memset(gVMPhycalMemoryBitmap, 0xFF, bitmapSize); + + for (UInt64 i = 0; i < descriptorCount; i++) { + OSMemoryDescriptor *descriptor = (OSMemoryDescriptor*)((UInt8*)memoryMap->map + (i * memoryMap->descriptorSize)); + + if (descriptor->type != kOSMemoryTypeConventional) { + continue; + } + + UInt64 startAddress = descriptor->physicalStart; + UInt64 endAddress = startAddress + (descriptor->pageCount * kVMPageSize); + + for (UInt64 addr = startAddress; addr < endAddress; addr += kVMPageSize) { + BITMAP_UNSET(gVMPhycalMemoryBitmap, addr); + } + } + + UInt64 kernelStart = KERNEL_VIRT_TO_PHYS((UInt64)&_kernel_start); + UInt64 kernelEnd = KERNEL_VIRT_TO_PHYS((UInt64)&_kernel_end); + + UInt64 bitmapStart = (UInt64)gVMPhycalMemoryBitmap; + UInt64 bitmapEnd = bitmapStart + gVMPhycalMemoryBitmapSize; + + for (UInt64 addr = 0; addr < kVMSafeSpaceStartAddress; addr += kVMPageSize) BITMAP_SET(gVMPhycalMemoryBitmap, addr); + for (UInt64 addr = kernelStart; addr < kernelEnd; addr += kVMPageSize) BITMAP_SET(gVMPhycalMemoryBitmap, addr); + for (UInt64 addr = bitmapStart; addr < bitmapEnd; addr += kVMPageSize) BITMAP_SET(gVMPhycalMemoryBitmap, addr); +} + +void* VMPhysicalMemoryAllocatePage() { + for (UInt64 i = 0; i < gVMPhycalMemoryBitmapSize; i++) { + if (gVMPhycalMemoryBitmap[i] == 0xFF) continue; + + for (UInt64 bit = 0; bit < 8; bit++) { + if ((gVMPhycalMemoryBitmap[i] & (1 << bit)) == 0) { + UInt64 address = (i * 8 + bit) * kVMPageSize; + BITMAP_SET(gVMPhycalMemoryBitmap, address); + return (void*)address; + } + } + } + return nullptr; // Out of memory +} + +void VMPhysicalMemoryFreePage(void* address) { + BITMAP_UNSET(gVMPhycalMemoryBitmap, (UInt64)address); +} \ No newline at end of file diff --git a/kernel/src/VM/VMM.c b/kernel/src/VM/VMM.c new file mode 100644 index 0000000..f759690 --- /dev/null +++ b/kernel/src/VM/VMM.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash +#include +#include + +#include + +#include +#include + +#include + +#include +#include "bootinfo.h" + +enum { + kVMUserStackTop = 0x70000000, + kVMUserStackSize = 0x4000 +}; + +UInt64* gVMKernelPML4 = nullptr; +UInt64 gVMKernelPML4Physical = 0; +static bool isInitialized = false; + +extern UInt64 _kernel_start; +extern UInt64 _kernel_end; +extern UInt8* gVMPhycalMemoryBitmap; +extern UInt64 gVMPhycalMemoryBitmapSize; +extern HALGlobalDescriptorTable gHALGlobalDescriptorTable[]; +extern HALInterruptsDescriptorTableEntry gHALInterruptsDescriptorTable[]; +extern UInt8 gHALDoubleFaultStack[]; +extern UInt8 stack_guard; + +static UInt64* sVMGetVirtualTable(UInt64 phys) { + if (isInitialized) return (UInt64*)PHYS_TO_HHDM(phys); + return (UInt64*)phys; +} + +UInt64* VMVirtualMemoryMapPage(UInt64* pml4, UInt64 phys, UInt64 virt, UInt64 flags) { + UInt64 pt_idx = VMM_PT_INDEX(virt); + UInt64 pd_idx = VMM_PD_INDEX(virt); + UInt64 pdpt_idx = VMM_PDPT_INDEX(virt); + UInt64 pml4_idx = VMM_PML4_INDEX(virt); + + UInt64* pml4_virt = pml4; + if (isInitialized) pml4_virt = (UInt64*)PHYS_TO_HHDM((UInt64)pml4); + + UInt64 table_flags = PTE_PRESENT | PTE_RW | (flags & PTE_USER); + + if (!(pml4_virt[pml4_idx] & PTE_PRESENT)) { + UInt64* addr = VMPhysicalMemoryAllocatePage(); + if (!addr) return nullptr; + UInt64* addr_virt = sVMGetVirtualTable((UInt64)addr); + memset(addr_virt, 0, kVMPageSize); + pml4_virt[pml4_idx] = (UInt64)addr | table_flags; + } else { + pml4_virt[pml4_idx] |= (flags & PTE_USER); + } + + UInt64* pdpt = (UInt64*)PTE_GET_ADDR(pml4_virt[pml4_idx]); + UInt64* pdpt_virt = sVMGetVirtualTable((UInt64)pdpt); + + if (!(pdpt_virt[pdpt_idx] & PTE_PRESENT)) { + UInt64* addr = VMPhysicalMemoryAllocatePage(); + if (!addr) return nullptr; + UInt64* addr_virt = sVMGetVirtualTable((UInt64)addr); + memset(addr_virt, 0, kVMPageSize); + pdpt_virt[pdpt_idx] = (UInt64)addr | table_flags; + } else { + pdpt_virt[pdpt_idx] |= (flags & PTE_USER); + } + + UInt64* pd = (UInt64*)PTE_GET_ADDR(pdpt_virt[pdpt_idx]); + UInt64* pd_virt = sVMGetVirtualTable((UInt64)pd); + + if (!(pd_virt[pd_idx] & PTE_PRESENT)) { + UInt64* addr = VMPhysicalMemoryAllocatePage(); + if (!addr) return nullptr; + UInt64* addr_virt = sVMGetVirtualTable((UInt64)addr); + memset(addr_virt, 0, kVMPageSize); + pd_virt[pd_idx] = (UInt64)addr | table_flags; + } else { + pd_virt[pd_idx] |= (flags & PTE_USER); + } + + UInt64* pt = (UInt64*)PTE_GET_ADDR(pd_virt[pd_idx]); + UInt64* pt_virt = sVMGetVirtualTable((UInt64)pt); + pt_virt[pt_idx] = phys | flags; + + __asm__ volatile("invlpg (%0)" :: "r" (virt) : "memory"); + + return (UInt64*)virt; +} + +void VMVirtualMemoryUnmapPage(UInt64* pml4, UInt64 virt) { + UInt64 pt_idx = VMM_PT_INDEX(virt); + UInt64 pd_idx = VMM_PD_INDEX(virt); + UInt64 pdpt_idx = VMM_PDPT_INDEX(virt); + UInt64 pml4_idx = VMM_PML4_INDEX(virt); + + UInt64* pml4_virt = pml4; + if (isInitialized) pml4_virt = (UInt64*)PHYS_TO_HHDM((UInt64)pml4); + + if (!(pml4_virt[pml4_idx] & PTE_PRESENT)) return; + UInt64* pdpt_virt = sVMGetVirtualTable(PTE_GET_ADDR(pml4_virt[pml4_idx])); + + if (!(pdpt_virt[pdpt_idx] & PTE_PRESENT)) return; + UInt64* pd_virt = sVMGetVirtualTable(PTE_GET_ADDR(pdpt_virt[pdpt_idx])); + + if (!(pd_virt[pd_idx] & PTE_PRESENT)) return; + UInt64* pt_virt = sVMGetVirtualTable(PTE_GET_ADDR(pd_virt[pd_idx])); + + pt_virt[pt_idx] = 0; + + __asm__ volatile("invlpg (%0)" :: "r" (virt) : "memory"); +} + +void VMLoadCR3(UInt64 pml4_addr) { + __asm__ volatile ("mov %0, %%cr3" :: "r"(pml4_addr) : "memory"); +} + +void VMVirtualMemoryInitialize(Bootinfo* info) { + gVMKernelPML4Physical = (UInt64)VMPhysicalMemoryAllocatePage(); + gVMKernelPML4 = (UInt64*)gVMKernelPML4Physical; + memset(gVMKernelPML4, 0, kVMPageSize); + + UInt64 k_virt_start = (UInt64)&_kernel_start; + UInt64 k_virt_end = (UInt64)&_kernel_end; + + UInt64 fb_start = (UInt64)info->framebuffer.base; + UInt64 fb_end = fb_start + info->framebuffer.baseSize; + UInt64 fb_size = fb_end - fb_start; + + UInt64 max_mem = VMPhysicalMemoryGetTotalMemorySize(); + for (UInt64 i = 0; i < max_mem; i += kVMPageSize) VMVirtualMemoryMapPage(gVMKernelPML4, i, PHYS_TO_HHDM(i), PTE_PRESENT | PTE_RW); + for (UInt64 i = k_virt_start; i < k_virt_end; i += kVMPageSize) VMVirtualMemoryMapPage(gVMKernelPML4, KERNEL_VIRT_TO_PHYS(i), i, PTE_PRESENT | PTE_RW); + for (UInt64 i = 0; i < fb_size; i += kVMPageSize) VMVirtualMemoryMapPage(gVMKernelPML4, fb_start + i, FB_VIRT_BASE + i, PTE_PRESENT | PTE_RW); + VMVirtualMemoryUnmapPage(gVMKernelPML4, (UInt64)&stack_guard); + + gVMPhycalMemoryBitmap = (UInt8*)PHYS_TO_HHDM((UInt64)gVMPhycalMemoryBitmap); + info->framebuffer.base = (UInt32*)FB_VIRT_BASE; + VMLoadCR3(gVMKernelPML4Physical); + isInitialized = true; +} + +UInt64 VMVirtualMemoryCreateAddressSpace() { + UInt64 phys = (UInt64)VMPhysicalMemoryAllocatePage(); + if (!phys) return 0; + + UInt64* virt = (UInt64*)PHYS_TO_HHDM(phys); + memset(virt, 0, kVMPageSize); + + UInt64* kernel_pml4_virt = sVMGetVirtualTable((UInt64)gVMKernelPML4); + + for (UInt32 i = 256; i < 512; i++) { + virt[i] = kernel_pml4_virt[i]; + } + + return phys; +} + +UInt64 VMGetCurrentCR3() { + UInt64 cr3; + __asm__ volatile("mov %%cr3, %0" : "=r"(cr3)); + return cr3; +} + + +void VMVirtualMemorySetupUserStack(UInt64* pml4_phys) { + UInt64 stack_bottom = kVMUserStackTop - kVMUserStackSize; + for (UInt64 addr = stack_bottom; addr < kVMUserStackTop; addr += 4096) { + void* phys = VMPhysicalMemoryAllocatePage(); + if (!phys) OSPanic("OOM in user stack setup"); + memset((void*)PHYS_TO_HHDM((UInt64)phys), 0, 4096); + VMVirtualMemoryMapPage((UInt64*)pml4_phys, (UInt64)phys, addr, PTE_PRESENT | PTE_RW | PTE_USER); + } +} diff --git a/kernel/src/arch/x86_64/GDT.c b/kernel/src/arch/x86_64/GDT.c new file mode 100644 index 0000000..0972860 --- /dev/null +++ b/kernel/src/arch/x86_64/GDT.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +// just fucking kill me already + +#include + +HALGlobalDescriptorTable gHALGlobalDescriptorTable[kHALGDTEntries]; +HALGlobalDescriptorTablePointer gHALGlobalDescriptorTablePointer; +HALTaskStateSegment gHALTaskStateSegment; +UInt8 gHALDoubleFaultStack[4096] = {0}; + +static void sHALGlobalDescriptorTableSetGate(int number, UInt64 base, UInt64 limit, UInt8 access, UInt8 granularity) { + gHALGlobalDescriptorTable[number].baseLow = (base & 0xFFFF); // left only low 16bit + gHALGlobalDescriptorTable[number].baseMiddle = (base >> 16) & 0xFF; // 3rd address byte + gHALGlobalDescriptorTable[number].baseHigh = (base >> 24) & 0xFF; // 4th address byte + + gHALGlobalDescriptorTable[number].limitLow = (limit & 0xFFFF); + gHALGlobalDescriptorTable[number].granularity = (limit >> 16) & 0x0F; // leave only first 4 bits (limit's left 16-19) + gHALGlobalDescriptorTable[number].granularity |= granularity & 0xF0; // get flags and concate two pieces so FFFFLLLL (L -- Limit; F -- flags) + gHALGlobalDescriptorTable[number].access = access; + + // fuck intel +} + + +static void sHALTaskStateSegmentWrite(int number) { + UInt64 base = (UInt64)&gHALTaskStateSegment; + UInt64 limit = sizeof(gHALTaskStateSegment); + UInt64 access = 0x89; // TSS_PRESENT | TSS_EXECUTABLE | TSS_ACCESSED; + UInt64 granularity = 0; + + sHALGlobalDescriptorTableSetGate(number, base, limit, access, granularity); + *((UInt64*)&gHALGlobalDescriptorTable[number+1]) = (base >> 32); // really scary but not really hard + // just direct write 8bytes to num+1 + // basically a hack but at this point i dont care +} + + +extern void gdt_flush(UInt64 gdt_ptr_addr); // entry.asm + +void HALGlobalDescriptorTableInitialize() { + gHALGlobalDescriptorTablePointer.limit = (sizeof(HALGlobalDescriptorTable) * kHALGDTEntries) - 1; + gHALGlobalDescriptorTablePointer.base = (UInt64)&gHALGlobalDescriptorTable; + + // 0: Null + sHALGlobalDescriptorTableSetGate(0, 0, 0, 0, 0); + + // 1: Kernel Code (Ring 0) + // Access: 0x9A (Present, Ring0, Exec/Read) + // Granularity: 0x20 (Long Mode bit) access ring 0 code exec code readable + sHALGlobalDescriptorTableSetGate(1, 0, 0, 0x9A, 0x20); // 0x9A = 1 00 1 1 0 1 + // 0x20 = 0010 0000 bit 5 is "Long mode" + // 2: Kernel Data (Ring 0) + // Access: 0x92 (Present, Ring0, Read/Write) + sHALGlobalDescriptorTableSetGate(2, 0, 0, 0x92, 0); // 0x92 = 1 00 1 0 0 1 + + // 3: User Data (Ring 3) + // Access: 0xF2 (Present, Ring3, Read/Write) + sHALGlobalDescriptorTableSetGate(3, 0, 0, 0xF2, 0); // 0xF2 = 1 11 1 0 0 1 + + // 4: User Code (Ring 3) + // Access: 0xFA (Present, Ring3, RWX) + sHALGlobalDescriptorTableSetGate(4, 0, 0, 0xFA, 0x20); // 0xFA = 1 11 1 1 0 1 + + for (UInt64 i = 0; i < sizeof(HALTaskStateSegment); i++) ((UInt8*)&gHALTaskStateSegment)[i] = 0; // zeroifying tss struct + + gHALTaskStateSegment.iomapBase = sizeof(HALTaskStateSegment); + gHALTaskStateSegment.ist1 = (UInt64)gHALDoubleFaultStack + sizeof(gHALDoubleFaultStack); + sHALTaskStateSegmentWrite(5); + + gdt_flush((UInt64)&gHALGlobalDescriptorTablePointer); + + // telling cpu that TSS info located at gdt[5]; offset = 5 * 8 = 40 = 0x28 + __asm__ volatile ("ltr %%ax" :: "a" (0x28)); +} + diff --git a/kernel/src/arch/x86_64/IDT.c b/kernel/src/arch/x86_64/IDT.c new file mode 100644 index 0000000..35dfde6 --- /dev/null +++ b/kernel/src/arch/x86_64/IDT.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#include +#include + +HALInterruptsDescriptorTableEntry gHALInterruptsDescriptorTable[256]; +HALInterruptsDescriptorTablePointer gHALInterruptsDescriptorTablePointer; + +extern void isr0(); extern void isr1(); extern void isr2(); extern void isr3(); +extern void isr4(); extern void isr5(); extern void isr6(); extern void isr7(); +extern void isr8(); extern void isr9(); extern void isr10(); extern void isr11(); +extern void isr12(); extern void isr13(); extern void isr14(); extern void isr15(); +extern void isr16(); extern void isr17(); extern void isr18(); extern void isr19(); +extern void isr20(); extern void isr21(); extern void isr22(); extern void isr23(); +extern void isr24(); extern void isr25(); extern void isr26(); extern void isr27(); +extern void isr28(); extern void isr29(); extern void isr30(); extern void isr31(); +extern void irq0(void); extern void irq1(void); + +extern void idt_load(UInt64); // asm: lidt [rdi] / ret + +static void sHALInterruptsDescriptorTableSetGate(int number, UInt64 handler, UInt16 selector, UInt8 flags) { + gHALInterruptsDescriptorTable[number].offsetLow = handler & 0xFFFF; + gHALInterruptsDescriptorTable[number].offsetMid = (handler >> 16) & 0xFFFF; + gHALInterruptsDescriptorTable[number].offsetHigh = (handler >> 32) & 0xFFFFFFFF; + + gHALInterruptsDescriptorTable[number].selector = selector; // 0x08 (Kernel Code) + gHALInterruptsDescriptorTable[number].ist = 0; + gHALInterruptsDescriptorTable[number].attributes = flags; + gHALInterruptsDescriptorTable[number].reserved = 0; +} + +void HALInterruptsDescriptorTableInitialize() { + gHALInterruptsDescriptorTablePointer.limit = (sizeof(HALInterruptsDescriptorTableEntry) * 256) - 1; + gHALInterruptsDescriptorTablePointer.base = (UInt64)&gHALInterruptsDescriptorTable; + + const UInt8 flags = 0x8E; + const UInt8 selector = 0x08; + + + sHALInterruptsDescriptorTableSetGate(0, (UInt64)isr0, selector, flags); + sHALInterruptsDescriptorTableSetGate(1, (UInt64)isr1, selector, flags); + sHALInterruptsDescriptorTableSetGate(2, (UInt64)isr2, selector, flags); + sHALInterruptsDescriptorTableSetGate(3, (UInt64)isr3, selector, flags); + sHALInterruptsDescriptorTableSetGate(4, (UInt64)isr4, selector, flags); + sHALInterruptsDescriptorTableSetGate(5, (UInt64)isr5, selector, flags); + sHALInterruptsDescriptorTableSetGate(6, (UInt64)isr6, selector, flags); + sHALInterruptsDescriptorTableSetGate(7, (UInt64)isr7, selector, flags); + sHALInterruptsDescriptorTableSetGate(8, (UInt64)isr8, selector, flags); + sHALInterruptsDescriptorTableSetGate(9, (UInt64)isr9, selector, flags); + sHALInterruptsDescriptorTableSetGate(10, (UInt64)isr10, selector, flags); + sHALInterruptsDescriptorTableSetGate(11, (UInt64)isr11, selector, flags); + sHALInterruptsDescriptorTableSetGate(12, (UInt64)isr12, selector, flags); + sHALInterruptsDescriptorTableSetGate(13, (UInt64)isr13, selector, flags); + sHALInterruptsDescriptorTableSetGate(14, (UInt64)isr14, selector, flags); + sHALInterruptsDescriptorTableSetGate(15, (UInt64)isr15, selector, flags); + sHALInterruptsDescriptorTableSetGate(16, (UInt64)isr16, selector, flags); + sHALInterruptsDescriptorTableSetGate(17, (UInt64)isr17, selector, flags); + sHALInterruptsDescriptorTableSetGate(18, (UInt64)isr18, selector, flags); + sHALInterruptsDescriptorTableSetGate(19, (UInt64)isr19, selector, flags); + sHALInterruptsDescriptorTableSetGate(20, (UInt64)isr20, selector, flags); + sHALInterruptsDescriptorTableSetGate(21, (UInt64)isr21, selector, flags); + sHALInterruptsDescriptorTableSetGate(22, (UInt64)isr22, selector, flags); + sHALInterruptsDescriptorTableSetGate(23, (UInt64)isr23, selector, flags); + sHALInterruptsDescriptorTableSetGate(24, (UInt64)isr24, selector, flags); + sHALInterruptsDescriptorTableSetGate(25, (UInt64)isr25, selector, flags); + sHALInterruptsDescriptorTableSetGate(26, (UInt64)isr26, selector, flags); + sHALInterruptsDescriptorTableSetGate(27, (UInt64)isr27, selector, flags); + sHALInterruptsDescriptorTableSetGate(28, (UInt64)isr28, selector, flags); + sHALInterruptsDescriptorTableSetGate(29, (UInt64)isr29, selector, flags); + sHALInterruptsDescriptorTableSetGate(30, (UInt64)isr30, selector, flags); + sHALInterruptsDescriptorTableSetGate(31, (UInt64)isr31, selector, flags); + + gHALInterruptsDescriptorTable[8].ist = 1; // TSS + gHALInterruptsDescriptorTable[13].ist = 1; + gHALInterruptsDescriptorTable[14].ist = 1; + + sHALInterruptsDescriptorTableSetGate(32, (UInt64)irq0, selector, flags); + sHALInterruptsDescriptorTableSetGate(33, (UInt64)irq1, selector, flags); + + __asm__ volatile ("lidt %0" : : "m"(gHALInterruptsDescriptorTablePointer)); +} diff --git a/kernel/src/arch/x86_64/OSCPU.c b/kernel/src/arch/x86_64/OSCPU.c new file mode 100644 index 0000000..db9c9cd --- /dev/null +++ b/kernel/src/arch/x86_64/OSCPU.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include +#include + +#define MSR_GS_BASE 0xC0000101 +#define MSR_KERNEL_GS_BASE 0xC0000102 + +OSCPUData gOSBootCPU = {0}; + +static inline void CPUID(UInt32 leaf, UInt32 subleaf, UInt32 *eax, UInt32 *ebx, UInt32 *ecx, UInt32 *edx) { + __asm__ volatile("cpuid" + : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) + : "a"(leaf), "c"(subleaf) + ); +} + +static inline void WRMSR(UInt32 msr, UInt64 val) { + UInt32 low = (UInt32)val; + UInt32 high = (UInt32)(val >> 32); + __asm__ volatile("wrmsr" :: "a"(low), "d"(high), "c"(msr)); +} + +void OSCPUInitialize(UInt64 kernelStackTop) { + gOSBootCPU.kernelStackPointer = kernelStackTop; + gOSBootCPU.selfAddress = (UInt64)&gOSBootCPU; + WRMSR(MSR_KERNEL_GS_BASE, (UInt64)&gOSBootCPU); + + + UInt32 eax, ebx, ecx, edx; + + CPUID(0, 0, &eax, &ebx, &ecx, &edx); + + UInt32* vendorPointer = (UInt32*)gOSBootCPU.vendorID; + vendorPointer[0] = ebx; + vendorPointer[1] = edx; + vendorPointer[2] = ecx; + gOSBootCPU.vendorID[12] = '\0'; + + CPUID(1, 0, &eax, &ebx, &ecx, &edx); + + gOSBootCPU.family = (eax >> 8) & 0xF; + gOSBootCPU.model = (eax >> 4) & 0xF; + if (gOSBootCPU.family == 6 || gOSBootCPU.family == 15) { + gOSBootCPU.model += ((eax >> 16) & 0xF) << 4; + } + + if (edx & (1 << 0)) gOSBootCPU.features |= kCPUFeatureFPU; + if (edx & (1 << 4)) gOSBootCPU.features |= kCPUFeatureTSC; + if (edx & (1 << 5)) gOSBootCPU.features |= kCPUFeatureMSR; + if (edx & (1 << 6)) gOSBootCPU.features |= kCPUFeaturePAE; + if (edx & (1 << 9)) gOSBootCPU.features |= kCPUFeatureAPIC; + if (edx & (1 << 12)) gOSBootCPU.features |= kCPUFeatureMTRR; + + if (edx & (1 << 25)) gOSBootCPU.features |= kCPUFeatureSSE; + if (edx & (1 << 26)) gOSBootCPU.features |= kCPUFeatureSSE2; + if (ecx & (1 << 0)) gOSBootCPU.features |= kCPUFeatureSSE3; + if (ecx & (1 << 9)) gOSBootCPU.features |= kCPUFeatureSSSE3; + if (ecx & (1 << 19)) gOSBootCPU.features |= kCPUFeatureSSE4_1; + if (ecx & (1 << 20)) gOSBootCPU.features |= kCPUFeatureSSE4_2; + + if (ecx & (1 << 28)) gOSBootCPU.features |= kCPUFeatureAVX; + if (ecx & (1 << 29)) gOSBootCPU.features |= kCPUFeatureF16C; + if (ecx & (1 << 30)) gOSBootCPU.features |= kCPUFeatureRDRAND; + + if (ecx & (1 << 31)) gOSBootCPU.features |= kCPUFeatureHypervisor; +} + +Boolean OSCPUHasFeature(OSCPUFeature feature) { + return (gOSBootCPU.features & feature) != 0; +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/PIC.c b/kernel/src/arch/x86_64/PIC.c new file mode 100644 index 0000000..fb82b1f --- /dev/null +++ b/kernel/src/arch/x86_64/PIC.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#include +#include +#include + + +UInt16 HALLegacyInterruptControllerRemap() { + UInt8 currentMaster = IOPortRead8(kIOMasterData); + UInt8 currentSlave = IOPortRead8(kIOSlaveData); + + // initialization; icw1 + IOPortWrite8WithWait(kIOMasterCommand, 0x11); + IOPortWrite8WithWait(kIOSlaveCommand, 0x11); + + // icw2 + IOPortWrite8WithWait(kIOMasterData, 0x20); // master now controlling idt[32..39] + IOPortWrite8WithWait(kIOSlaveData, 0x28); // idt[40..47] + + // icw3 + IOPortWrite8WithWait(kIOMasterData, 0x04); // slave on irq2 + IOPortWrite8WithWait(kIOSlaveData, 0x02); // assign id = 2 to slave + + // icw4; 0x01 -- 8086 mode + IOPortWrite8WithWait(kIOMasterData, 0x01); + IOPortWrite8WithWait(kIOSlaveData, 0x01); + + IOPortWrite8WithWait(kIOMasterData, 0xFD); // 1111 1101 + // 0 -- means 'on' + IOPortWrite8WithWait(kIOSlaveData, 0xFF); // Everything ON + + return ((UInt16) currentMaster << 8) | currentSlave; +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/cpuinfo.c b/kernel/src/arch/x86_64/cpuinfo.c deleted file mode 100644 index 5924123..0000000 --- a/kernel/src/arch/x86_64/cpuinfo.c +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#include -#include - -#define MSR_GS_BASE 0xC0000101 -#define MSR_KERNEL_GS_BASE 0xC0000102 - -cpu_info g_cpu = {0}; - -static inline void cpuid(u32 leaf, u32 subleaf, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) { - __asm__ volatile("cpuid" - : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) - : "a"(leaf), "c"(subleaf) - ); -} - -static inline void wrmsr(u32 msr, u64 val) { - u32 low = (u32)val; - u32 high = (u32)(val >> 32); - __asm__ volatile("wrmsr" :: "a"(low), "d"(high), "c"(msr)); -} - -void cpuinfo_init(u64 kernel_stack_top) { - g_cpu.kernel_rsp = kernel_stack_top; - g_cpu.self = (u64)&g_cpu; - wrmsr(MSR_KERNEL_GS_BASE, (u64)&g_cpu); - - - u32 eax, ebx, ecx, edx; - - cpuid(0, 0, &eax, &ebx, &ecx, &edx); - - u32* vendor_ptr = (u32*)g_cpu.vendor; - vendor_ptr[0] = ebx; - vendor_ptr[1] = edx; - vendor_ptr[2] = ecx; - g_cpu.vendor[12] = '\0'; - - cpuid(1, 0, &eax, &ebx, &ecx, &edx); - - g_cpu.family = (eax >> 8) & 0xF; - g_cpu.model = (eax >> 4) & 0xF; - if (g_cpu.family == 6 || g_cpu.family == 15) { - g_cpu.model += ((eax >> 16) & 0xF) << 4; - } - - if (edx & (1 << 0)) g_cpu.features |= CPU_FEAT_FPU; - if (edx & (1 << 4)) g_cpu.features |= CPU_FEAT_TSC; - if (edx & (1 << 5)) g_cpu.features |= CPU_FEAT_MSR; - if (edx & (1 << 6)) g_cpu.features |= CPU_FEAT_PAE; - if (edx & (1 << 9)) g_cpu.features |= CPU_FEAT_APIC; - if (edx & (1 << 12)) g_cpu.features |= CPU_FEAT_MTRR; - if (edx & (1 << 25)) g_cpu.features |= CPU_FEAT_SSE; - if (edx & (1 << 26)) g_cpu.features |= CPU_FEAT_SSE2; - - if (ecx & (1 << 0)) g_cpu.features |= CPU_FEAT_SSE3; - if (ecx & (1 << 9)) g_cpu.features |= CPU_FEAT_SSSE3; - if (ecx & (1 << 19)) g_cpu.features |= CPU_FEAT_SSE4_1; - if (ecx & (1 << 20)) g_cpu.features |= CPU_FEAT_SSE4_2; - if (ecx & (1 << 28)) g_cpu.features |= CPU_FEAT_AVX; - if (ecx & (1 << 29)) g_cpu.features |= CPU_FEAT_F16C; - - if (ecx & (1 << 30)) g_cpu.features |= CPU_FEAT_RDRAND; - - if (ecx & (1 << 31)) g_cpu.features |= CPU_FEAT_HYPERVISOR; -} - -bool cpu_has(u64 feature) { - return (g_cpu.features & feature) != 0; -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/gdt.c b/kernel/src/arch/x86_64/gdt.c deleted file mode 100644 index 8d75e60..0000000 --- a/kernel/src/arch/x86_64/gdt.c +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -// just fucking kill me already - -#include -#define GDT_ENTIRES 7 - -GDTDescriptor gdt[GDT_ENTIRES]; -GDTPtr gdt_ptr; -TSS tss; -u8 double_fault_stack[4096] = {0}; - -void gdt_set_gate(int num, u64 base, u64 limit, u8 access, u8 gran) { - gdt[num].base_low = (base & 0xFFFF); // left only low 16bit - gdt[num].base_middle = (base >> 16) & 0xFF; // 3rd address byte - gdt[num].base_high = (base >> 24) & 0xFF; // 4th address byte - - gdt[num].limit_low = (limit & 0xFFFF); - gdt[num].granularity = (limit >> 16) & 0x0F; // leave only first 4 bits (limit's left 16-19) - gdt[num].granularity |= gran & 0xF0; // get flags and concate two pieces so FFFFLLLL (L -- Limit; F -- flags) - gdt[num].access = access; - - // fuck intel -} - - -void write_tss(int num) { - u64 base = (u64)&tss; - u64 limit = sizeof(tss); - u64 access = 0x89; // TSS_PRESENT | TSS_EXECUTABLE | TSS_ACCESSED; - u64 gran = 0; - - gdt_set_gate(num, base, limit, access, gran); - *((u64*)&gdt[num+1]) = (base >> 32); // really scary but not really hard - // just direct write 8bytes to num+1 - // basically a hack but at this point i dont care -} - - -extern void gdt_flush(u64 gdt_ptr_addr); // entry.asm - -void gdt_init() { - gdt_ptr.limit = (sizeof(GDTDescriptor) * GDT_ENTIRES) - 1; - gdt_ptr.base = (u64)&gdt; - - // 0: Null - gdt_set_gate(0, 0, 0, 0, 0); - - // 1: Kernel Code (Ring 0) - // Access: 0x9A (Present, Ring0, Exec/Read) - // Granularity: 0x20 (Long Mode bit) access ring 0 code exec code readable - gdt_set_gate(1, 0, 0, 0x9A, 0x20); // 0x9A = 1 00 1 1 0 1 - // 0x20 = 0010 0000 bit 5 is "Long mode" - // 2: Kernel Data (Ring 0) - // Access: 0x92 (Present, Ring0, Read/Write) - gdt_set_gate(2, 0, 0, 0x92, 0); // 0x92 = 1 00 1 0 0 1 - - // 3: User Data (Ring 3) - // Access: 0xF2 (Present, Ring3, Read/Write) - gdt_set_gate(3, 0, 0, 0xF2, 0); // 0xF2 = 1 11 1 0 0 1 - - // 4: User Code (Ring 3) - // Access: 0xFA (Present, Ring3, RWX) - gdt_set_gate(4, 0, 0, 0xFA, 0x20); // 0xFA = 1 11 1 1 0 1 - - for (u64 i = 0; i < sizeof(TSS); i++) ((u8*)&tss)[i] = 0; // zeroifying tss struct - - tss.iomap_base = sizeof(TSS); - tss.ist1 = (u64)double_fault_stack + sizeof(double_fault_stack); - write_tss(5); - - gdt_flush((u64)&gdt_ptr); - - // telling cpu that TSS info located at gdt[5]; offset = 5 * 8 = 40 = 0x28 - __asm__ volatile ("ltr %%ax" :: "a" (0x28)); -} - diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c deleted file mode 100644 index 85ef428..0000000 --- a/kernel/src/arch/x86_64/idt.c +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include -#include - -IDTEntry idt[256]; -IDTPtr idt_ptr; - -extern void isr0(); extern void isr1(); extern void isr2(); extern void isr3(); -extern void isr4(); extern void isr5(); extern void isr6(); extern void isr7(); -extern void isr8(); extern void isr9(); extern void isr10(); extern void isr11(); -extern void isr12(); extern void isr13(); extern void isr14(); extern void isr15(); -extern void isr16(); extern void isr17(); extern void isr18(); extern void isr19(); -extern void isr20(); extern void isr21(); extern void isr22(); extern void isr23(); -extern void isr24(); extern void isr25(); extern void isr26(); extern void isr27(); -extern void isr28(); extern void isr29(); extern void isr30(); extern void isr31(); -extern void irq0(void); extern void irq1(void); - -extern void idt_load(u64); // asm: lidt [rdi] / ret - -void idt_set_gate(int num, u64 handler, u16 sel, u8 flags) { - idt[num].offset_low = handler & 0xFFFF; - idt[num].offset_mid = (handler >> 16) & 0xFFFF; - idt[num].offset_high = (handler >> 32) & 0xFFFFFFFF; - - idt[num].selector = sel; // 0x08 (Kernel Code) - idt[num].ist = 0; - idt[num].attributes = flags; - idt[num].reserved = 0; -} - -void idt_init() { - idt_ptr.limit = (sizeof(IDTEntry) * 256) - 1; - idt_ptr.base = (u64)&idt; - - const u8 flags = 0x8E; - const u8 selector = 0x08; - - - idt_set_gate(0, (u64)isr0, selector, flags); - idt_set_gate(1, (u64)isr1, selector, flags); - idt_set_gate(2, (u64)isr2, selector, flags); - idt_set_gate(3, (u64)isr3, selector, flags); - idt_set_gate(4, (u64)isr4, selector, flags); - idt_set_gate(5, (u64)isr5, selector, flags); - idt_set_gate(6, (u64)isr6, selector, flags); - idt_set_gate(7, (u64)isr7, selector, flags); - idt_set_gate(8, (u64)isr8, selector, flags); - idt_set_gate(9, (u64)isr9, selector, flags); - idt_set_gate(10, (u64)isr10, selector, flags); - idt_set_gate(11, (u64)isr11, selector, flags); - idt_set_gate(12, (u64)isr12, selector, flags); - idt_set_gate(13, (u64)isr13, selector, flags); - idt_set_gate(14, (u64)isr14, selector, flags); - idt_set_gate(15, (u64)isr15, selector, flags); - idt_set_gate(16, (u64)isr16, selector, flags); - idt_set_gate(17, (u64)isr17, selector, flags); - idt_set_gate(18, (u64)isr18, selector, flags); - idt_set_gate(19, (u64)isr19, selector, flags); - idt_set_gate(20, (u64)isr20, selector, flags); - idt_set_gate(21, (u64)isr21, selector, flags); - idt_set_gate(22, (u64)isr22, selector, flags); - idt_set_gate(23, (u64)isr23, selector, flags); - idt_set_gate(24, (u64)isr24, selector, flags); - idt_set_gate(25, (u64)isr25, selector, flags); - idt_set_gate(26, (u64)isr26, selector, flags); - idt_set_gate(27, (u64)isr27, selector, flags); - idt_set_gate(28, (u64)isr28, selector, flags); - idt_set_gate(29, (u64)isr29, selector, flags); - idt_set_gate(30, (u64)isr30, selector, flags); - idt_set_gate(31, (u64)isr31, selector, flags); - - idt[8].ist = 1; // TSS - idt[13].ist = 1; - idt[14].ist = 1; - - idt_set_gate(32, (u64)irq0, selector, flags); - idt_set_gate(33, (u64)irq1, selector, flags); - - __asm__ volatile ("lidt %0" : : "m"(idt_ptr)); -} diff --git a/kernel/src/arch/x86_64/interrupts.c b/kernel/src/arch/x86_64/interrupts.c index ccf10db..3eae84b 100644 --- a/kernel/src/arch/x86_64/interrupts.c +++ b/kernel/src/arch/x86_64/interrupts.c @@ -1,41 +1,49 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2025 0xKarinyash -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include -extern task* curr_task; - -void isr_handler_c(Registers *regs) { - if (regs->int_no == 3) { - return print_regs(); +void isr_handler_c(CPURegisters* frame) { + if (frame->interruptNumber == 3) { + IOConsoleLog("--------------------------------\n"); + IOConsoleLog("\t\t^gREGISTERS^!\n"); + IOConsoleLog("--------------------------------\n"); + IOConsoleLog("^gRAX^!=%X, ^gRBX^!=%X\n", frame->rax, frame->rbx); + IOConsoleLog("^gRCX^!=%X, ^gRDX^!=%X\n", frame->rcx, frame->rdx); + IOConsoleLog("^gRSI^!=%X, ^gRDI^!=%X\n", frame->rsi, frame->rdi); + IOConsoleLog("^gRBP^!=%X, ^gR8^! =%X\n", frame->rbp, frame->r8); + IOConsoleLog("^gR9^! =%X, ^gR10^!=%X \n", frame->r9, frame->r10); + IOConsoleLog("^gR11^!=%X, ^gR12^!=%X\n", frame->r11, frame->r12); + IOConsoleLog("^gR13^!=%X, ^gR14^!=%X\n", frame->r13, frame->r14); + IOConsoleLog("^gR15^!=%X\n",frame->r15); + IOConsoleLog("--------------------------------\n"); } - if ((regs->cs & 3) != 0) { - kprintf("\n[Dewar] Process '%s' (PID %d) Segmentation Fault at %X\n", - curr_task->proc->name, curr_task->proc->pid, regs->rip); - curr_task->task_state = DEAD; - sys_exit(-1); - sched_next((u64)regs); + if ((frame->cs & 3) != 0) { + IOConsoleLog("\n[Dewar] Process '%s' (PID %d) Segmentation Fault at %X\n", + gOSSchedulerCurrentTask->process->name, gOSSchedulerCurrentTask->process->processId, frame->rip); + gOSSchedulerCurrentTask->taskState = kOSProcessStateDead; + OSServiceProcessExit(-1); + OSSchedulerNext((UInt64)frame); return; } - panic_exception(regs); + OSPanicException(frame); } -u64 irq_handler_c(Registers *regs) { - u64 curr_rsp = (u64)regs; - switch (regs->int_no) { - case 32: curr_rsp = timer_handler(regs); break; - case 33: kb_handler(); break; +UInt64 irq_handler_c(CPURegisters* regs) { + UInt64 curr_rsp = (UInt64)regs; + switch (regs->interruptNumber) { + case 32: curr_rsp = IOTimerInterruptsHandler(regs); break; + case 33: IOKeyboardInterruptsHandler(); break; default: break; } - outb(MASTER_COMMAND, 0x20); + IOPortWrite8(kIOMasterCommand, 0x20); return curr_rsp; } \ No newline at end of file diff --git a/kernel/src/arch/x86_64/pic.c b/kernel/src/arch/x86_64/pic.c deleted file mode 100644 index 46d04e3..0000000 --- a/kernel/src/arch/x86_64/pic.c +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include -#include -#include - - -u16 pic_remap() { - u8 curr_master = inb(MASTER_DATA); - u8 curr_slave = inb(SLAVE_DATA); - - // initialization; icw1 - outb_wait(MASTER_COMMAND, 0x11); - outb_wait(SLAVE_COMMAND, 0x11); - - // icw2 - outb_wait(MASTER_DATA, 0x20); // master now controlling idt[32..39] - outb_wait(SLAVE_DATA, 0x28); // idt[40..47] - - // icw3 - outb_wait(MASTER_DATA, 0x04); // slave on irq2 - outb_wait(SLAVE_DATA, 0x02); // assign id = 2 to slave - - // icw4; 0x01 -- 8086 mode - outb_wait(MASTER_DATA, 0x01); - outb_wait(SLAVE_DATA, 0x01); - - outb_wait(MASTER_DATA, 0xFD); // 1111 1101 - // 0 -- means 'on' - outb_wait(SLAVE_DATA, 0xFF); // Everything ON - - return ((u16) curr_master << 8) | curr_slave; -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscall.c b/kernel/src/arch/x86_64/syscall.c index 20a44bf..f842d43 100644 --- a/kernel/src/arch/x86_64/syscall.c +++ b/kernel/src/arch/x86_64/syscall.c @@ -1,66 +1,66 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2026 0xKarinyash -#include +#include #include #include -#include -#include -#include +#include +#include +#include -#include -#include -#include +#include +#include +#include -static inline void wrmsr(u32 msr, u64 val) { - u32 low = (u32)val; - u32 high = (u32)(val >> 32); +static inline void WRMSR(UInt32 msr, UInt64 value) { + UInt32 low = (UInt32)value; + UInt32 high = (UInt32)(value >> 32); __asm__ volatile("wrmsr" :: "a"(low), "d"(high), "c"(msr)); } -static inline u64 rdmsr(u32 msr) { - u32 low, high; +static inline UInt64 RDMSR(UInt32 msr) { + UInt32 low, high; __asm__ volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr)); - return ((u64)high << 32) | low; + return ((UInt64)high << 32) | low; } extern void syscall_entry(); -void syscall_init() { - u64 efer = rdmsr(MSR_EFER); - wrmsr(MSR_EFER, efer | 1); // Enabling SCE in EFER. Just enabling 0 bit +void OSServicesInitialize() { + UInt64 efer = RDMSR(kHALModelSpecificRegisterExtendedFeatureEnable); + WRMSR(kHALModelSpecificRegisterExtendedFeatureEnable, efer | 1); // Enabling SCE in EFER. Just enabling 0 bit // setting up STAR // 32:47 kernel selector (0x08) // 48:64 user selector (0x01 cuz sysret adds +16 for CS and +8 for SS) - u64 star = (0x13ULL << 48) | (0x08ULL << 32); - wrmsr(MSR_STAR, star); + UInt64 star = (0x13ULL << 48) | (0x08ULL << 32); + WRMSR(kHALModelSpecificRegisterSystemCallTarget, star); - wrmsr(MSR_LSTAR, (u64)syscall_entry); // setting handler adress + WRMSR(kHALModelSpecificRegisterLongSystemCallTarget, (UInt64)syscall_entry); // setting handler adress // masking flags (IA32_FMASK) // 9 bit for finterrupts in syscall (IF) and few more necessary flags - wrmsr(MSR_FMASK, 0x200); // masking only IF + WRMSR(kHALModelSpecificRegisterSystemCallFlagMask, 0x200); // masking only IF - if (g_cpu.kernel_rsp == 0) { - void* stack_phys = pmm_alloc_page(); - g_cpu.kernel_rsp = (u64)stack_phys + HHDM_OFFSET + 4096; + if (gOSBootCPU.kernelStackPointer == 0) { + void* physicalStackPointer = VMPhysicalMemoryAllocatePage(); + gOSBootCPU.kernelStackPointer = (UInt64)physicalStackPointer + HHDM_OFFSET + 4096; } - wrmsr(MSR_GS_BASE, (u64)&g_cpu); - wrmsr(MSR_KERNEL_GS_BASE, (u64)&g_cpu); + WRMSR(kHALModelSpecificRegisterGSBase, (UInt64)&gOSBootCPU); + WRMSR(kHALModelSpecificRegisterKernelGSBase, (UInt64)&gOSBootCPU); } -u64 syscall_dispatch(u64 id, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5) { +UInt64 syscall_dispatch(UInt64 id, UInt64 arg1, UInt64 arg2, UInt64 arg3, UInt64 arg4, UInt64 arg5) { switch (id) { - case SYS_EXIT: return sys_exit(arg1); - case SYS_SPAWN: return sys_spawn((const char*)arg1); - case SYS_MEM: return sys_mem(arg1); - case SYS_WRITE: return sys_write(arg1, arg2, arg3); - case SYS_READ: return sys_read(arg1, arg2, arg3); - case SYS_WAIT: return sys_wait(arg1); + case SYS_EXIT: return OSServiceProcessExit(arg1); + case SYS_SPAWN: return OSServiceProcessSpawn((const char*)arg1); + case SYS_MEM: return OSServiceMemoryGet(arg1); + case SYS_WRITE: return OSServiceWrite(arg1, arg2, arg3); + case SYS_READ: return OSServiceRead(arg1, arg2, arg3); + case SYS_WAIT: return OSServiceProcessWait(arg1); default: - kprintf("[Dewar] Unknown syscall %d\n", id); + IOConsoleLog("[Dewar] Unknown syscall %d\n", id); return -1; } } \ No newline at end of file diff --git a/kernel/src/core/hot.c b/kernel/src/core/hot.c deleted file mode 100644 index c1c7b9b..0000000 --- a/kernel/src/core/hot.c +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#include -#include -#include - -#include -#include -#include -#include - -#include "../../common/hot_header.h" - -u64 load_hot(process* proc, u8* data) { - hot_header* header = (hot_header*)data; - if (header->magic != HOT_MAGIC) { - return -1; - } - - hot_segment* segments = (hot_segment*)(data + sizeof(hot_header)); - for (u64 i = 0; i < header->segments_count; i++) { - hot_segment* seg = &segments[i]; - if (seg->memsz == 0) continue; - - u64 start = seg->vaddr & ~(0xFFFULL); - u64 end = (seg->vaddr + seg->memsz + 0xFFF) & ~(0xFFFULL); - - for (u64 addr = start; addr < end; addr += PAGE_SIZE) { - void* phys = pmm_alloc_page(); - vmm_map_page((u64*)proc->pml4_phys, (u64)phys, addr, PTE_USER | PTE_RW | PTE_PRESENT); - void* kernel_virt = (void*)((u64)phys + HHDM_OFFSET); - memset(kernel_virt, 0, PAGE_SIZE); - u64 page_overleap_start = (addr > seg->vaddr) ? addr : seg->vaddr; - u64 page_overleap_end = (addr + PAGE_SIZE < seg->vaddr + seg->filesz) - ? (addr + PAGE_SIZE) - : (seg->vaddr + seg->filesz); - if (page_overleap_start < page_overleap_end) { - u64 copy_size = page_overleap_end - page_overleap_start; - u64 src_offset = seg->offset + (page_overleap_start - seg->vaddr); - u64 dst_offset = page_overleap_start - addr; - - memcpy((u8*)kernel_virt + dst_offset, data + src_offset, copy_size); - } - } - } - - return header->entry_point; -} \ No newline at end of file diff --git a/kernel/src/core/loader.c b/kernel/src/core/loader.c deleted file mode 100644 index 75be23b..0000000 --- a/kernel/src/core/loader.c +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - -#include -#include - -extern task* curr_task; -extern u32 next_pid; - -#define USER_STACK_TOP 0x70000000 -#define HEAP_START 0x40000000 - -i32 process_spawn(const char* path, const char* name) { - fs_node* file = vfs_open(path); - if (!file) return -1; - - process* new_proc = (process*)malloc(sizeof(process)); - if (!new_proc) return -2; - memset(new_proc, 0, sizeof(process)); - new_proc->pid = next_pid++; - new_proc->state = RUNNING; - new_proc->pml4_phys = vmm_create_address_space(); - new_proc->heap_start = HEAP_START; - new_proc->heap_cur = HEAP_START; - strncpy(new_proc->name, name, 31); - - u8* file_buffer = (u8*)malloc(file->len); - if (!file_buffer) { - free(new_proc); - return -3; - } - vfs_read(file, 0, file->len, file_buffer); - - u64 entry = load_hot(new_proc, file_buffer); - if (!entry) return -4; - - free(file_buffer); - - vmm_setup_user_stack((u64*)new_proc->pml4_phys); - sched_spawn((void(*)())entry, new_proc, true, USER_STACK_TOP); - - return new_proc->pid; -} - -void init_task_entry() { - i32 pid = process_spawn("/bin/init", "init"); - if (pid < 0) { - panic("FATAL: Failed to spawn /bin/init"); - } - - while (1) { __asm__("sti; hlt"); } -} \ No newline at end of file diff --git a/kernel/src/core/panic.c b/kernel/src/core/panic.c deleted file mode 100644 index 645bb85..0000000 --- a/kernel/src/core/panic.c +++ /dev/null @@ -1,168 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include -#include - -#include -#include - -#include - -const char* fun_messages[] = { - "Execution finished abnormally with code: 0x_x", - "It's definitely your fault.", - "No more Roblox!", - "Call your mom 4 help!", - "2bad4u", - "Touch grass", - "Skill issue", - "You should just go outside actually", - "Perfect opportunity to take a shower", - "404 not found", - "Windows is locked! Password:___ Time left: 5:45:41", - "GOOOOOAL", - "\"NAM PIZDA\": hackers dropped our registry", - "geeked vs locked in", - "HEEEELP!", - "LET ME GO!", - "You little asshole, make it better", - "Go and read books for programming u idiot", - "TIME TO BRAKE! :3 Take a tea and try again later cutie", - "Code have been eaten by Aliens", - "That's all, folks!", - "Raiden, answer me, Raiden, respond! Raiden?! RAIDEEEEEEEEEN!", - "I'll be back", - "Hastla la vista, baby", - "Ti chego mne tut nagovoril...", - "Your access has been denied because of your region.\n\t\t\t\tPlease, use Chultem VPN and try again later.", - "Fatal error has been occurred. \n\t\t\t\tYour device will be transformed into Niva in a few seconds.", - "Have you tried turning it off and on again?", - "Put it in rice maybe?", - "Just hit the monitor, it usually helps", - "I think it needs a rest. Come back tomorrow", - "You clicked something wrong, didn't you?", - "You hacked it too hard, bro", - "I think you deleted the internet", - "Stop downloading RAM", - "Pro tip: dont crash", - "Stop ricing the kernel you loonixtard, TermOS is NOT Loonix", - "Attaboy, Jack. He's good. Really good.", - "Zhenih priehal", - "YOUR PC WAS BLOCKED BY FBI FOR WATCHING PORNOGRAPHY SEND 20 US DOLLARS", - "fuck off", - "Your GPU is now mining Ethereum for me. Thanks.", - "Your PC is locked!\n\t\t\t\tPay a fee of 0.019082006 bitcoins to a wallet 1KtoProchitalTotSosal to get decryption key!", -}; - - -const char* exception_messages[] = { - "Division By Zero", - "Debug", - "Non Maskable Interrupt", - "Breakpoint", - "Into Detected Overflow", - "Out of Bounds", - "Invalid Opcode", - "Device Not Available", - "Double Fault", - "Coprocessor Segment Overrun", - "Bad TSS", - "Segment Not Present", - "Stack Fault", - "General Protection Fault", - "Page Fault", - "Reserved", - "x87 Floating-Point Exception", - "Alignment Check", - "Machine Check", - "SIMD Floating-Point Exception", - "Virtualization Exception", - "Control Protection Exception", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Hypervisor Injection Exception", - "VMM Communication Exception", - "Security Exception", - "Reserved" -}; - -__attribute__((noreturn)) void die() { - while (1) { - __asm__ volatile ("cli; hlt"); - } -} - -void draw_panic_bg() { - console_clear(0x000000); - console_set_color(0xFFFFFF); - console_set_default_color(0xFFFFFF); - - u64 msg_count = sizeof(fun_messages) / sizeof(fun_messages[0]); - u8 rand_num = krand() % msg_count; - - kprintf("\n\n"); - kprintf("\t\t\t\t^bKERNEL PANIC^! :( \n"); - kprintf("\t\t--------------------------------\n"); - kprintf("\t\t^y%s^!\n", fun_messages[rand_num]); - kprintf("\t\t--------------------------------\n"); -} - -__attribute__((noreturn)) void panic_exception(Registers *regs) { - draw_panic_bg(); - - kprintf("\t\t^yCPU EXCEPTION^!: ^b%s^! (%d)\n", exception_messages[regs->int_no], regs->int_no); - if (regs->err_code) kprintf("\t\t^yError Code^!: %X\n", regs->err_code); - kprintf("\t\t^yInstruction Pointer^! (^yRIP^!): %X\n", regs->rip); - kprintf("\t\t^yCode Segment^! (^yCS^!): %X\n", regs->cs); - kprintf("\t\t^yFlags^! (^yRFLAGS^!): %X\n", regs->rflags); - kprintf("\t\t^yStack Pointer^! (^yRSP^!): %X\n", regs->rsp); - if (regs->int_no == 14) { - kprintf("\t\t--------------------------------\n"); - kprintf("\t\t ^yPage Fault Helper^! \n"); - kprintf("\t\t--------------------------------\n"); - u64 cr2; - __asm__ volatile("mov %%cr2, %0" : "=r"(cr2)); - kprintf("\t\t^yFaulting Address^! (^yCR2^!): %X\n", cr2); - kprintf("\t\t^yERRCode^!: %X\n", regs->err_code); - u64 present = (regs->err_code & (1 << 0)) != 0; - u64 write = (regs->err_code & (1 << 1)) != 0; - u64 user = (regs->err_code & (1 << 2)) != 0; - u64 reserved = (regs->err_code & (1 << 3)) != 0; - u64 instruction = (regs->err_code & (1 << 4)) != 0; - kprintf("\t\t\t[^bP^!] ^yReason^!: %s\n", present ? "Page Protection violation" : "Non-present page"); - kprintf("\t\t\t[^bW^!] ^yCaused by^! %s\n", write ? "WRITE" : "READ"); - kprintf("\t\t\t[^bU^!] ^yRing^! %s\n", user ? "3" : "0"); - if (reserved) kprintf("\t\t\t[^bR^!] CPU Wrote 1 to a reserved field in page table entry. ^rCorrupt page table?^!\n"); - if (instruction) kprintf("\t\t\t[^bI^!] ^yTried to^! execute ^ycode from^! NX ^ymemory^!\n"); - } - kprintf("\t\t--------------------------------\n"); - kprintf("\t\t\t\t^yREGISTERS^!\n"); - kprintf("\t\t--------------------------------\n"); - kprintf("\t\t^yRAX^!=%X, ^yRBX^!=%X\n", regs->rax, regs->rbx); - kprintf("\t\t^yRCX^!=%X, ^yRDX^!=%X\n", regs->rcx, regs->rdx); - kprintf("\t\t^yRSI^!=%X, ^yRDI^!=%X\n", regs->rsi, regs->rdi); - kprintf("\t\t^yRBP^!=%X, ^yR8^! =%X\n", regs->rbp, regs->r8); - kprintf("\t\t^yR9^! =%X, ^yR10^!=%X \n", regs->r9, regs->r10); - kprintf("\t\t^yR11^!=%X, ^yR12^!=%X\n", regs->r11, regs->r12); - kprintf("\t\t^yR13^!=%X, ^yR14^!=%X\n", regs->r13, regs->r14); - kprintf("\t\t^yR15^!=%X\n",regs->r15); - kprintf("\t\t--------------------------------\n"); - kprintf("\t\t\t\t^bSystem halted.^!\n"); - - die(); -} - -__attribute__((noreturn)) void panic(const char* msg) { - draw_panic_bg(); - - kprintf("\t\t^yReason^!: %s\n", msg); - kprintf("\t\t--------------------------------\n"); - kprintf("\t\t\t\t^bSystem halted.^!\n"); - - die(); -} \ No newline at end of file diff --git a/kernel/src/core/rand.c b/kernel/src/core/rand.c deleted file mode 100644 index 319b04c..0000000 --- a/kernel/src/core/rand.c +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include "bootinfo.h" -#include -#include -#include - -static u64 prng_state = 0; - -static inline u64 rdtsc() { - u32 lo, hi; - __asm__ volatile ("rdtsc" : "=a" (lo), "=d" (hi)); - - return ((u64)hi << 32) | lo; -} - -void rng_init() { - prng_state = rdtsc(); - if (prng_state == 0) prng_state = BOOTINFO_MAGIC; // why not reuse "termOS"? -} - -static u64 xorshift_rand() { - u64 x = prng_state; - x ^= x << 13; - x ^= x >> 7; - x ^= x << 17; - return prng_state = x; -} - -static bool hw_rand(u64 *val) { - u8 ok; - __asm__ volatile ("rdrand %0; setc %1" - : "=r" (*val), "=qm" (ok)); - return ok != 0; -} - -u64 krand() { - u64 res; - if (cpu_has(CPU_FEAT_RDRAND)) { - if (hw_rand(&res)) return res; - } - - return xorshift_rand(); -} \ No newline at end of file diff --git a/kernel/src/core/scheduler.c b/kernel/src/core/scheduler.c deleted file mode 100644 index 0154a4f..0000000 --- a/kernel/src/core/scheduler.c +++ /dev/null @@ -1,147 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include -#include -#include -#include -#include -#include -#include -#include - -task* curr_task = nullptr; -u32 next_pid = 1; - -extern void irq0_handler(); -extern u64 pml4_kernel_phys; - -static process kernel_process; - -void idle_task() { - while (1) { - __asm__ volatile ("hlt"); - } -} - -void sched_init() { - kernel_process.pid = 0; - kernel_process.state = RUNNING; - kernel_process.pml4_phys = pml4_kernel_phys; - strcpy(kernel_process.name, "kernel"); - - task* kt = (task*)malloc(sizeof(task)); - memset(kt, 0, sizeof(task)); - kt->id = 0; - kt->proc = &kernel_process; - kt->sleep_ticks = 0; - kt->next = kt; - kt->task_state = RUNNING; - kt->waiting_on_pid = -1; - - curr_task = kt; - sched_spawn(idle_task, &kernel_process, false, 0); -} - -task* sched_spawn(void(*entry)(), process* owner, bool is_user, u64 fixed_user_stack) { - task* t = (task*)malloc(sizeof(task)); - if (!t) return nullptr; - if (!owner) owner = &kernel_process; - - u64 stack_size = 16384; - u8* stack_base = (u8*)malloc(stack_size); - if (!stack_base) panic("OOM for task stack"); - u64* rsp = (u64*)(stack_base + stack_size); - - u64 cs = is_user ? 0x23 : 0x08; - u64 ss = is_user ? 0x1b : 0x10; - u64 rflags = 0x202; - u64 target_rsp = 0; - if (is_user) target_rsp = fixed_user_stack; - else target_rsp = (u64)stack_base + stack_size; - - *--rsp = ss; // SS -- Kernel data - *--rsp = target_rsp; // rsp - *--rsp = rflags; // RFLAGS -- Interrupts Enabled | Reserved bit; - *--rsp = cs; // CS -- Kernel Code; - *--rsp = (u64)entry; // RIP - - *--rsp = 0; // int no - *--rsp = 0; // err code - - for (u8 i = 0; i < 15; i++) *--rsp = 0; // R15 .. RAX - - t->rsp = (u64)rsp; - t->proc = owner; - t->id = owner->pid; - t->sleep_ticks = 0; - t->next = curr_task->next; - t->kernel_stack_top = (u64)stack_base + stack_size; - t->task_state = RUNNING; - t->waiting_on_pid = -1; - curr_task->next = t; - return t; -} - -u64 sched_next(u64 curr_rsp) { - if (!curr_task) return curr_rsp; - - curr_task->rsp = curr_rsp; - task* it = curr_task->next; - - do { - if (it->sleep_ticks > 0) it->sleep_ticks--; - it = it->next; - } while (it != curr_task->next); - - if (curr_task->sleep_ticks > 0) curr_task->sleep_ticks--; - - task* next = curr_task; - while (1) { - // TODO: add gc here; - next = next->next; - if (next->task_state == SLEEPING && next->sleep_ticks == 0) next->task_state = RUNNING; - if (next->task_state == RUNNING) break; - if (next == curr_task) { - if (curr_task->task_state == RUNNING) break; - panic("no running tasks"); - } - } - - if (next->proc->pml4_phys != curr_task->proc->pml4_phys) load_cr3(next->proc->pml4_phys); - curr_task = next; - tss.rsp0 = curr_task->kernel_stack_top; - g_cpu.kernel_rsp = curr_task->kernel_stack_top; - return curr_task->rsp; -} - -void sched_block(u32 pid) { - curr_task->task_state = BLOCKED; - curr_task->waiting_on_pid = pid; - __asm__ volatile("int $32"); -} - -void sched_wakeup(u32 pid) { - task* it = curr_task; - do { - if (it->task_state == BLOCKED && it->waiting_on_pid == (i32)pid) { - it->task_state = RUNNING; - it->waiting_on_pid = -1; - } - it = it->next; - } while (it != curr_task); -} - -void sched_exit() { - u32 my_pid = curr_task->id; - curr_task->task_state = DEAD; - - sched_wakeup(my_pid); - __asm__ volatile("int $32"); -} - -void yield(u64 ticks) { - curr_task->sleep_ticks = ticks; - curr_task->task_state = SLEEPING; - __asm__ volatile("hlt"); -} \ No newline at end of file diff --git a/kernel/src/core/splash.c b/kernel/src/core/splash.c deleted file mode 100644 index c528073..0000000 --- a/kernel/src/core/splash.c +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash -#include -#include -#include "../data/logo.h" - -void show_splash(SG_Context *sg_ctx) { - SG_Point logo_point = {0, 10}; - sg_put_img(sg_ctx, &logo_point, &logo_img); - SG_Point start_pos = {75, 55}; // greeting - console_set_cursor_pos(&start_pos); - kprintf("Welcome to ^ptermOS^!!!!\n"); - - SG_Point text_normal_point = {0, 120}; // not nice to hardcode nums like that but we have what we have - console_set_cursor_pos(&text_normal_point); -} diff --git a/kernel/src/drivers/console.c b/kernel/src/drivers/console.c deleted file mode 100644 index 403c706..0000000 --- a/kernel/src/drivers/console.c +++ /dev/null @@ -1,305 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include "core/scheduler.h" -#include -#include -#include -#include -#include - -#include -#include - -#include - -#define COLOR_RED 0xFF5555 -#define COLOR_VERYRED 0xFF0000 -#define COLOR_GREEN 0x08bf39 -#define COLOR_VERYGREEN 0x00FF00 -#define COLOR_TURQUOISE 0x5effaf -#define COLOR_BLUE 0x5555FF -#define COLOR_VERYBLUE 0x0000FF -#define COLOR_LIGHTBLUE 0x3890e8 -#define COLOR_YELLOW 0xFFFF55 -#define COLOR_CYAN 0x55FFFF -#define COLOR_MAGENTA 0xFF55FF -#define COLOR_BLACK 0x000000 -#define COLOR_WHITE 0xFFFFFF -#define COLOR_PINK 0xFFA3B1 - -static SG_Context *ctx_ptr = nullptr; -static SG_Point s_cursor_pos = {0}; -static SG_Font s_font = {0}; -static u32 s_color = COLOR_WHITE; -static u32 s_def_color = COLOR_WHITE; -static u32 s_bg_color = COLOR_BLACK; -static bool s_are_we_blinkin = true; -static bool s_waiting_for_input = false; -static bool s_cursor_visible = false; - -void console_init(SG_Context *ctx) { - ctx_ptr = ctx; - s_cursor_pos.x = 0; - s_cursor_pos.y = 0; - - s_font.h = 16; - s_font.w = 8; - s_font.base = (const unsigned char*)font8x16; -} - -u64 console_get_colors() { - return ((u64) s_color << 32) | s_bg_color; -} - -void console_clear(u32 color) { - if (!ctx_ptr) return; - - SG_Point p = {0, 0}; - sg_draw_rect(ctx_ptr, &p, ctx_ptr->width, ctx_ptr->height, color); - - s_cursor_pos.x = 0; - s_cursor_pos.y = 0; - s_bg_color = color; -} - -SG_Context* console_get_context() { - return ctx_ptr; -} - -SG_Point console_get_dimensions() { - SG_Point p = {0}; - p.x = ctx_ptr->width; - p.y = ctx_ptr->height; - return p; -} - -void console_set_cursor_pos(SG_Point *p) { - if (!p) return; - s_cursor_pos.x = p->x; - s_cursor_pos.y = p->y; -} - -void console_putc(char c) { - serial_writec(c); - if (!ctx_ptr) return; - if (c == '\n') { - s_cursor_pos.x = 0; - s_cursor_pos.y += s_font.h; - } else if (c == '\t') { - s_cursor_pos.x += s_font.w * 4; - } else if (c == '\b') { - s_cursor_pos.x -= s_font.w; - sg_draw_rect(ctx_ptr, &s_cursor_pos, s_font.w, s_font.h, s_bg_color); - } else { - sg_draw_char_bitmap(ctx_ptr, &s_cursor_pos, c, s_color, &s_font); - s_cursor_pos.x += s_font.w; - } - - if (s_cursor_pos.x >= ctx_ptr->width) { - s_cursor_pos.x = 0; - s_cursor_pos.y += s_font.h; - } - if (s_cursor_pos.y >= ctx_ptr->height) { - console_clear(s_bg_color); // TODO: do scrolling - } -} - -void kprint(const char *str) { - for (i32 i = 0; str[i] != '\0'; i++) console_putc(str[i]); -} - -static void print_dec(const i64 n) { - if (n < 0) console_putc('-'); - u64 u = abs(n); - char buffer[32]; - i32 i = 0; - - do { - buffer[i] = (u % 10) + '0'; - u /= 10; - i++; - } while (u > 0); - - while (--i >= 0) { - console_putc(buffer[i]); - } -} - -static void print_hex(u64 u, u8 padding) { - console_putc('0'); - console_putc('x'); - - if (u == 0) { - console_putc('0'); - for (i32 i = 1; i < padding; i++) console_putc('0'); - return; - } - - char buffer[16] = {0}; - i32 i = 0; - - do { - i32 digit = u % 16; - if (digit < 10) buffer[i++] = digit + '0'; - else buffer[i++] = digit - 10 + 'A'; - u /= 16; - } while (u > 0); - - while(i < padding) { - console_putc('0'); - padding--; - } - - while (--i >= 0) { - console_putc(buffer[i]); - } -} - - -void kprintf(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - - for (i32 i = 0; fmt[i] != '\0'; i++) { - if (fmt[i] == '%') { - i++; - switch (fmt[i]) { - case 's': { - const char *str = va_arg(args, const char*); - if (!str) str = "undefined"; - kprint(str); - break; - } - case 'c': { - char c = (char)va_arg(args, int); - console_putc(c); - break; - } - case 'd': { - i32 num = va_arg(args, i32); - print_dec(num); - break; - } - case 'x': { - u64 num = va_arg(args, u64); - print_hex(num, 0); - break; - } - case 'X' : { - u64 num = va_arg(args, u64); - print_hex(num, 16); - break; - } - default: { - console_putc(fmt[i]); - break; - } - } - } else if (fmt[i] == '^') { - i++; - switch (fmt[i]) { - case 'r': console_set_color(COLOR_RED); break; - case 'R': console_set_color(COLOR_VERYRED); break; - case 'g': console_set_color(COLOR_GREEN); break; - case 'G': console_set_color(COLOR_VERYGREEN); break; - case 't': console_set_color(COLOR_TURQUOISE); break; - case 'b': console_set_color(COLOR_BLUE); break; - case 'B': console_set_color(COLOR_VERYBLUE); break; - case 'l': console_set_color(COLOR_LIGHTBLUE); break; - case 'y': console_set_color(COLOR_YELLOW); break; - case 'c': console_set_color(COLOR_CYAN); break; - case 'm': console_set_color(COLOR_MAGENTA); break; - case 'p': console_set_color(COLOR_PINK); break; - case '0': console_set_color(COLOR_BLACK); break; - case 'w': console_set_color(COLOR_WHITE); break; - case '!': console_set_color(s_def_color); break; - case '~': console_set_color(~s_bg_color); break; - case '^': console_putc('^'); break; - default: { - console_putc('^'); - console_putc(fmt[i]); - break; - } - } - } else { - console_putc(fmt[i]); - } - } - - va_end(args); -} - -void console_set_color(u32 color) { - s_color = color; -} - -void console_set_default_color(u32 color) { - s_def_color = color; -} - -char console_getc() { - s_waiting_for_input = true; - while (kb_buf.head == kb_buf.tail) { __asm__ volatile ("sti"); yield(1); } - __asm__ volatile ("cli"); - s_waiting_for_input = false; - char temp = kb_buf.buffer[kb_buf.tail]; - kb_buf.tail = (kb_buf.tail + 1) % KB_BUFF_SIZE; - __asm__ volatile ("sti"); - if (s_cursor_visible) { - cursor_blink(); - s_cursor_visible = false; - } - return temp; -} - -void kgets(char* buff, u32 lim) { - u32 i = 0; - while (true) { - char c = console_getc(); - switch (c) { - case '\n': { - buff[i] = '\0'; - kprintf("\n"); - return; - } - case '\b': { - if (i > 0) { - i--; - kprintf("\b \b"); - } - break; - } - default: { - if (i < lim - 1) { - buff[i] = c; - kprintf("%c", c); - i++; - } - } - } - } -} - -void cursor_blink() { - sg_draw_rect(ctx_ptr, &s_cursor_pos, s_font.w, s_font.h, sg_get_pixel(ctx_ptr, &s_cursor_pos) ^ 0xFFFFFF); -} - -void cursor_blinker_sched_task() { - while (true) { - if (s_are_we_blinkin) { - if (s_waiting_for_input) { - cursor_blink(); - s_cursor_visible = !s_cursor_visible; - } - } else if (s_cursor_visible) { - cursor_blink(); - s_cursor_visible = !s_cursor_visible; - } - yield(500); - } -} - -void console_toggle_cursor_blink() { - s_are_we_blinkin = !s_are_we_blinkin; -} \ No newline at end of file diff --git a/kernel/src/drivers/serial.c b/kernel/src/drivers/serial.c deleted file mode 100644 index 7fe2104..0000000 --- a/kernel/src/drivers/serial.c +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include -#include - -#define PORT 0x3F8 // com1 - -int serial_init() { - outb(PORT + 1, 0x00); // interrupt enable register (+1) / disable interruptions - outb(PORT + 3, 0x80); // line control register (+3) - outb(PORT + 0, 0x03); // speed : low byte - outb(PORT + 1, 0x00); // speed : high byte - outb(PORT + 3, 0x03); // line control register (+3) / reset DLAB / no parity / 1 stop bit / (8N1) - outb(PORT + 2, 0xC7); // FIFO Control register (+2) / 1100 0111 / last ones are enable FIFO buff / first ones to clean noise - outb(PORT + 4, 0x0B); // ready :3 - return 0; -} - -static int is_transmit_empty() { - return inb(PORT + 5) & 0x20; // checking 5th bit LSR -} - -void serial_writec(char chr) { - while (is_transmit_empty() == 0); // waiting for buffer to flush (spinlock) - outb(PORT, chr); -} - -void serial_write(const char *str) { - for (int i = 0; str[i] != '\0'; i++) serial_writec(str[i]); -} \ No newline at end of file diff --git a/kernel/src/drivers/shitgui.c b/kernel/src/drivers/shitgui.c deleted file mode 100644 index 6bd11de..0000000 --- a/kernel/src/drivers/shitgui.c +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include -#include -#include -#include -#include - -#define SHITGUI_TRANSPARENCY_KEY 0xFF00FF - -SG_Context* main_context; - -void sg_init(SG_Context *ctx) { - main_context = ctx; -} - -u32 sg_get_pixel(SG_Context *ctx, SG_Point *p) { - if (!ctx->fb || !p || p->x >= ctx->width || p->y >= ctx->height) return 0; - return ctx->fb[p->y * ctx->pitch + p->x]; -} - -void sg_put_img(SG_Context *ctx, SG_Point *p, SG_Image *img) { - if (!ctx->fb || !img) return; - - u32 start_x = p->x; - u32 start_y = p->y; - u32 draw_w = img->width; - u32 draw_h = img->height; - - if (start_x >= ctx->width || start_y >= ctx->height) return; - if (start_x + draw_w > ctx->width) draw_w = ctx->width - start_x; - if (start_y + draw_h > ctx->height) draw_h = ctx->height - start_y; - - for (u32 y = 0; y < draw_h; y++) { - volatile u32 *dest_ptr = &ctx->fb[(start_y + y) * ctx->pitch + start_x]; - u32 *src_ptr = &img->buffer[y * img->width]; - for (u32 x = 0; x < draw_w; x++) { - u32 color = src_ptr[x]; - if (color != SHITGUI_TRANSPARENCY_KEY) dest_ptr[x] = color; - } - } -} - -void sg_draw_rect(SG_Context *ctx, SG_Point *p, u32 w, u32 h, u32 color) { - if (!ctx->fb) return; - - u32 start_x = p->x; - u32 start_y = p->y; - u32 draw_w = w; - u32 draw_h = h; - - if (start_x >= ctx->width || start_y >= ctx->height) return; - if (start_x + draw_w > ctx->width) draw_w = ctx->width - start_x; - if (start_y + draw_h > ctx->height) draw_h = ctx->height - start_y; - - - for (u32 y = 0; y < draw_h; y++) { - volatile u32 *row_ptr = &ctx->fb[(start_y + y) * ctx->pitch + start_x]; - for (u32 x = 0; x < draw_w; x++) row_ptr[x] = color; - } -} - -void sg_draw_char_bitmap(SG_Context *ctx, SG_Point *p, char c, u32 color, SG_Font *font) { - if (!ctx->fb) return; - - u32 start_x = p->x; - u32 start_y = p->y; - u32 draw_w = font->w; - u32 draw_h = font->h; - - if (start_x >= ctx->width || start_y >= ctx->height) return; - if (start_x + draw_w > ctx->width) draw_w = ctx->width - start_x; - if (start_y + draw_h > ctx->height) draw_h = ctx->height - start_y; - - for (u32 y = 0; y < draw_h; y++) { - u8 bitmap_row = font->base[(unsigned char)c * font->h + y]; - volatile u32 *row_ptr = &ctx->fb[(start_y + y) * ctx->pitch + start_x]; - for (u32 x = 0; x < draw_w; x++) { - if (bitmap_row & (1 << (7 - x))) { - row_ptr[x] = color; - } - } - } -} \ No newline at end of file diff --git a/kernel/src/drivers/timer.c b/kernel/src/drivers/timer.c deleted file mode 100644 index 3f62358..0000000 --- a/kernel/src/drivers/timer.c +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include -#include -#include -#include - -#define PIT_BASE_CLOCK 1193180 -#define PIT_CMD 0x43 -#define PIT_DATA 0x40 - -volatile u64 ticks = 0; - -void timer_init(u32 freq) { - u32 divisor = PIT_BASE_CLOCK / freq; - - outb(PIT_CMD, 0x36); // 0x36 = 00110110 = channel 0, LOHI byte access, Mode 3, binary - outb(PIT_DATA, divisor & 0xFF); - outb(PIT_DATA, (divisor >> 8) & 0xFF); - - u8 mask = inb(0x21); - mask &= ~(1 << 0); - outb(0x21, mask); -} - -u64 timer_handler(Registers *regs) { - ticks++; - return sched_next((u64)regs); -} - - -void sleep(u64 ms) { - u64 start = ticks; - while (ticks < start + ms) __asm__ volatile ("hlt"); -} - -u64 get_uptime() { - return ticks; -} \ No newline at end of file diff --git a/kernel/src/fs/cpio.c b/kernel/src/fs/cpio.c deleted file mode 100644 index 2ddeba4..0000000 --- a/kernel/src/fs/cpio.c +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#include -#include -#include -#include -#include -#include -#include -#include - -#define ALIGN4(x) (((x) + 3) & ~3) - -typedef struct { - char c_magic[6]; // "070701" - char c_ino[8]; - char c_mode[8]; // type and flags - char c_uid[8]; - char c_gid[8]; - char c_nlink[8]; - char c_mtime[8]; - char c_filesize[8]; - char c_devmajor[8]; - char c_devminor[8]; - char c_rdevmajor[8]; - char c_rdevminor[8]; - char c_namesize[8]; // including \0 - char c_check[8]; // checksum (usually 0) -} cpio_header; - -static fs_ops cpio_ops = { - .read = cpio_read, - .write = nullptr, - .open = nullptr, - .close = nullptr, -}; - -u64 hex_to_u64(const char* s, i32 len) { - u64 res = 0; - for (i32 i = 0; i < len; i++) { - char c = s[i]; - res <<= 4; - if (c >= '0' && c <= '9') res += (c - '0'); - else if (c >= 'A' && c <= 'F') res += (c - 'A' + 10); - else if (c >= 'a' && c <= 'f') res += (c - 'a' + 10); - } - - return res; -} - -u64 cpio_read(fs_node* node, u64 offset, u64 size, u8* buff) { - if (offset > node->len) return 0; // EOF - if ((offset + size) > node->len) size = node->len - offset; - - memcpy(buff, (char*)node->impl_data + offset, size); - return size; -} - -fs_node* cpio_mount(void* base, u64 size) { - u8* ptr = (u8*)base; - u8* end = ptr + size; - - fs_node* root = malloc(sizeof(fs_node)); - if (!root) panic("CPIO: Failed to malloc for root node!"); - memset(root, 0, sizeof(fs_node)); - strcpy(root->name, "/"); - root->flags = FS_DIR; - root->ops = &cpio_ops; - - fs_node* tail = nullptr; - - while (ptr < end) { - cpio_header* header = (cpio_header*)ptr; - - if (strncmp(header->c_magic, "070701", 6) != 0) panic("CPIO: Bad magic! Corrupted initramfs"); - u64 namesize = hex_to_u64(header->c_namesize, 8); - u64 filesize = hex_to_u64(header->c_filesize, 8); - - char* filename = (char*)(ptr + sizeof(cpio_header)); - if (strcmp(filename, "TRAILER!!!") == 0) break; - - u64 header_and_name_len = sizeof(cpio_header) + namesize; - u64 offset_to_data = ALIGN4(header_and_name_len); - void* file_content = (void*)(ptr + offset_to_data); - - fs_node* new_node = malloc(sizeof(fs_node)); - if (!new_node) panic("CPIO: Failed to malloc for new node!"); - memset(new_node, 0, sizeof(fs_node)); - strncpy(new_node->name, filename, sizeof(new_node->name) - 1); - - new_node->len = filesize; - new_node->inode = hex_to_u64(header->c_ino, 8); - new_node->ops = &cpio_ops; - new_node->impl_data = file_content; - - u64 mode = hex_to_u64(header->c_mode, 8); - if ((mode & 0xF000) == 0x4000) new_node->flags = FS_DIR; - else new_node->flags = FS_FILE; - - if (root->ptr == nullptr) root->ptr = new_node; - else if (tail) tail->next = new_node; - - tail = new_node; - - kprintf("^bCPIO^!: Found file '^y%s^!' (size ^y%d^!) at ^y%x^!\n", filename, filesize, file_content); - - u64 data_len = ALIGN4(filesize); - ptr += offset_to_data + data_len; - } - - return root; -} \ No newline at end of file diff --git a/kernel/src/fs/vfs.c b/kernel/src/fs/vfs.c deleted file mode 100644 index 7cf08e9..0000000 --- a/kernel/src/fs/vfs.c +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#include -#include - -fs_node* fs_root = nullptr; - -void vfs_init(fs_node* root_node) { - fs_root = root_node; -} - -u64 vfs_read(fs_node* node, u64 offset, u64 size, u8* buff) { - if (!node) return 0; - if (!node->ops->read) return 0; - - return node->ops->read(node, offset, size, buff); -} - -fs_node* vfs_open(const char* path) { - if (!fs_root) return nullptr; - if (strcmp(path, "/") == 0) return fs_root; - - const char* search_name = path; - if (path[0] == '/') search_name++; - - fs_node* curr = fs_root->ptr; - while (curr != nullptr) { - if (strcmp(curr->name, search_name) == 0) { - if (curr->ops->open) curr->ops->open(curr); - return curr; - } - curr = curr->next; - } - - return nullptr; -} - -void vfs_close(fs_node* node) { - if (node && node->ops->close) node->ops->close(node); -} \ No newline at end of file diff --git a/kernel/src/kmain.c b/kernel/src/kmain.c index 9420878..14ee7cb 100644 --- a/kernel/src/kmain.c +++ b/kernel/src/kmain.c @@ -7,107 +7,110 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include -#include -#include -#include -#include -#include +#include +#include +#include -#include -#include -#include -#include +#include +#include + +#include +#include +#include +#include #include -#include -#include -#include +#include +#include +#include -#include -#include +#include +#include -#define FG_COLOR 0xffffff -#define BG_COLOR 0x111111 +enum { + kDefaultConsoleForegroundColor = 0xffffff, + kDefaultConsoleBackgroundColor = 0x111111, +}; -extern u64 _kernel_end; +extern UInt64 _kernel_end; extern void* stack_top; -static SG_Context sg_ctx; +static IOGraphicsContext sIOGraphicsContext; void kmain(Bootinfo* info) { - serial_init(); - serial_write("Kernel started\n"); + IOSerialInit(); + IOSerialWrite("Kernel started\n"); - console_init(&sg_ctx); + IOConsoleInit(&sIOGraphicsContext); - if (info->magic != BOOTINFO_MAGIC) panic("Corrupt bootinfo!"); + if (info->magic != BOOTINFO_MAGIC) OSPanic("Corrupt bootinfo!"); - cpuinfo_init((u64)&stack_top); - kprintf("Got CPUINFO\n"); - rng_init(); - kprintf("RNG initialized\n"); - gdt_init(); - kprintf("GDT initialized\n"); - idt_init(); - kprintf("IDT initialized\n"); - pic_remap(); - kprintf("PIC remapped\n"); - pmm_init(&info->mem); - kprintf("PMM initialized\n"); - vmm_init(info); - kprintf("VMM initialized\n"); - timer_init(1000); - kprintf("Timer initialized\n"); - heap_init(); - kprintf("Heap initialized\n"); - sched_init(); - kprintf("Scheduler initialized\n"); - sg_init(&sg_ctx); - kprintf("Shitgui initialized\n"); - syscall_init(); + OSCPUInitialize((UInt64)&stack_top); + IOConsoleLog("Got CPUINFO\n"); + RandInitialize(); + IOConsoleLog("Random initialized\n"); + HALGlobalDescriptorTableInitialize(); + IOConsoleLog("GDT initialized\n"); + HALInterruptsDescriptorTableInitialize(); + IOConsoleLog("IDT initialized\n"); + HALLegacyInterruptControllerRemap(); + IOConsoleLog("PIC remapped\n"); + VMPhysicalMemoryInitialize(&info->memoryMap); + IOConsoleLog("PMM initialized\n"); + VMVirtualMemoryInitialize(info); + IOConsoleLog("VMM initialized\n"); + IOTimerInitialize(1000); + IOConsoleLog("Timer initialized\n"); + VMHeapInitialize(); + IOConsoleLog("Heap initialized\n"); + OSSchedulerInitialize(); + IOConsoleLog("Scheduler initialized\n"); - info = (Bootinfo*)PHYS_TO_HHDM((u64)info); + OSServicesInitialize(); + IOConsoleLog("Syscalls initialized"); - fs_node* root = cpio_mount(PHYS_TO_HHDM(info->initramfs.addr), info->initramfs.size); - vfs_init(root); - kprintf("VFS initialized\n"); + info = (Bootinfo*)PHYS_TO_HHDM((UInt64)info); - u32 *fb = (u32*)info->framebuffer.base; - if (!fb) return kprintf("No framebuffer found!!"); + FSVNode* root = FSCPIOMount(PHYS_TO_HHDM(info->initramfs.address), info->initramfs.size); + FSVirtualFileSystemInitialize(root); + IOConsoleLog("VFS initialized\n"); - sg_ctx.fb = fb; - sg_ctx.height = info->framebuffer.height; - sg_ctx.width = info->framebuffer.width; - sg_ctx.pitch = info->framebuffer.pitch; + UInt32 *framebuffer = (UInt32*)info->framebuffer.base; + if (!framebuffer) return IOConsoleLog("No framebuffer found!!"); - console_clear(BG_COLOR); - console_set_color(FG_COLOR); - console_set_default_color(FG_COLOR); + sIOGraphicsContext.framebuffer = framebuffer; + sIOGraphicsContext.dimensions.height = info->framebuffer.height; + sIOGraphicsContext.dimensions.width = info->framebuffer.width; + sIOGraphicsContext.pixelsPerScanLine = info->framebuffer.pitch; - show_splash(&sg_ctx); + IOConsoleClear(kDefaultConsoleBackgroundColor); + IOConsoleSetForegroundColor(kDefaultConsoleForegroundColor); + IOConsoleSetDefaultForegroundColor(kDefaultConsoleForegroundColor); + + SplashShow(&sIOGraphicsContext); bool staying_in_ksh = false; - if (!info->initramfs.addr) { - kprintf("^rWARNING^!: Failed to load ^yinitramfs^!! Staying in kernel rescue shell!\n\n"); + if (!info->initramfs.address) { + IOConsoleLog("^rWARNING^!: Failed to load ^yinitramfs^!! Staying in kernel rescue shell!\n\n"); staying_in_ksh = true; } if (!staying_in_ksh) { - kprintf("Press any key to continue booting. \nPress ^yq^! to stay in ^gksh^!\n"); + IOConsoleLog("Press any key to continue booting. \nPress ^yq^! to stay in ^gksh^!\n"); char c = '\n'; - c = console_getc(); + c = IOConsoleGetCharacter(); if (c == 'q') staying_in_ksh = true; } - if (staying_in_ksh) sched_spawn(ksh, nullptr, false, 0); - else sched_spawn(init_task_entry, nullptr, false, 0); + if (staying_in_ksh) OSSchedulerSpawn(ksh, nullptr, false, 0); + else OSSchedulerSpawn(init_task_entry, nullptr, false, 0); __asm__ volatile("sti"); while (true) __asm__ volatile("hlt"); - panic("How in the name of God you got here?"); + OSPanic("How in the name of God you got here?"); } \ No newline at end of file diff --git a/kernel/src/lib/Rand.c b/kernel/src/lib/Rand.c new file mode 100644 index 0000000..9d7989b --- /dev/null +++ b/kernel/src/lib/Rand.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash + +#include "bootinfo.h" +#include +#include +#include + +static UInt64 sPseudorandState = 0; + +static inline UInt64 RDTSC() { + UInt32 lo, hi; + __asm__ volatile ("rdtsc" : "=a" (lo), "=d" (hi)); + + return ((UInt64)hi << 32) | lo; +} + +void RandInitialize() { + sPseudorandState = RDTSC(); + if (sPseudorandState == 0) sPseudorandState = BOOTINFO_MAGIC; // why not reuse "termOS"? +} + +static UInt64 RandXorshift() { + UInt64 x = sPseudorandState; + x ^= x << 13; + x ^= x >> 7; + x ^= x << 17; + return sPseudorandState = x; +} + +static bool RandHardware(UInt64 *value) { + UInt8 ok; + __asm__ volatile ("rdrand %0; setc %1" + : "=r" (*value), "=qm" (ok)); + return ok != 0; +} + +UInt64 Rand() { + UInt64 result; + if (OSCPUHasFeature(kCPUFeatureRDRAND)) { + if (RandHardware(&result)) return result; + } + + return RandXorshift(); +} \ No newline at end of file diff --git a/kernel/src/lib/Splash.c b/kernel/src/lib/Splash.c new file mode 100644 index 0000000..53371af --- /dev/null +++ b/kernel/src/lib/Splash.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 0xKarinyash +#include +#include + +#include + +void SplashShow(IOGraphicsContext* IOGraphicsContextPointer) { + IOGraphicsPoint logoPoint = {0, 10}; + IOGraphicsPoint startPoint = {75, 55}; // greeting + IOGraphicsPoint normalTextPoint = {0, 120}; // not nice to hardcode nums like that but we have what we have + + IOGraphicsDrawImage(IOGraphicsContextPointer, &logoPoint, &logoImage); + IOConsoleSetCursorPosition(&startPoint); + IOConsoleLog("Welcome to ^ptermOS^!!!!\n"); + + IOConsoleSetCursorPosition(&normalTextPoint); +} diff --git a/kernel/src/core/string.c b/kernel/src/lib/String.c similarity index 52% rename from kernel/src/core/string.c rename to kernel/src/lib/String.c index 2001d7a..b83060d 100644 --- a/kernel/src/core/string.c +++ b/kernel/src/lib/String.c @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2025 0xKarinyash -#include +#include -i32 strcmp(const char *s1, const char *s2) { +Int32 strcmp(const char *s1, const char *s2) { while (*s1 && (*s1 == *s2)) { s1++; s2++; @@ -11,7 +11,7 @@ i32 strcmp(const char *s1, const char *s2) { return *(const unsigned char*)s1 - *(const unsigned char*)s2; } -i32 strncmp(const char* s1, const char* s2, u64 n) { +Int32 strncmp(const char* s1, const char* s2, UInt64 n) { while (n > 0) { if (*s1 != *s2) return *(unsigned char*)s1 - *(unsigned char*)s2; if (*s1 == '\0') return 0; @@ -30,7 +30,7 @@ char* strcpy(char* dest, const char* src) { return saved; } -char* strncpy(char* dest, const char* src, u64 n) { +char* strncpy(char* dest, const char* src, UInt64 n) { char* saved = dest; while (*src && n > 0) { *dest++ = *src++; @@ -41,4 +41,31 @@ char* strncpy(char* dest, const char* src, u64 n) { n--; } return saved; +} + +void *memset(void *ptr, int value, Size num) { + UInt8 *p = (UInt8 *)ptr; + while (num--) { + *p++ = (UInt8)value; + } + return ptr; +} + +void* memcpy(void* dest, const void* src, UInt64 n) { + UInt8* d = (UInt8*)dest; + const UInt8* s = (const UInt8*)src; + + while (n >= 8) { + *(UInt64*)d = *(const UInt64*)s; + d += 8; + s += 8; + n -= 8; + } + + while (n > 0) { + *d++ = *s++; + n--; + } + + return dest; } \ No newline at end of file diff --git a/kernel/src/mm/heap.c b/kernel/src/mm/heap.c deleted file mode 100644 index 32f1c84..0000000 --- a/kernel/src/mm/heap.c +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include -#include -#include -#include -#include -#include - -#define HEAP_SIZE_PAGES 1024 - -extern u64* pml4_kernel; -static block_header* heap_list_head = nullptr; - -void combine_forward(block_header* curr) { - if (!curr->next || !curr->next->is_free) return; - curr->size += sizeof(block_header) + curr->next->size; - curr->next = curr->next->next; - if (curr->next) curr->next->prev = curr; // what the fuck -} - -void heap_init() { - u64 heap_start = KERNEL_HEAP_START; - - for (u64 i = 0; i < HEAP_SIZE_PAGES; i++) { - u64 phys = (u64)pmm_alloc_page(); - if (!phys) panic("OOM during heap init"); - - u64 virt = heap_start + (i * PAGE_SIZE); - vmm_map_page(pml4_kernel, phys, virt, PTE_PRESENT | PTE_RW); - } - - heap_list_head = (block_header*)heap_start; - heap_list_head->magic = HEADER_MAGIC; - heap_list_head->size = (HEAP_SIZE_PAGES * PAGE_SIZE) - sizeof(block_header); - heap_list_head->is_free = true; - heap_list_head->next = nullptr; - heap_list_head->prev = nullptr; -} - -void* malloc(u64 size) { - if (size == 0) return nullptr; - u64 aligned_size = (size + 15) & ~15; - - block_header* curr = heap_list_head; - while (curr) { - if (curr->is_free && curr->size >= aligned_size) { - if (curr->size > aligned_size + sizeof(block_header) + 16) { - block_header* new_block = (block_header*)((u64)curr + sizeof(block_header) + aligned_size); - new_block->size = curr->size - aligned_size - sizeof(block_header); - new_block->is_free = true; - new_block->next = curr->next; - new_block->prev = curr; - new_block->magic = HEADER_MAGIC; - - if (curr->next) curr->next->prev = new_block; - curr->next = new_block; - curr->size = aligned_size; - } - curr->is_free = false; - return (void*)((u64)curr + sizeof(block_header)); - } - curr = curr->next; - } - - return nullptr; -} - -void free(void* ptr) { - if (!ptr) return; - - block_header* curr = (block_header*)((u64)ptr - sizeof(block_header)); - if (curr->magic != HEADER_MAGIC) return; - - curr->is_free = true; - if (curr->next && curr->next->is_free) combine_forward(curr); - if (curr->prev && curr->prev->is_free) combine_forward(curr->prev); -} - -void* realloc(void* ptr, u64 new_size) { - if (!ptr) return malloc(new_size); - if (new_size == 0) { - free(ptr); - return nullptr; - } - - block_header* curr = (block_header*)((u64)ptr - sizeof(block_header)); - if (curr->size >= new_size) return ptr; - - if (curr->next && - curr->next->is_free && - (curr->size + sizeof(block_header) + curr->next->size) >= new_size) { // why ts so fucking unreadable - combine_forward(curr); - return ptr; - } - - void* new_ptr = malloc(new_size); - if (!new_ptr) return nullptr; - - memcpy(new_ptr, ptr, curr->size); - free(ptr); - - return new_ptr; -} \ No newline at end of file diff --git a/kernel/src/mm/memory.c b/kernel/src/mm/memory.c deleted file mode 100644 index 95f21ba..0000000 --- a/kernel/src/mm/memory.c +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include -#include - -void *memset(void *ptr, int value, usize num) { - u8 *p = (u8 *)ptr; - while (num--) { - *p++ = (u8)value; - } - return ptr; -} - -void* memcpy(void* dest, const void* src, u64 n) { - u8* d = (u8*)dest; - const u8* s = (const u8*)src; - - while (n >= 8) { - *(u64*)d = *(const u64*)s; - d += 8; - s += 8; - n -= 8; - } - - while (n > 0) { - *d++ = *s++; - n--; - } - - return dest; -} \ No newline at end of file diff --git a/kernel/src/mm/pmm.c b/kernel/src/mm/pmm.c deleted file mode 100644 index 144f9e1..0000000 --- a/kernel/src/mm/pmm.c +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash - -#include - -#include -#include -#include -#include - -#include "bootinfo.h" -#include "mm/vmm.h" - -extern u64 _kernel_start; -extern u64 _kernel_end; - -u8* bitmap = nullptr; -u64 bitmap_size_g = 0; -static u64 total_mem_size = 0; - -u64 pmm_get_total_mem() { - return total_mem_size; -} - -void pmm_init(BI_MemoryMap* mmap) { - u64 descriptors_count = mmap->map_size / mmap->descriptor_size; - u64 max_physical_address = 0; - - for (u64 i = 0; i < descriptors_count; i++) { - efi_memory_descriptor_k* descriptor = (efi_memory_descriptor_k*)((u8*)mmap->map + (i * mmap->descriptor_size)); - if (descriptor->type == EfiMemoryMappedIO || - descriptor->type == EfiMemoryMappedIOPortSpace || - descriptor->type == EfiUnusableMemory || - descriptor->type == EfiReservedMemoryType || - descriptor->type == EfiPalCode) continue; - - u64 nominee = descriptor->physical_start + descriptor->number_of_pages * PAGE_SIZE; - max_physical_address = MAX(nominee, max_physical_address); - } - total_mem_size = max_physical_address; - - u64 pages_count = max_physical_address / PAGE_SIZE; - u64 bitmap_size = (pages_count + 7) / 8; - efi_memory_descriptor_k* desc_to_save = nullptr; - - for (u64 i = 0; i < descriptors_count; i++) { - efi_memory_descriptor_k* descriptor = (efi_memory_descriptor_k*)((u8*)mmap->map + (i * mmap->descriptor_size)); - // scary - if ((descriptor->type == EfiConventionalMemory) && \ - ((descriptor->number_of_pages * PAGE_SIZE) >= bitmap_size) && \ - (descriptor->physical_start >= SAFE_SPACE_START_ADDR)) { - desc_to_save = descriptor; - break; - } - } - - if (desc_to_save == nullptr) { - panic("Not enough RAM for bitmap!"); - } - - bitmap = (u8*)desc_to_save->physical_start; - bitmap_size_g = bitmap_size; - - memset(bitmap, 0xFF, bitmap_size); - - for (u64 i = 0; i < descriptors_count; i++) { - efi_memory_descriptor_k* descriptor = (efi_memory_descriptor_k*)((u8*)mmap->map + (i * mmap->descriptor_size));// this shit will haunt my dreams - if (descriptor->type != EfiConventionalMemory) continue; - u64 start_addr = descriptor->physical_start; - u64 end_addr = start_addr + (descriptor->number_of_pages * PAGE_SIZE); - for (u64 j = start_addr; j < end_addr; j += PAGE_SIZE) BITMAP_UNSET(bitmap, j); - } - - u64 k_start = KERNEL_VIRT_TO_PHYS((u64)&_kernel_start); - u64 k_end = KERNEL_VIRT_TO_PHYS((u64)&_kernel_end); - - u64 bitmap_start = (u64)bitmap; - u64 bitmap_end = bitmap_start + bitmap_size_g; - - for (u64 i = 0; i < SAFE_SPACE_START_ADDR; i += PAGE_SIZE) BITMAP_SET(bitmap, i); // mem, that addr < 1MB is NOT safe to use on x86 - for (u64 i = k_start; i < k_end; i += PAGE_SIZE) BITMAP_SET(bitmap, i); - for (u64 i = bitmap_start; i < bitmap_end; i += PAGE_SIZE) BITMAP_SET(bitmap, i); -} - -void* pmm_alloc_page() { - for (u64 i = 0; i < bitmap_size_g; i++) { - if (bitmap[i] == 0xFF) continue; - for (u64 j = 0; j < 8; j++) { - u64 addr = (i * 8 + j) * PAGE_SIZE; - if ((bitmap[i] & (1 << j)) == 0) { - BITMAP_SET(bitmap, addr); - return (void*)addr; - } - } - } - return nullptr; -} - -void pmm_free_page(void* addr) { - BITMAP_UNSET(bitmap, (u64)addr); -} diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c deleted file mode 100644 index 9fbcdfb..0000000 --- a/kernel/src/mm/vmm.c +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 0xKarinyash -#include -#include -#include - -#include - -#include -#include - -#include -#include "bootinfo.h" - -#define USER_STACK_TOP 0x70000000 -#define USER_STACK_SIZE 0x4000 - -u64* pml4_kernel = nullptr; -u64 pml4_kernel_phys = 0; -static bool is_initialized = false; - -extern u64 _kernel_start; -extern u64 _kernel_end; -extern u8* bitmap; -extern u64 bitmap_size_g; -extern GDTDescriptor gdt[]; -extern IDTEntry idt[]; -extern u8 double_fault_stack[]; -extern u8 stack_guard; - -static u64* get_table_virt(u64 phys) { - if (is_initialized) return (u64*)PHYS_TO_HHDM(phys); - return (u64*)phys; -} - -u64* vmm_map_page(u64* pml4, u64 phys, u64 virt, u64 flags) { - u64 pt_idx = VMM_PT_INDEX(virt); - u64 pd_idx = VMM_PD_INDEX(virt); - u64 pdpt_idx = VMM_PDPT_INDEX(virt); - u64 pml4_idx = VMM_PML4_INDEX(virt); - - u64* pml4_virt = pml4; - if (is_initialized) pml4_virt = (u64*)PHYS_TO_HHDM((u64)pml4); - - u64 table_flags = PTE_PRESENT | PTE_RW | (flags & PTE_USER); - - if (!(pml4_virt[pml4_idx] & PTE_PRESENT)) { - u64* addr = pmm_alloc_page(); - if (!addr) return nullptr; - u64* addr_virt = get_table_virt((u64)addr); - memset(addr_virt, 0, PAGE_SIZE); - pml4_virt[pml4_idx] = (u64)addr | table_flags; - } else { - pml4_virt[pml4_idx] |= (flags & PTE_USER); - } - - u64* pdpt = (u64*)PTE_GET_ADDR(pml4_virt[pml4_idx]); - u64* pdpt_virt = get_table_virt((u64)pdpt); - - if (!(pdpt_virt[pdpt_idx] & PTE_PRESENT)) { - u64* addr = pmm_alloc_page(); - if (!addr) return nullptr; - u64* addr_virt = get_table_virt((u64)addr); - memset(addr_virt, 0, PAGE_SIZE); - pdpt_virt[pdpt_idx] = (u64)addr | table_flags; - } else { - pdpt_virt[pdpt_idx] |= (flags & PTE_USER); - } - - u64* pd = (u64*)PTE_GET_ADDR(pdpt_virt[pdpt_idx]); - u64* pd_virt = get_table_virt((u64)pd); - - if (!(pd_virt[pd_idx] & PTE_PRESENT)) { - u64* addr = pmm_alloc_page(); - if (!addr) return nullptr; - u64* addr_virt = get_table_virt((u64)addr); - memset(addr_virt, 0, PAGE_SIZE); - pd_virt[pd_idx] = (u64)addr | table_flags; - } else { - pd_virt[pd_idx] |= (flags & PTE_USER); - } - - u64* pt = (u64*)PTE_GET_ADDR(pd_virt[pd_idx]); - u64* pt_virt = get_table_virt((u64)pt); - pt_virt[pt_idx] = phys | flags; - - __asm__ volatile("invlpg (%0)" :: "r" (virt) : "memory"); - - return (u64*)virt; -} - -void vmm_unmap_page(u64* pml4, u64 virt) { - u64 pt_idx = VMM_PT_INDEX(virt); - u64 pd_idx = VMM_PD_INDEX(virt); - u64 pdpt_idx = VMM_PDPT_INDEX(virt); - u64 pml4_idx = VMM_PML4_INDEX(virt); - - u64* pml4_virt = pml4; - if (is_initialized) pml4_virt = (u64*)PHYS_TO_HHDM((u64)pml4); - - if (!(pml4_virt[pml4_idx] & PTE_PRESENT)) return; - u64* pdpt_virt = get_table_virt(PTE_GET_ADDR(pml4_virt[pml4_idx])); - - if (!(pdpt_virt[pdpt_idx] & PTE_PRESENT)) return; - u64* pd_virt = get_table_virt(PTE_GET_ADDR(pdpt_virt[pdpt_idx])); - - if (!(pd_virt[pd_idx] & PTE_PRESENT)) return; - u64* pt_virt = get_table_virt(PTE_GET_ADDR(pd_virt[pd_idx])); - - pt_virt[pt_idx] = 0; - - __asm__ volatile("invlpg (%0)" :: "r" (virt) : "memory"); -} - -void load_cr3(u64 pml4_addr) { - __asm__ volatile ("mov %0, %%cr3" :: "r"(pml4_addr) : "memory"); -} - -void vmm_init(Bootinfo* info) { - pml4_kernel_phys = (u64)pmm_alloc_page(); - pml4_kernel = (u64*)pml4_kernel_phys; - memset(pml4_kernel, 0, PAGE_SIZE); - - u64 k_virt_start = (u64)&_kernel_start; - u64 k_virt_end = (u64)&_kernel_end; - - u64 fb_start = (u64)info->framebuffer.base; - u64 fb_end = fb_start + info->framebuffer.base_size; - u64 fb_size = fb_end - fb_start; - - u64 max_mem = pmm_get_total_mem(); - for (u64 i = 0; i < max_mem; i += PAGE_SIZE) vmm_map_page(pml4_kernel, i, PHYS_TO_HHDM(i), PTE_PRESENT | PTE_RW); - for (u64 i = k_virt_start; i < k_virt_end; i += PAGE_SIZE) vmm_map_page(pml4_kernel, KERNEL_VIRT_TO_PHYS(i), i, PTE_PRESENT | PTE_RW); - for (u64 i = 0; i < fb_size; i += PAGE_SIZE) vmm_map_page(pml4_kernel, fb_start + i, FB_VIRT_BASE + i, PTE_PRESENT | PTE_RW); - vmm_unmap_page(pml4_kernel, (u64)&stack_guard); - - bitmap = (u8*)PHYS_TO_HHDM((u64)bitmap); - info->framebuffer.base = (u32*)FB_VIRT_BASE; - load_cr3(pml4_kernel_phys); - is_initialized = true; -} - -u64 vmm_create_address_space() { - u64 phys = (u64)pmm_alloc_page(); - if (!phys) return 0; - - u64* virt = (u64*)PHYS_TO_HHDM(phys); - memset(virt, 0, PAGE_SIZE); - - u64* kernel_pml4_virt = get_table_virt((u64)pml4_kernel); - - for (u32 i = 256; i < 512; i++) { - virt[i] = kernel_pml4_virt[i]; - } - - return phys; -} - -u64 vmm_get_current_cr3() { - u64 cr3; - __asm__ volatile("mov %%cr3, %0" : "=r"(cr3)); - return cr3; -} - - -void vmm_setup_user_stack(u64* pml4_phys) { - u64 stack_bottom = USER_STACK_TOP - USER_STACK_SIZE; - for (u64 addr = stack_bottom; addr < USER_STACK_TOP; addr += 4096) { - void* phys = pmm_alloc_page(); - if (!phys) panic("OOM in user stack setup"); - memset((void*)PHYS_TO_HHDM((u64)phys), 0, 4096); - vmm_map_page((u64*)pml4_phys, (u64)phys, addr, PTE_PRESENT | PTE_RW | PTE_USER); - } -} diff --git a/kernel/src/shell/builtins.c b/kernel/src/shell/builtins.c index 1a95957..b93bcef 100644 --- a/kernel/src/shell/builtins.c +++ b/kernel/src/shell/builtins.c @@ -1,28 +1,26 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2025 0xKarinyash - #include -#include +#include -#include -#include +#include +#include -#include -#include -#include -#include +#include +#include -#include -#include +#include + +#include +#include #include -#include "../data/cats.h" +#include -extern task* curr_task; -const char* ascii_logo[] = { +const char* asciiLogo[] = { " /\\___/\\ ", " | > < | ", " | w | ", @@ -33,96 +31,76 @@ const char* ascii_logo[] = { " |_______| " }; -void cmd_kfetch() { - u64 uptime_s = get_uptime() / 1000; +void KSHCommandKernelFetch() { + UInt64 uptimeSeconds = IOTimerGetTicks() / 1000; - kprintf("\n\n"); - kprintf("^p %s ^!\t\t^g kernel^!@^gtermos\n^0", ascii_logo[0]); - kprintf("^p %s ^!\t\t^!-------------\n^!", ascii_logo[1]); - kprintf("^p %s ^!\t\t^gOS^!: termOS %s\n^!", ascii_logo[2], TERMOS_VERSION); - kprintf("^p %s ^!\t\t^gKernel^!: Dewar (x86_64), build: %s %s\n^!", ascii_logo[3], __DATE__, __TIME__); - kprintf("^p %s ^!\t\t^gUptime^!: %d seconds\n^!", ascii_logo[4], uptime_s); - kprintf("^p %s ^!\t\t^gShell^!: ksh\n^!", ascii_logo[5]); - kprintf("^p %s ^!\t\t^gDE^!: shitgui\n^!", ascii_logo[6]); - kprintf("^p %s ^!\t\t^gCPU^!: %s (^yFamily^!: %d; ^yModel^!: %d)\n^!", ascii_logo[7], g_cpu.vendor, g_cpu.family, g_cpu.model); - kprintf("\n\n"); + IOConsoleLog("\n\n"); + IOConsoleLog("^p %s ^!\t\t^g kernel^!@^gtermos\n^0", asciiLogo[0]); + IOConsoleLog("^p %s ^!\t\t^!-------------\n^!", asciiLogo[1]); + IOConsoleLog("^p %s ^!\t\t^gOS^!: termOS %s\n^!", asciiLogo[2], TERMOS_VERSION); + IOConsoleLog("^p %s ^!\t\t^gKernel^!: Dewar (x86_64), build: %s %s\n^!", asciiLogo[3], __DATE__, __TIME__); + IOConsoleLog("^p %s ^!\t\t^gUptime^!: %d seconds\n^!", asciiLogo[4], uptimeSeconds); + IOConsoleLog("^p %s ^!\t\t^gShell^!: ksh\n^!", asciiLogo[5]); + IOConsoleLog("^p %s ^!\t\t^gDE^!: shitgui\n^!", asciiLogo[6]); + IOConsoleLog("^p %s ^!\t\t^gCPU^!: %s (^yFamily^!: %d; ^yModel^!: %d)\n^!", asciiLogo[7], gOSBootCPU.vendorID, gOSBootCPU.family, gOSBootCPU.model); + IOConsoleLog("\n\n"); } -void cmd_meow() { - u64 cats_count = sizeof(cats) / sizeof(cats[0]); - u8 rand_num = krand() % cats_count; - kprintf("Nyaaa!!\n\n%s\n\n", cats[rand_num]); +void KSHCommandMeow() { + UInt64 catsCount = sizeof(cats) / sizeof(cats[0]); + UInt8 randomNumber = Rand() % catsCount; + IOConsoleLog("Nyaaa!!\n\n%s\n\n", cats[randomNumber]); } -void cmd_help() { - kprintf("Welcome to ^ptermOS^!'s ^gk^!ernel ^gsh^!ell!\n"); - kprintf("It loads when userspace is failed to load and acts as a basic rescue environment\n"); - kprintf("Available commands:\n"); +void KSHCommandHelp() { + IOConsoleLog("Welcome to ^ptermOS^!'s ^gk^!ernel ^gsh^!ell!\n"); + IOConsoleLog("It loads when userspace is failed to load and acts as a basic rescue environment\n"); + IOConsoleLog("Available commands:\n"); - kprintf("\t^rDebug^!:\n"); - kprintf("\t\t^ysleep^! \t\tSleep for 3seconds\n"); - kprintf("\t\t^ydbg^! \t\tTest new stuff\n"); - kprintf("\t\t^yregs^! \t\tPrint current regs\n"); - kprintf("\t\t^ypanic^! \t\tPanics (lol)\n"); - kprintf("\t\t^yud2^! \t\tPanics with #UD\n"); - kprintf("\t\t^ypf^! \t\tPanics with #PF\n"); - kprintf("\t\t^yuserspace^! \t\tAttempt to jump in ring 3\n"); - - kprintf("\t^pFun^!:\n"); - kprintf("\t\t^ysplash^! \t\tShows splash (works kinda unstable)\n"); - kprintf("\t\t^ymeow^! \t\tcats!!!\n"); - kprintf("\t\t^ykfetch^! \t\tr/unixporn compatible\n"); - - kprintf("\t^gCustomisation^!:\n"); - kprintf("\t\t^yblinking^! \t\tDisable/Enable cursor blinking\n"); + IOConsoleLog("\t^rDebug^!:\n"); + IOConsoleLog("\t\t^ysleep^! \t\tSleep for 3seconds\n"); + IOConsoleLog("\t\t^ydbg^! \t\tTest new stuff\n"); + IOConsoleLog("\t\t^yregs^! \t\tPrint current regs\n"); + IOConsoleLog("\t\t^ypanic^! \t\tPanics (lol)\n"); + IOConsoleLog("\t\t^yud2^! \t\tPanics with #UD\n"); + IOConsoleLog("\t\t^ypf^! \t\tPanics with #PF\n"); - kprintf("\t^bMisc^!:\n"); - kprintf("\t\t^yclear^! \t\tClear console\n"); - kprintf("\t\t^yhelp^! \t\tShow this menu\n"); - kprintf("\t\t^yrand^! \t\tGet a random number\n"); - kprintf("\t\t^yver^! \t\tDisplays termOS's version\n"); + IOConsoleLog("\t^pFun^!:\n"); + IOConsoleLog("\t\t^ysplash^! \t\tShows splash (works kinda unstable)\n"); + IOConsoleLog("\t\t^ymeow^! \t\tcats!!!\n"); + IOConsoleLog("\t\t^ykfetch^! \t\tr/unixporn compatible\n"); + + IOConsoleLog("\t^bMisc^!:\n"); + IOConsoleLog("\t\t^yclear^! \t\tClear console\n"); + IOConsoleLog("\t\t^yhelp^! \t\tShow this menu\n"); + IOConsoleLog("\t\t^yrand^! \t\tGet a random number\n"); + IOConsoleLog("\t\t^yver^! \t\tDisplays termOS's version\n"); } -void cmd_regs() { +void KSHCommandRegisters() { __asm__ volatile ("int3"); +} + +void KSHCommandSleep() { + OSSchedulerYield(3000); } -void print_regs(Registers *regs) { - kprintf("--------------------------------\n"); - kprintf("\t\t^gREGISTERS^!\n"); - kprintf("--------------------------------\n"); - kprintf("^gRAX^!=%X, ^gRBX^!=%X\n", regs->rax, regs->rbx); - kprintf("^gRCX^!=%X, ^gRDX^!=%X\n", regs->rcx, regs->rdx); - kprintf("^gRSI^!=%X, ^gRDI^!=%X\n", regs->rsi, regs->rdi); - kprintf("^gRBP^!=%X, ^gR8^! =%X\n", regs->rbp, regs->r8); - kprintf("^gR9^! =%X, ^gR10^!=%X \n", regs->r9, regs->r10); - kprintf("^gR11^!=%X, ^gR12^!=%X\n", regs->r11, regs->r12); - kprintf("^gR13^!=%X, ^gR14^!=%X\n", regs->r13, regs->r14); - kprintf("^gR15^!=%X\n",regs->r15); - kprintf("--------------------------------\n"); +void KSHCommandRand() { + IOConsoleLog("Your rand number (0..100) is ... ^y%d^!!\n", Rand() % 100); } - -void cmd_sleep() { - sleep(3000); -} - -void cmd_rand() { - kprintf("Your rand number (0..100) is ... ^y%d^!!\n", krand() % 100); -} - -void cmd_debug() { - u64 status = debug(); - kprintf("\nDebug ended with code %d\n", status); +void KSHCommandDebug() { + UInt64 status = KSHDebug(); + IOConsoleLog("\nDebug ended with code %d\n", status); return; } -void cmd_ver() { - kprintf("termOS version %s\n", TERMOS_VERSION); - kprintf("Dewar Kernel (x86_64), build: %s %s\n", __DATE__, __TIME__); - kprintf("License: GPL-3.0-or-later\n"); +void KSHCommandVer() { + IOConsoleLog("termOS version %s\n", TERMOS_VERSION); + IOConsoleLog("Dewar Kernel (x86_64), build: %s %s\n", __DATE__, __TIME__); + IOConsoleLog("License: GPL-3.0-or-later\n"); } void cmd_userspace() { - kprintf("Command disabled due to be really broken\n"); + IOConsoleLog("Command disabled due to be really broken\n"); } \ No newline at end of file diff --git a/kernel/src/shell/dbgcmd.c b/kernel/src/shell/dbgcmd.c index 6fec36f..952155f 100644 --- a/kernel/src/shell/dbgcmd.c +++ b/kernel/src/shell/dbgcmd.c @@ -2,8 +2,8 @@ // Copyright (c) 2026 0xKarinyash #include -#include +#include -u64 debug() { +UInt64 KSHDebug() { return 0; } \ No newline at end of file diff --git a/kernel/src/shell/ksh.c b/kernel/src/shell/ksh.c index 0ac5b06..d936e1c 100644 --- a/kernel/src/shell/ksh.c +++ b/kernel/src/shell/ksh.c @@ -4,14 +4,15 @@ #include #include -#include -#include +#include +#include -#include -#include -#include -#include -#include +#include +#include + +#include +#include +#include typedef enum { TOKEN_EMPTY, @@ -33,28 +34,22 @@ typedef enum { TOKEN_PANIC, TOKEN_PANIC_UD2, TOKEN_PANIC_PF, - TOKEN_USERSPACE, TOKEN_CLEAR, - TOKEN_BLINKING, TOKEN_RAND, TOKEN_VER, TOKEN_BACK, TOKEN_FORWARD, -} ksh_token; +} KSHToken; typedef struct { char* str; - ksh_token token; -} ksh_command_map; + KSHToken token; +} KSHCommandMap; -static const ksh_command_map token_map[] = { - {"", TOKEN_EMPTY}, - - // customisation - {"blinking", TOKEN_BLINKING}, - +static const KSHCommandMap CommandMap[] = { + {"", TOKEN_EMPTY}, // debug {"sleep", TOKEN_SLEEP}, {"dbg", TOKEN_DEBUG}, @@ -62,7 +57,6 @@ static const ksh_command_map token_map[] = { {"panic", TOKEN_PANIC}, {"ud2", TOKEN_PANIC_UD2}, {"pf", TOKEN_PANIC_PF}, - {"userspace", TOKEN_USERSPACE}, // fun {"meow", TOKEN_MEOW}, @@ -78,41 +72,38 @@ static const ksh_command_map token_map[] = { {nullptr, TOKEN_NULL} }; -ksh_token char2token(char* token) { - for (i32 i = 0; token_map[i].str != nullptr; i++) { - if (strcmp(token, token_map[i].str) == 0) return token_map[i].token; +KSHToken char2token(char* token) { + for (Int32 i = 0; CommandMap[i].str != nullptr; i++) { + if (strcmp(token, CommandMap[i].str) == 0) return CommandMap[i].token; } return TOKEN_ILLEGAL; } void ksh() { - sched_spawn(cursor_blinker_sched_task, nullptr, false, 0); while (true) { - kprintf("ksh_> "); + IOConsoleLog("ksh_> "); char cmdbuff[256]; - kgets(cmdbuff, 256); + IOConsoleReadLine(cmdbuff, 256); switch(char2token(cmdbuff)) { case TOKEN_EMPTY: continue; - case TOKEN_CLEAR: console_clear((u32) console_get_colors() & 0xFFFFFFFF); break; - case TOKEN_BLINKING: console_toggle_cursor_blink(); break; - case TOKEN_RAND: cmd_rand(); break; - case TOKEN_VER: cmd_ver(); break; + case TOKEN_CLEAR: IOConsoleClear((UInt32) IOConsoleGetColors() & 0xFFFFFFFF); break; + case TOKEN_RAND: KSHCommandRand(); break; + case TOKEN_VER: KSHCommandVer(); break; - case TOKEN_SLEEP: cmd_sleep(); break; - case TOKEN_DEBUG: cmd_debug(); break; - case TOKEN_REGS: cmd_regs(); break; - case TOKEN_PANIC: panic("Manually initiated panic"); + case TOKEN_SLEEP: KSHCommandSleep(); break; + case TOKEN_DEBUG: KSHCommandDebug(); break; + case TOKEN_REGS: KSHCommandRegisters(); break; + case TOKEN_PANIC: OSPanic("Manually initiated panic"); case TOKEN_PANIC_UD2: __asm__ volatile ("ud2"); - case TOKEN_PANIC_PF: u64* bad_ptr = (u64*)0xDEADBEEF; *bad_ptr = 666; - case TOKEN_USERSPACE: cmd_userspace(); break; + case TOKEN_PANIC_PF: UInt64* bad_ptr = (UInt64*)0xDEADBEEF; *bad_ptr = 666; - case TOKEN_SPLASH: show_splash(console_get_context()); break; - case TOKEN_KFETCH: cmd_kfetch(); break; - case TOKEN_MEOW: cmd_meow(); break; + case TOKEN_SPLASH: SplashShow(IOConsoleGetGraphicsContext()); break; + case TOKEN_KFETCH: KSHCommandKernelFetch(); break; + case TOKEN_MEOW: KSHCommandMeow(); break; - case TOKEN_HELP: cmd_help(); break; - default: kprintf("Unknown command!!\n"); break; + case TOKEN_HELP: KSHCommandHelp(); break; + default: IOConsoleLog("Unknown command!!\n"); break; } } } \ No newline at end of file diff --git a/kernel/src/syscalls/io.c b/kernel/src/syscalls/io.c deleted file mode 100644 index cf04278..0000000 --- a/kernel/src/syscalls/io.c +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#include -#include - -u64 sys_write(u64 fd, u64 buff, u64 len) { - if (fd == 1 || fd == 2) { - char* str = (char*)buff; - for (u64 i = 0; i < len; i++) { - console_putc(str[i]); - } - return len; - } - return 0; -} - -u64 sys_read(u64 fd, u64 buff, u64 count) { - char* buf = (char*)buff; - if (fd == 0) { - for (u64 i = 0; i < count; i++) { - buf[i] = console_getc(); - } - return count; - } - return 0; -} \ No newline at end of file diff --git a/kernel/src/syscalls/mem.c b/kernel/src/syscalls/mem.c deleted file mode 100644 index 86b9d92..0000000 --- a/kernel/src/syscalls/mem.c +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#include - -#include - -#include -#include -#include - -extern task* curr_task; - -u64 sys_mem(u64 size) { - if (size == 0) return 0; - process* proc = curr_task->proc; - u64 addr_to_ret = proc->heap_cur; - - u64 pages_needed = (size + (PAGE_SIZE-1)) / PAGE_SIZE; - - for (u64 i = 0; i < pages_needed; i++) { - void* phys = pmm_alloc_page(); - if (!phys) return 0; - - vmm_map_page((u64*)proc->pml4_phys, (u64)phys, proc->heap_cur, PTE_PRESENT | PTE_RW | PTE_USER); - memset((void*)PHYS_TO_HHDM((u64)phys), 0, PAGE_SIZE); - - proc->heap_cur += 4096; - } - - return addr_to_ret; -} diff --git a/kernel/src/syscalls/proc.c b/kernel/src/syscalls/proc.c deleted file mode 100644 index c0c5e18..0000000 --- a/kernel/src/syscalls/proc.c +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#include -#include -#include -#include -#include - -extern task* curr_task; - -i32 sys_exit(i32 code) { - kprintf("\n[Dewar] process %s exited with code %d\n", curr_task->proc->name, code); - sched_exit(); - return code; -} - - -i32 sys_spawn(const char* path) { - return process_spawn(path, path); -} - -i32 sys_wait(u64 pid) { - sched_block(pid); - return pid; -} diff --git a/userspace/debug/src/main.c b/userspace/debug/src/main.c index db5df75..bc3e366 100644 --- a/userspace/debug/src/main.c +++ b/userspace/debug/src/main.c @@ -7,9 +7,9 @@ #define VECTOR_BUFFER_SIZE 8 typedef struct { - i32* data; - u64 size; - u64 capacity; + Int32* data; + UInt64 size; + UInt64 capacity; } Vector; void vector_init(Vector* vec) { @@ -18,11 +18,11 @@ void vector_init(Vector* vec) { vec->capacity = 0; } -u8 vector_append(Vector* vec, const i32 num) { +UInt8 vector_append(Vector* vec, const Int32 num) { if (vec->size >= vec->capacity) { - u64 new_cap = (vec->capacity == 0) ? VECTOR_BUFFER_SIZE : vec->capacity * 2; + UInt64 new_cap = (vec->capacity == 0) ? VECTOR_BUFFER_SIZE : vec->capacity * 2; - i32* new_data = realloc(vec->data, new_cap * sizeof(i32)); + Int32* new_data = realloc(vec->data, new_cap * sizeof(Int32)); if (!new_data) return 2; // Out of memory vec->data = new_data; @@ -38,9 +38,9 @@ void vector_reset(Vector* vec) { vec->size = 0; } -u8 vector_reserve(Vector* vec, u64 new_cap) { +UInt8 vector_reserve(Vector* vec, UInt64 new_cap) { if (new_cap <= vec->capacity) return 0; - i32* new_data = realloc(vec->data, new_cap * sizeof(i32)); + Int32* new_data = realloc(vec->data, new_cap * sizeof(Int32)); if (!new_data) return 2; vec->data = new_data; @@ -58,7 +58,7 @@ void vector_free(Vector* vec) { void render_list(Vector* numbers) { printf("\nNumbers [%d/%d]: [", numbers->size, numbers->capacity); if (numbers->size == 0) printf("]"); - for (u64 i = 0; i < numbers->size; i++) { + for (UInt64 i = 0; i < numbers->size; i++) { printf("%d", numbers->data[i]); if (i + 1 >= numbers->size) { printf("]"); @@ -74,7 +74,7 @@ int main() { printf("Heap test\n"); printf("press any key to add 1 number press 'q' to exit\n"); char c = 'd'; - u64 i = 0; + UInt64 i = 0; while (c != 'q') { render_list(&nums); vector_append(&nums, i); diff --git a/userspace/init/src/main.c b/userspace/init/src/main.c index 725f0b5..16ceb38 100644 --- a/userspace/init/src/main.c +++ b/userspace/init/src/main.c @@ -7,7 +7,7 @@ // TODO: read .cfg and spawn what stated there int main() { while (1) { - i32 pid = spawn("/bin/termosh"); + Int32 pid = spawn("/bin/termosh"); if (pid < 0) return pid; wait(pid); } diff --git a/userspace/libterm/inc/malloc.h b/userspace/libterm/inc/malloc.h index ac79909..6e1556c 100644 --- a/userspace/libterm/inc/malloc.h +++ b/userspace/libterm/inc/malloc.h @@ -7,13 +7,13 @@ #define HEADER_MAGIC 0x1CE1CE typedef struct block_header { - u64 magic; + UInt64 magic; struct block_header* next; struct block_header* prev; - u64 size; + UInt64 size; bool is_free; } block_header; -void* malloc(u64 size); +void* malloc(UInt64 size); void free(void* ptr); -void* realloc(void* ptr, u64 new_size); \ No newline at end of file +void* realloc(void* ptr, UInt64 new_size); \ No newline at end of file diff --git a/userspace/libterm/inc/process.h b/userspace/libterm/inc/process.h index 8f4e7d8..f66c7ed 100644 --- a/userspace/libterm/inc/process.h +++ b/userspace/libterm/inc/process.h @@ -4,5 +4,5 @@ #pragma once #include -i32 spawn(const char* path); -i32 wait(u64 pid); \ No newline at end of file +Int32 spawn(const char* path); +Int32 wait(UInt64 pid); \ No newline at end of file diff --git a/userspace/libterm/inc/stdio.h b/userspace/libterm/inc/stdio.h index b446dbf..9de61bc 100644 --- a/userspace/libterm/inc/stdio.h +++ b/userspace/libterm/inc/stdio.h @@ -5,7 +5,7 @@ #include int printf(const char *fmt, ...); -int snprintf(char* str, u64 size, const char* fmt, ...); +int snprintf(char* str, UInt64 size, const char* fmt, ...); int getchar(); char* gets(char* str); -char* gets_s(char* str, u64 size); \ No newline at end of file +char* gets_s(char* str, UInt64 size); \ No newline at end of file diff --git a/userspace/libterm/inc/string.h b/userspace/libterm/inc/string.h index ccfd26d..57094f0 100644 --- a/userspace/libterm/inc/string.h +++ b/userspace/libterm/inc/string.h @@ -5,12 +5,12 @@ #include void *memset(void *ptr, int value, usize num); -void* memcpy(void* dest, const void* src, u64 n); -i32 strcmp(const char *s1, const char *s2); -i32 strncmp(const char* s1, const char* s2, u64 n); +void* memcpy(void* dest, const void* src, UInt64 n); +Int32 strcmp(const char *s1, const char *s2); +Int32 strncmp(const char* s1, const char* s2, UInt64 n); char* strcpy(char* dest, const char* src); -char* strncpy(char* dest, const char* src, u64 n); -u64 strlen(const char* str); -u64 strspn(const char* s, const char* accept); +char* strncpy(char* dest, const char* src, UInt64 n); +UInt64 strlen(const char* str); +UInt64 strspn(const char* s, const char* accept); char* strpbrk(const char* s, const char* accept); char* strtok(char *s, const char* delim); \ No newline at end of file diff --git a/userspace/libterm/inc/types.h b/userspace/libterm/inc/types.h index 422ef65..daa8029 100644 --- a/userspace/libterm/inc/types.h +++ b/userspace/libterm/inc/types.h @@ -3,21 +3,21 @@ #pragma once -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef unsigned long long u64; +typedef unsigned char UInt8; +typedef unsigned short UInt16; +typedef unsigned int UInt32; +typedef unsigned long long UInt64; -typedef signed char i8; -typedef signed short i16; -typedef signed int i32; -typedef signed long long i64; +typedef signed char Int8; +typedef signed short Int16; +typedef signed int Int32; +typedef signed long long Int64; -typedef u64 usize; -typedef u64 uintptr_t; +typedef UInt64 usize; +typedef UInt64 uintptr_t; #ifndef __cplusplus #define bool _Bool #define true 1 #define false 0 -#endif +#endif \ No newline at end of file diff --git a/userspace/libterm/src/malloc.c b/userspace/libterm/src/malloc.c index 546421d..c7b6ca4 100644 --- a/userspace/libterm/src/malloc.c +++ b/userspace/libterm/src/malloc.c @@ -6,7 +6,7 @@ #include static block_header* heap_list_head = nullptr; -extern u64 sys_mem(u64 size); +extern UInt64 sys_mem(UInt64 size); void combine_forward(block_header* curr) { if (!curr->next || !curr->next->is_free) return; @@ -15,16 +15,16 @@ void combine_forward(block_header* curr) { if (curr->next) curr->next->prev = curr; // what the fuck } -void* malloc(u64 size) { +void* malloc(UInt64 size) { if (size == 0) return nullptr; - u64 aligned_size = (size + 15) & ~15; + UInt64 aligned_size = (size + 15) & ~15; block_header* curr = heap_list_head; block_header* last = nullptr; while (curr) { if (curr->is_free && curr->size >= aligned_size) { if (curr->size > aligned_size + sizeof(block_header) + 16) { - block_header* new_block = (block_header*)((u64)curr + sizeof(block_header) + aligned_size); + block_header* new_block = (block_header*)((UInt64)curr + sizeof(block_header) + aligned_size); new_block->size = curr->size - aligned_size - sizeof(block_header); new_block->is_free = true; new_block->next = curr->next; @@ -36,17 +36,17 @@ void* malloc(u64 size) { curr->size = aligned_size; } curr->is_free = false; - return (void*)((u64)curr + sizeof(block_header)); + return (void*)((UInt64)curr + sizeof(block_header)); } last = curr; curr = curr->next; } - u64 need_to_alloc = aligned_size + sizeof(block_header); + UInt64 need_to_alloc = aligned_size + sizeof(block_header); - u64 page_aligned_size = (need_to_alloc + 4095) & ~4095; + UInt64 page_aligned_size = (need_to_alloc + 4095) & ~4095; - u64 new_mem_addr = sys_mem(page_aligned_size); + UInt64 new_mem_addr = sys_mem(page_aligned_size); if (new_mem_addr == 0) return nullptr; block_header* new_block = (block_header*)new_mem_addr; @@ -68,7 +68,7 @@ void* malloc(u64 size) { void free(void* ptr) { if (!ptr) return; - block_header* curr = (block_header*)((u64)ptr - sizeof(block_header)); + block_header* curr = (block_header*)((UInt64)ptr - sizeof(block_header)); if (curr->magic != HEADER_MAGIC) return; curr->is_free = true; @@ -76,14 +76,14 @@ void free(void* ptr) { if (curr->prev && curr->prev->is_free) combine_forward(curr->prev); } -void* realloc(void* ptr, u64 new_size) { +void* realloc(void* ptr, UInt64 new_size) { if (!ptr) return malloc(new_size); if (new_size == 0) { free(ptr); return nullptr; } - block_header* curr = (block_header*)((u64)ptr - sizeof(block_header)); + block_header* curr = (block_header*)((UInt64)ptr - sizeof(block_header)); if (curr->size >= new_size) return ptr; if (curr->next && diff --git a/userspace/libterm/src/process.c b/userspace/libterm/src/process.c index 99d06fa..e44b58d 100644 --- a/userspace/libterm/src/process.c +++ b/userspace/libterm/src/process.c @@ -3,13 +3,13 @@ #include -extern i32 sys_spawn(const char* path); -extern i32 sys_wait(u64 pid); +extern Int32 sys_spawn(const char* path); +extern Int32 sys_wait(UInt64 pid); -i32 spawn(const char* path) { +Int32 spawn(const char* path) { return sys_spawn(path); } -i32 wait(u64 pid) { +Int32 wait(UInt64 pid) { return sys_wait(pid); } \ No newline at end of file diff --git a/userspace/libterm/src/stdio.c b/userspace/libterm/src/stdio.c index 2e215e2..12715e5 100644 --- a/userspace/libterm/src/stdio.c +++ b/userspace/libterm/src/stdio.c @@ -9,23 +9,23 @@ #define EOF (-1) #define PRINTF_BUFFER_SIZE 1024 -extern u64 sys_read(u64 fd, void* buf, u64 len); -extern u64 sys_write(u64 fd, const void* buf, u64 len); +extern UInt64 sys_read(UInt64 fd, void* buf, UInt64 len); +extern UInt64 sys_write(UInt64 fd, const void* buf, UInt64 len); static void putchar(char c) { sys_write(1, &c, 1); } -static inline void buf_add(char* str, u64 size, u64* written, char c) { +static inline void buf_add(char* str, UInt64 size, UInt64* written, char c) { if (*written < size - 1 && size > 0) { str[*written] = c; } (*written)++; } -int vsnprintf(char* str, u64 size, const char* fmt, va_list args) { - u64 written = 0; - for (u32 i = 0; fmt[i] != '\0'; i++) { +int vsnprintf(char* str, UInt64 size, const char* fmt, va_list args) { + UInt64 written = 0; + for (UInt32 i = 0; fmt[i] != '\0'; i++) { if (fmt[i] == '%') { i++; if (fmt[i] == '\0') break; @@ -42,14 +42,14 @@ int vsnprintf(char* str, u64 size, const char* fmt, va_list args) { break; } case 'd': { - i64 n = va_arg(args, int); + Int64 n = va_arg(args, int); if (n < 0) { buf_add(str, size, &written, '-'); n = -n; } - u64 u = (u64)n; + UInt64 u = (UInt64)n; char tmp[32]; - i32 pos = 0; + Int32 pos = 0; if (u == 0) tmp[pos++] = '0'; while (u > 0) { tmp[pos++] = (u % 10) + '0'; @@ -61,8 +61,8 @@ int vsnprintf(char* str, u64 size, const char* fmt, va_list args) { } case 'x': case 'X': { - u64 u = va_arg(args, unsigned long long); - u8 padding = (fmt[i] == 'X') ? 16 : 0; + UInt64 u = va_arg(args, unsigned long long); + UInt8 padding = (fmt[i] == 'X') ? 16 : 0; char tmp[32]; int pos = 0; @@ -117,7 +117,7 @@ int printf(const char *fmt, ...) { int len = vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - u64 write_len = ((u64)len < sizeof(buf)) ? len : (sizeof(buf) - 1); + UInt64 write_len = ((UInt64)len < sizeof(buf)) ? len : (sizeof(buf) - 1); sys_write(1, buf, write_len); return (int)write_len; @@ -155,10 +155,10 @@ char* gets(char* str) { return str; } -char* gets_s(char* str, u64 size) { +char* gets_s(char* str, UInt64 size) { if (size == 0) return str; - u64 i = 0; + UInt64 i = 0; int c; while (i < size - 1) { diff --git a/userspace/libterm/src/string.c b/userspace/libterm/src/string.c index 2594541..0865f67 100644 --- a/userspace/libterm/src/string.c +++ b/userspace/libterm/src/string.c @@ -6,19 +6,19 @@ static char* olds; void *memset(void *ptr, int value, usize num) { - u8 *p = (u8 *)ptr; + UInt8 *p = (UInt8 *)ptr; while (num--) { - *p++ = (u8)value; + *p++ = (UInt8)value; } return ptr; } -void* memcpy(void* dest, const void* src, u64 n) { - u8* d = (u8*)dest; - const u8* s = (const u8*)src; +void* memcpy(void* dest, const void* src, UInt64 n) { + UInt8* d = (UInt8*)dest; + const UInt8* s = (const UInt8*)src; while (n >= 8) { - *(u64*)d = *(const u64*)s; + *(UInt64*)d = *(const UInt64*)s; d += 8; s += 8; n -= 8; @@ -32,7 +32,7 @@ void* memcpy(void* dest, const void* src, u64 n) { return dest; } -i32 strcmp(const char *s1, const char *s2) { +Int32 strcmp(const char *s1, const char *s2) { while (*s1 && (*s1 == *s2)) { s1++; s2++; @@ -40,7 +40,7 @@ i32 strcmp(const char *s1, const char *s2) { return *(const unsigned char*)s1 - *(const unsigned char*)s2; } -i32 strncmp(const char* s1, const char* s2, u64 n) { +Int32 strncmp(const char* s1, const char* s2, UInt64 n) { while (n > 0) { if (*s1 != *s2) return *(unsigned char*)s1 - *(unsigned char*)s2; if (*s1 == '\0') return 0; @@ -59,7 +59,7 @@ char* strcpy(char* dest, const char* src) { return saved; } -char* strncpy(char* dest, const char* src, u64 n) { +char* strncpy(char* dest, const char* src, UInt64 n) { char* saved = dest; while (*src && n > 0) { *dest++ = *src++; @@ -72,8 +72,8 @@ char* strncpy(char* dest, const char* src, u64 n) { return saved; } -u64 strlen(const char* str) { - u64 res = 0; +UInt64 strlen(const char* str) { + UInt64 res = 0; for (res = 0; str[res]; res++); return res; } @@ -86,8 +86,8 @@ static inline int is_in_set(char c, const char* set) { return 0; } -u64 strspn(const char* s, const char* accept) { - u64 count = 0; +UInt64 strspn(const char* s, const char* accept) { + UInt64 count = 0; while (*s && is_in_set(*s, accept)) { count++; s++; diff --git a/userspace/termosh/src/handlers/spawn.c b/userspace/termosh/src/handlers/spawn.c index d7797b7..beaf302 100644 --- a/userspace/termosh/src/handlers/spawn.c +++ b/userspace/termosh/src/handlers/spawn.c @@ -4,7 +4,7 @@ #include void cmd_spawn(const char* path) { - i32 pid = spawn(path); + Int32 pid = spawn(path); if (pid < 0) { switch (pid) { case -1: printf("\"%s\" not found.\n", path); break;