full refactor in kernel/: now its apple-styled; im so fucking tired

This commit is contained in:
Karina
2026-01-31 01:40:10 +04:00
parent e323e91dac
commit 1ea9ba1a9f
123 changed files with 2822 additions and 2774 deletions
+8 -8
View File
@@ -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) {
+20 -20
View File
@@ -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
+19 -19
View File
@@ -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;
+9 -7
View File
@@ -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
@@ -1,8 +1,8 @@
// font8x16 bitmap font
// Source: https://github.com/hubenchang0515/font8x16
// License: MIT
#pragma once
#include <types.h>
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,
@@ -3,12 +3,12 @@
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <drivers/shitgui.h>
#include <IO/IOGraphics.h>
#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
};
+9
View File
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
#include <FS/VFS.h>
UInt64 FSCPIORead(FSVNode* node, UInt64 offset, UInt64 size, UInt8* buffer);
FSVNode* FSCPIOMount(void* baseAddress, UInt64 totalSize);
+42
View File
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
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);
+36
View File
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <IO/IOGraphics.h>
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, ...);
+50
View File
@@ -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 <types.h>
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
);
+19
View File
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
enum {
kIOKeyboardBufferSize = 256,
};
typedef struct {
char buffer[kIOKeyboardBufferSize];
UInt16 head;
UInt16 tail;
} IOKeyboardBuffer;
extern IOKeyboardBuffer gIOKeyboardInputBuffer;
void IOKeyboardInterruptsHandler();
+8
View File
@@ -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);
+9
View File
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
void IOTimerInitialize(UInt32 freq);
UInt64 IOTimerInterruptsHandler(CPURegisters *regs);
UInt64 IOTimerGetTicks();
@@ -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);
@@ -3,6 +3,6 @@
#pragma once
#include <types.h>
#include <core/scheduler.h>
#include <OS/OSScheduler.h>
u64 load_hot(process* proc, u8* data);
UInt64 HOTLoad(OSProcess* process, UInt8* data);
@@ -5,5 +5,5 @@
#include <types.h>
i32 process_spawn(const char* path, const char* name);
Int32 OSLoaderProcessSpawn(const char* executablePath, const char* processName);
void init_task_entry();
+8
View File
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
__attribute__((noreturn)) void OSPanicException(CPURegisters* frame);
__attribute__((noreturn)) void OSPanic(const char* msg);
+44
View File
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
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;
+8
View File
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
UInt64 OSServiceWrite(UInt64 fileDescriptor, UInt64 buffer, UInt64 length);
UInt64 OSServiceRead(UInt64 fileDescriptor, UInt64 buffer, UInt64 count);
@@ -4,4 +4,4 @@
#pragma once
#include <types.h>
u64 sys_mem(u64 size);
UInt64 OSServiceMemoryGet(UInt64 size);
+10
View File
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
Int32 OSServiceProcessExit(Int32 code);
Int32 OSServiceProcessSpawn(const char* path);
Int32 OSServiceProcessWait(UInt64 pid);
+28
View File
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
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);
+49
View File
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include "bootinfo.h"
#include <types.h>
#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);
+6 -6
View File
@@ -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);
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);
+45
View File
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
#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();
+22
View File
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
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();
+44
View File
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
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();
}
+42
View File
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
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);
@@ -3,4 +3,4 @@
#pragma once
#include <types.h>
u16 pic_remap();
UInt16 HALLegacyInterruptControllerRemap();
-40
View File
@@ -1,40 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
#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);
-42
View File
@@ -1,42 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
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();
-22
View File
@@ -1,22 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
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();
-39
View File
@@ -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();
}
+13 -9
View File
@@ -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();
void OSServicesInitialize();
-10
View File
@@ -1,10 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
__attribute__((noreturn)) void panic_exception(Registers *regs);
__attribute__((noreturn)) void panic(const char* msg);
extern const char* exception_messages[];
-42
View File
@@ -1,42 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
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
-10
View File
@@ -1,10 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
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);
-22
View File
@@ -1,22 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <drivers/shitgui.h>
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();
-4
View File
@@ -1,4 +0,0 @@
#pragma once
#include <types.h>
extern u8 font8x16[128][16];
-16
View File
@@ -1,16 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
#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();
-8
View File
@@ -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);
-33
View File
@@ -1,33 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
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);
-10
View File
@@ -1,10 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
void timer_init(u32 freq);
u64 timer_handler(Registers *regs);
void sleep(u64 ms);
u64 get_uptime();
-8
View File
@@ -1,8 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
#include <fs/vfs.h>
u64 cpio_read(fs_node* node, u64 offset, u64 size, u8* buff);
fs_node* cpio_mount(void* base, u64 size);
-38
View File
@@ -1,38 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
#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);
@@ -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;
}
@@ -4,5 +4,5 @@
#pragma once
#include <types.h>
void rng_init();
u64 krand();
void RandInitialize();
UInt64 Rand();
@@ -2,7 +2,7 @@
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <drivers/shitgui.h>
#include <IO/IOGraphics.h>
void show_splash(SG_Context *sg_ctx);
void SplashShow(IOGraphicsContext* IOGraphicsContextPointer);
+12
View File
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
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);
-8
View File
@@ -1,8 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <types.h>
void* memset(void* ptr, int value, usize num);
void* memcpy(void* dest, const void* src, u64 n);
-22
View File
@@ -1,22 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#pragma once
#include "bootinfo.h"
#include <types.h>
#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);
+8 -10
View File
@@ -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();
void KSHCommandKernelFetch();
void KSHCommandMeow();
void KSHCommandHelp();
void KSHCommandRegisters();
void KSHCommandSleep();
void KSHCommandDebug();
void KSHCommandRand();
void KSHCommandVer();
+1 -1
View File
@@ -4,4 +4,4 @@
#pragma once
#include <types.h>
u64 debug();
UInt64 KSHDebug();
-1
View File
@@ -2,6 +2,5 @@
// Copyright (c) 2025 0xKarinyash
#pragma once
#include <drivers/shitgui.h>
void ksh();
-8
View File
@@ -1,8 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
u64 sys_write(u64 fd, u64 buff, u64 len);
u64 sys_read(u64 fd, u64 buff, u64 count);
-10
View File
@@ -1,10 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
i32 sys_exit(i32 code);
i32 sys_spawn(const char* path);
i32 sys_wait(u64 pid);
+15 -46
View File
@@ -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
+122
View File
@@ -0,0 +1,122 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <types.h>
#include <FS/CPIO.h>
#include <FS/VFS.h>
#include <lib/String.h>
#include <OS/OSPanic.h>
#include <VM/Heap.h>
#include <IO/IOConsole.h>
#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;
}
+53
View File
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <FS/VFS.h>
#include <lib/String.h>
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);
}
}
+276
View File
@@ -0,0 +1,276 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <IO/IOConsole.h>
#include <IO/IOSerial.h>
#include <IO/IOGraphics.h>
#include <IO/IOKeyboard.h>
#include <lib/Math.h>
#include <OS/OSScheduler.h>
#include <types.h>
#include <stdarg.h>
#include <Data/VGAFont.h>
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++;
}
}
}
}
}
+82
View File
@@ -0,0 +1,82 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
// RIP shitgui -- you started it all
#include <OS/OSScheduler.h>
#include <OS/OSPanic.h>
#include <IO/IOGraphics.h>
#include <VM/Heap.h>
#include <lib/String.h>
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;
}
}
}
}
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <drivers/keyboard.h>
#include <drivers/console.h>
#include <IO/IOKeyboard.h>
#include <IO/IOConsole.h>
#include <io.h>
#include <IO.h>
#include <types.h>
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;
}
}
+33
View File
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <IO/IOSerial.h>
#include <IO.h>
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]);
}
+36
View File
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <IO/IOTimer.h>
#include <IO.h>
#include <types.h>
#include <OS/OSScheduler.h>
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;
}
+48
View File
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <OS/Exec/HOTLoader.h>
#include <OS/OSScheduler.h>
#include <lib/String.h>
#include <VM/PMM.h>
#include <VM/VMM.h>
#include <VM/Heap.h>
#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;
}
+78
View File
@@ -0,0 +1,78 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <OS/Exec/HOTLoader.h>
#include <OS/Exec/OSLoader.h>
#include <OS/OSPanic.h>
#include <OS/OSScheduler.h>
#include <lib/String.h>
#include <VM/PMM.h>
#include <VM/VMM.h>
#include <VM/Heap.h>
#include <FS/VFS.h>
#include <IO/IOConsole.h>
#include <types.h>
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"); }
}
+168
View File
@@ -0,0 +1,168 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <OS/OSPanic.h>
#include <lib/Rand.h>
#include <IO/IOGraphics.h>
#include <IO/IOConsole.h>
#include <types.h>
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();
}
+146
View File
@@ -0,0 +1,146 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <OS/OSPanic.h>
#include <OS/OSScheduler.h>
#include <lib/String.h>
#include <VM/Heap.h>
#include <VM/VMM.h>
#include <OSCPU.h>
#include <GDT.h>
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");
}
+27
View File
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <OS/Services/OSServiceIO.h>
#include <IO/IOConsole.h>
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;
}
+30
View File
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <OS/Services/OSServiceMemory.h>
#include <OS/OSScheduler.h>
#include <VM/PMM.h>
#include <VM/VMM.h>
#include <lib/String.h>
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;
}
+24
View File
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <OS/Services/OSServiceProcess.h>
#include <OS/OSScheduler.h>
#include <OS/OSPanic.h>
#include <OS/Exec/OSLoader.h>
#include <IO/IOConsole.h>
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;
}
+103
View File
@@ -0,0 +1,103 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <VM/Heap.h>
#include <VM/PMM.h>
#include <VM/VMM.h>
#include <lib/String.h>
#include <OS/OSPanic.h>
#include <types.h>
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;
}
+115
View File
@@ -0,0 +1,115 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <VM/PMM.h>
#include <VM/VMM.h>
#include <lib/String.h>
#include <lib/Math.h>
#include <OS/OSPanic.h>
#include <types.h>
#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);
}
+177
View File
@@ -0,0 +1,177 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <VM/VMM.h>
#include <VM/PMM.h>
#include <OS/OSPanic.h>
#include <GDT.h>
#include <IDT.h>
#include <lib/String.h>
#include <types.h>
#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);
}
}
+77
View File
@@ -0,0 +1,77 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
// just fucking kill me already
#include <GDT.h>
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));
}
+82
View File
@@ -0,0 +1,82 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <IDT.h>
#include <types.h>
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));
}
+72
View File
@@ -0,0 +1,72 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <types.h>
#include <OSCPU.h>
#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;
}
+34
View File
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <PIC.h>
#include <IO.h>
#include <types.h>
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;
}
-72
View File
@@ -1,72 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <types.h>
#include <cpuinfo.h>
#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;
}
-78
View File
@@ -1,78 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
// just fucking kill me already
#include <gdt.h>
#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));
}
-82
View File
@@ -1,82 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <idt.h>
#include <types.h>
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));
}
+34 -26
View File
@@ -1,41 +1,49 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <io.h>
#include <core/panic.h>
#include <core/scheduler.h>
#include <drivers/keyboard.h>
#include <drivers/console.h>
#include <drivers/timer.h>
#include <shell/builtins.h>
#include <syscalls/proc.h>
#include <IO.h>
#include <OS/OSPanic.h>
#include <OS/OSScheduler.h>
#include <IO/IOKeyboard.h>
#include <IO/IOConsole.h>
#include <IO/IOTimer.h>
#include <OS/Services/OSServiceProcess.h>
#include <types.h>
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;
}
-34
View File
@@ -1,34 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <pic.h>
#include <io.h>
#include <types.h>
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;
}
+33 -33
View File
@@ -1,66 +1,66 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <cpuinfo.h>
#include <OSCPU.h>
#include <syscall.h>
#include <types.h>
#include <drivers/console.h>
#include <mm/pmm.h>
#include <mm/vmm.h>
#include <IO/IOConsole.h>
#include <VM/PMM.h>
#include <VM/VMM.h>
#include <syscalls/proc.h>
#include <syscalls/mem.h>
#include <syscalls/io.h>
#include <OS/Services/OSServiceProcess.h>
#include <OS/Services/OSServiceMemory.h>
#include <OS/Services/OSServiceIO.h>
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;
}
}
-49
View File
@@ -1,49 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <core/hot.h>
#include <core/scheduler.h>
#include <core/string.h>
#include <mm/pmm.h>
#include <mm/vmm.h>
#include <mm/heap.h>
#include <mm/memory.h>
#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;
}
-67
View File
@@ -1,67 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <core/panic.h>
#include <core/hot.h>
#include <core/loader.h>
#include <core/scheduler.h>
#include <core/string.h>
#include <shell/ksh.h>
#include <mm/pmm.h>
#include <mm/vmm.h>
#include <mm/heap.h>
#include <mm/memory.h>
#include <fs/vfs.h>
#include <drivers/console.h>
#include <types.h>
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"); }
}
-168
View File
@@ -1,168 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <core/panic.h>
#include <core/rand.h>
#include <drivers/shitgui.h>
#include <drivers/console.h>
#include <types.h>
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();
}
-45
View File
@@ -1,45 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include "bootinfo.h"
#include <core/rand.h>
#include <cpuinfo.h>
#include <types.h>
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();
}
-147
View File
@@ -1,147 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <core/panic.h>
#include <core/scheduler.h>
#include <core/string.h>
#include <mm/heap.h>
#include <mm/vmm.h>
#include <mm/memory.h>
#include <cpuinfo.h>
#include <gdt.h>
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");
}
-16
View File
@@ -1,16 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <drivers/shitgui.h>
#include <drivers/console.h>
#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);
}
-305
View File
@@ -1,305 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include "core/scheduler.h"
#include <drivers/console.h>
#include <drivers/serial.h>
#include <drivers/font.h>
#include <drivers/shitgui.h>
#include <drivers/keyboard.h>
#include <core/math.h>
#include <types.h>
#include <stdarg.h>
#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;
}
-31
View File
@@ -1,31 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <drivers/serial.h>
#include <io.h>
#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]);
}
-85
View File
@@ -1,85 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <core/scheduler.h>
#include <core/panic.h>
#include <drivers/shitgui.h>
#include <mm/heap.h>
#include <mm/memory.h>
#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;
}
}
}
}
-40
View File
@@ -1,40 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <drivers/timer.h>
#include <io.h>
#include <types.h>
#include <core/scheduler.h>
#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;
}
-113
View File
@@ -1,113 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <types.h>
#include <fs/cpio.h>
#include <fs/vfs.h>
#include <core/string.h>
#include <core/panic.h>
#include <mm/memory.h>
#include <mm/heap.h>
#include <drivers/console.h>
#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;
}
-41
View File
@@ -1,41 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <fs/vfs.h>
#include <core/string.h>
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);
}
+73 -70
View File
@@ -7,107 +7,110 @@
#include <types.h>
#include <drivers/shitgui.h>
#include <drivers/serial.h>
#include <drivers/console.h>
#include <drivers/timer.h>
#include <IO/IOGraphics.h>
#include <IO/IOSerial.h>
#include <IO/IOConsole.h>
#include <IO/IOTimer.h>
#include <core/panic.h>
#include <core/scheduler.h>
#include <core/splash.h>
#include <core/rand.h>
#include <core/loader.h>
#include <OS/OSPanic.h>
#include <OS/OSScheduler.h>
#include <OS/Exec/OSLoader.h>
#include <gdt.h>
#include <idt.h>
#include <pic.h>
#include <cpuinfo.h>
#include <lib/Splash.h>
#include <lib/Rand.h>
#include <GDT.h>
#include <IDT.h>
#include <PIC.h>
#include <OSCPU.h>
#include <syscall.h>
#include <mm/pmm.h>
#include <mm/vmm.h>
#include <mm/heap.h>
#include <VM/PMM.h>
#include <VM/VMM.h>
#include <VM/Heap.h>
#include <fs/cpio.h>
#include <fs/vfs.h>
#include <FS/CPIO.h>
#include <FS/VFS.h>
#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?");
}
+45
View File
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include "bootinfo.h"
#include <lib/Rand.h>
#include <OSCPU.h>
#include <types.h>
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();
}
+18
View File
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <IO/IOGraphics.h>
#include <IO/IOConsole.h>
#include <Data/logo.h>
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);
}

Some files were not shown because too many files have changed in this diff Show More