├── .gitignore ├── .gitmodules ├── LICENSE.txt ├── Makefile ├── boron ├── Makefile ├── address_space.txt ├── include │ ├── _limine.h │ ├── arch.h │ ├── arch │ │ ├── amd64.h │ │ ├── amd64.inc │ │ ├── amd64 │ │ │ └── ipl.h │ │ └── ipl.h │ ├── ex.h │ ├── ex │ │ ├── handtab.h │ │ ├── internal.h │ │ ├── object.h │ │ ├── process.h │ │ └── rwlock.h │ ├── except.h │ ├── hal.h │ ├── hal │ │ ├── data.h │ │ ├── init.h │ │ ├── pci.h │ │ └── timer.h │ ├── io.h │ ├── io │ │ ├── cntrobj.h │ │ ├── devobj.h │ │ ├── dispatch.h │ │ ├── drvobj.h │ │ ├── fcb.h │ │ ├── fileobj.h │ │ ├── part.h │ │ └── rdwr.h │ ├── ke.h │ ├── ke │ │ ├── apc.h │ │ ├── atomics.h │ │ ├── crash.h │ │ ├── dbg.h │ │ ├── dispatch.h │ │ ├── dpc.h │ │ ├── event.h │ │ ├── int.h │ │ ├── ipl.h │ │ ├── irq.h │ │ ├── locks.h │ │ ├── mode.h │ │ ├── mutex.h │ │ ├── prcb.h │ │ ├── process.h │ │ ├── sched.h │ │ ├── semaphor.h │ │ ├── smp.h │ │ ├── stats.h │ │ ├── thread.h │ │ ├── timer.h │ │ ├── types.h │ │ ├── ver.h │ │ └── wait.h │ ├── ldr.h │ ├── limreq.h │ ├── main.h │ ├── mm.h │ ├── mm │ │ ├── addrnode.h │ │ ├── cache.h │ │ ├── heap.h │ │ ├── mdl.h │ │ ├── pfn.h │ │ ├── pmm.h │ │ ├── pool.h │ │ ├── probe.h │ │ ├── pt.h │ │ ├── section.h │ │ ├── services.h │ │ ├── vad.h │ │ └── view.h │ ├── ob.h │ ├── ps.h │ ├── ps │ │ ├── pebteb.h │ │ ├── process.h │ │ ├── services.h │ │ └── thread.h │ └── string.h ├── linker.ld ├── scripts │ └── generate_symbols.py ├── source │ ├── ex │ │ ├── event.c │ │ ├── exp.h │ │ ├── handtab.c │ │ ├── init.c │ │ ├── mutex.c │ │ ├── rwlock.c │ │ ├── servsup.c │ │ └── wait.c │ ├── hal │ │ ├── dbg.c │ │ └── hal.c │ ├── io │ │ ├── cntrller.c │ │ ├── device.c │ │ ├── driver.c │ │ ├── fcb.c │ │ ├── file.c │ │ ├── init.c │ │ ├── iop.h │ │ ├── parse.c │ │ ├── part.c │ │ ├── partobj.c │ │ └── rdwr.c │ ├── ke │ │ ├── amd64 │ │ │ ├── archi.h │ │ │ ├── cpu.c │ │ │ ├── debug.c │ │ │ ├── init.c │ │ │ ├── intlist.inc │ │ │ ├── intobj.c │ │ │ ├── misc.asm │ │ │ ├── pio.c │ │ │ ├── probe.c │ │ │ ├── syscall.asm │ │ │ ├── thredsup.c │ │ │ ├── tlbs.c │ │ │ ├── trap.asm │ │ │ ├── traplist.asm │ │ │ └── traps.c │ │ ├── apc.c │ │ ├── crash.c │ │ ├── dispatch.c │ │ ├── dpc.c │ │ ├── event.c │ │ ├── except.c │ │ ├── init.c │ │ ├── ipl.c │ │ ├── ki.h │ │ ├── limreq.c │ │ ├── lock.c │ │ ├── mode.c │ │ ├── mutex.c │ │ ├── process.c │ │ ├── sched.c │ │ ├── semaphor.c │ │ ├── smp.c │ │ ├── stats.c │ │ ├── stop.c │ │ ├── symbols.c │ │ ├── tests.c │ │ ├── thread.c │ │ └── timer.c │ ├── ldr │ │ ├── dll.c │ │ ├── initroot.c │ │ ├── ldri.h │ │ └── loader.c │ ├── mm │ │ ├── amd64 │ │ │ ├── pt.c │ │ │ └── ptfree.c │ │ ├── cache.c │ │ ├── commit.c │ │ ├── fault.c │ │ ├── heap.c │ │ ├── map.c │ │ ├── mdl.c │ │ ├── mi.h │ │ ├── pmm.c │ │ ├── pool.c │ │ ├── poolhdr.c │ │ ├── poolsup.c │ │ ├── reclaim.c │ │ ├── slab.c │ │ ├── svcs.c │ │ ├── teardown.c │ │ ├── vad.c │ │ ├── view.c │ │ └── vmm.c │ ├── ob │ │ ├── create.c │ │ ├── dir.c │ │ ├── handle.c │ │ ├── init.c │ │ ├── link.c │ │ ├── obp.h │ │ ├── ref.c │ │ └── type.c │ ├── ps │ │ ├── attach.c │ │ ├── init.c │ │ ├── initproc.c │ │ ├── process.c │ │ ├── psp.h │ │ ├── thread.c │ │ └── userthrd.c │ ├── rtl │ │ ├── assert.c │ │ ├── elf.c │ │ ├── print.c │ │ ├── rbtree.c │ │ ├── status.c │ │ └── string.c │ └── system_services.h └── structure.md ├── borondll ├── Makefile ├── include │ ├── boron.h │ ├── list.h │ ├── main.h │ └── svcs.h └── src │ ├── calls.asm │ ├── init.c │ ├── reloc.c │ └── rtl ├── common └── include │ ├── _stb_sprintf.h │ ├── elf.h │ ├── exs.h │ ├── handle.h │ ├── ios.h │ ├── kes.h │ ├── mms.h │ ├── obs.h │ ├── pss.h │ ├── rtl │ ├── ansi.h │ ├── assert.h │ ├── check64.h │ ├── elf.h │ ├── fbsdtree.h │ ├── list.h │ ├── rbtree.h │ └── symdefs.h │ ├── status.h │ └── string.h ├── drivers ├── CommonMakefile ├── ext2fs │ ├── Makefile │ ├── linker.ld │ └── source │ │ ├── ext2.h │ │ ├── main.c │ │ └── mount.c ├── halx86 │ ├── Makefile │ ├── linker.ld │ └── source │ │ ├── acpi.c │ │ ├── acpi.h │ │ ├── apic.c │ │ ├── apic.h │ │ ├── crash.c │ │ ├── font.h │ │ ├── hali.h │ │ ├── hpet.c │ │ ├── hpet.h │ │ ├── init.c │ │ ├── ioapic.c │ │ ├── ioapic.h │ │ ├── pci.c │ │ ├── pci.h │ │ ├── pio.c │ │ ├── pio.h │ │ ├── pit.c │ │ ├── pit.h │ │ ├── term.c │ │ ├── timer.c │ │ ├── tsc.c │ │ ├── tsc.h │ │ └── uart.h ├── i8042prt │ ├── Makefile │ ├── linker.ld │ └── source │ │ ├── i8042.c │ │ ├── i8042.h │ │ ├── kbd.c │ │ ├── kbd.h │ │ └── main.c ├── stornvme │ ├── Makefile │ ├── linker.ld │ └── source │ │ ├── commands.c │ │ ├── enum.c │ │ ├── main.c │ │ ├── nvme.h │ │ ├── queue.c │ │ └── rdwr.c └── test │ ├── Makefile │ ├── linker.ld │ ├── source │ ├── apctst.c │ ├── balltst.c │ ├── ccbtst.c │ ├── fworktst.c │ ├── hndtbtst.c │ ├── inttst.c │ ├── iotst.c │ ├── kbdtst.c │ ├── main.c │ ├── mdltst.c │ ├── mm1tst.c │ ├── mm2tst.c │ ├── mm3tst.c │ ├── mutextst.c │ ├── ob2tst.c │ ├── objectst.c │ ├── proctst.c │ ├── rwlcktst.c │ ├── sintab.h │ ├── stortst.c │ ├── tests.h │ └── utils.h │ └── test.txt ├── images ├── 2023-10-15 12-03-52.png ├── 2023-10-15 12-05-14.png ├── 2023-10-24 22-40-20.png ├── 2023-10-25 21-15-25.png ├── 2023-10-28 19-41-04.png ├── 2024-06-23 12-06-27.png └── 2024-06-23 12-07-01.png ├── limine.cfg ├── readme.md ├── run-unix.sh ├── run.bat ├── run.sh └── styleguide.md /.gitignore: -------------------------------------------------------------------------------- 1 | build/* 2 | boron/build/* 3 | 4 | drivers/*/build/* 5 | drivers/*.sys 6 | 7 | borondll/build/* 8 | 9 | user/*/build/* 10 | user/*.exe 11 | user/*.dll 12 | 13 | .keep/* 14 | keep/* 15 | limine/* 16 | 17 | vdiske2.vdi 18 | vdiske2.vmdk 19 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "limine"] 2 | path = limine 3 | url = https://github.com/limine-bootloader/limine.git 4 | branch = v7.x-binary 5 | [submodule "source/ha/flanterm"] 6 | path = drivers/halx86/source/flanterm 7 | url = https://github.com/mintsuki/flanterm.git 8 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2023-2025 iProgramInCpp 2 | 3 | Redistribution and use in source and binary forms, with or 4 | without modification, are permitted provided that the 5 | following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above 8 | copyright notice, this list of conditions and the following 9 | disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials 14 | provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of 17 | its contributors may be used to endorse or promote products 18 | derived from this software without specific prior written 19 | permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 22 | CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, 23 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 26 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 32 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /boron/address_space.txt: -------------------------------------------------------------------------------- 1 | BORON Operating System Address Space (AMD64) 2 | 3 | ** Kernel Mode ** 4 | 5 | +------------------------------+ - 0xFFFFFFFFFFFFFFFF 6 | | kernel code & data | 7 | +------------------------------+ - 0xFFFFFFFF80000000 8 | | | 9 | +------------------------------+ - 0xFFFFF08000000000 10 | | system module DLLs | 11 | +------------------------------+ - 0xFFFFF00000000000 12 | | | 13 | | | 14 | | unused | 15 | | | 16 | | | 17 | +------------------------------+ - 0xFFFFA20000000000 18 | | file system caching | 19 | +------------------------------+ - 0xFFFFA18000000000 20 | | virtually linear page tables | 21 | +------------------------------+ - 0xFFFFA10000000000 22 | | dynamic pool space | 23 | +------------------------------+ - 0xFFFFA08000000000 24 | | page frame data base | 25 | +------------------------------+ - 0xFFFFA00000000000 26 | | higher half direct map | 27 | +------------------------------+ - 0xFFFF800000000000 28 | 29 | NOTE: file system caching will be implemented in the future 30 | 31 | ** User Mode ** 32 | 33 | Currently this is nothing more than a plan. 34 | Now, a user process has complete control over its own 35 | address space. (They will even be able to unmap the 36 | PEB/TEBs if they want as well!) 37 | 38 | However, this is the plan for normal user processes. 39 | 40 | +-----------------------------+ - 0x0000800000000000 41 | | process environment block | 42 | +-----------------------------+ - 0x00007ffffffff000 43 | | operating system DLLs | 44 | +-----------------------------+ - 0x00007fff00000000 45 | | thread environment blocks | 46 | +-----------------------------+ - 0x00007ffe00000000 47 | | thread stacks | 48 | +-----------------------------+ - 0x00007e0000000000 49 | | user mappings | 50 | +-----------------------------+ - 0x0000500000000000 51 | | user heap | 52 | +-----------------------------+ - 0x0000200000000000 53 | | user DLLs | 54 | +-----------------------------+ - 0x0000100000000000 55 | | program executable | 56 | +-----------------------------+ - 0x0000000000001000 57 | | | 58 | +-----------------------------+ - 0x0000000000000000 59 | -------------------------------------------------------------------------------- /boron/include/arch.h: -------------------------------------------------------------------------------- 1 | #ifndef NS64_ARCH_H 2 | #define NS64_ARCH_H 3 | 4 | #include 5 | 6 | // ==== Platform specific defintions ==== 7 | #ifdef TARGET_AMD64 8 | #include 9 | #endif 10 | 11 | // ==== Forward declarations. Depending on the platform, we'll include platform specific definitions. ==== 12 | typedef struct KREGISTERS_tag KREGISTERS, *PKREGISTERS; // List of registers. 13 | 14 | // Functions that do different things based on architecture, 15 | // but exist everywhere 16 | #ifdef TARGET_AMD64 17 | 18 | FORCE_INLINE 19 | void KeWaitForNextInterrupt(void) 20 | { 21 | ASM("hlt":::"memory"); 22 | } 23 | 24 | FORCE_INLINE 25 | void KeSpinningHint(void) 26 | { 27 | ASM("pause":::"memory"); 28 | } 29 | 30 | FORCE_INLINE 31 | void KeInvalidatePage(void* Address) 32 | { 33 | ASM("invlpg (%0)"::"r"((uintptr_t)Address):"memory"); 34 | } 35 | 36 | #else 37 | 38 | void KeWaitForNextInterrupt(void); 39 | void KeSpinningHint(void); 40 | void KeInvalidatePage(void* Page); 41 | 42 | #endif 43 | 44 | void KeSetCPUPointer(void* CpuPointer); 45 | void* KeGetCPUPointer(void); 46 | uintptr_t KeGetCurrentPageTable(void); 47 | void KeSetCurrentPageTable(uintptr_t PageTable); 48 | bool KeDisableInterrupts(); // returns old state 49 | void KeRestoreInterrupts(bool OldState); 50 | 51 | // CPU initialization function 52 | void KeInitCPU(); // initializes the current CPU 53 | 54 | // ==== Interrupt priority level ==== 55 | void KeOnUpdateIPL(KIPL newIPL, KIPL oldIPL); 56 | 57 | void KeIssueTLBShootDown(uintptr_t Address, size_t Length); 58 | 59 | // Architecture specific data 60 | KARCH_DATA* KeGetData(); 61 | 62 | // ==== Execution Control ==== 63 | //Don't use - reimplement if you need to: NO_RETURN void KeJumpContext(PKREGISTERS Registers); 64 | 65 | #endif//NS64_ARCH_H 66 | -------------------------------------------------------------------------------- /boron/include/arch/amd64.inc: -------------------------------------------------------------------------------- 1 | ; Boron64 - Include file for platform specific assembly stuff 2 | %ifndef NS64_AMD64_INC 3 | %define NS64_AMD64_INC 4 | bits 64 5 | 6 | %define SEG_NULL 0x00 7 | %define SEG_RING_0_CODE 0x08 8 | %define SEG_RING_0_DATA 0x10 9 | %define SEG_RING_3_DATA 0x18 10 | %define SEG_RING_3_CODE 0x20 11 | 12 | ; Clears all registers except RAX, RDI, and RBP 13 | %macro CLEAR_REGS 0 14 | xor rbx, rbx 15 | xor rcx, rcx 16 | xor rdx, rdx 17 | xor rsi, rsi 18 | xor r8, r8 19 | xor r9, r9 20 | xor r10, r10 21 | xor r11, r11 22 | xor r12, r12 23 | xor r13, r13 24 | xor r14, r14 25 | xor r15, r15 26 | %endmacro 27 | 28 | ; magic IPL to avoid popping registers we don't need to pop, since 29 | ; this interrupt frame was pushed by KeYieldCurrentThread in kernel mode 30 | %define MAGIC_IPL 0x42424242 31 | 32 | %endif ;NS64_AMD64_INC 33 | -------------------------------------------------------------------------------- /boron/include/arch/amd64/ipl.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | arch/amd64/ipl.h 7 | 8 | Abstract: 9 | This header file contains the constant IPL definitions 10 | for the AMD64 platform. 11 | 12 | Author: 13 | iProgramInCpp - 8 October 2023 14 | ***/ 15 | #ifndef BORON_ARCH_IPL_AMD64_H 16 | #define BORON_ARCH_IPL_AMD64_H 17 | 18 | typedef enum KIPL_tag 19 | { 20 | IPL_UNDEFINED = -1, 21 | IPL_NORMAL = 0x0, // business as usual 22 | IPL_APC = 0x3, // asynch procedure calls. Page faults only allowed up to this IPL 23 | IPL_DPC = 0x4, // deferred procedure calls and the scheduler 24 | IPL_DEVICES0 = 0x5, // tier 1 for devices (keyboard, mouse) 25 | IPL_DEVICES1 = 0x6, // tier 2 for devices 26 | IPL_DEVICES2 = 0x7, 27 | IPL_DEVICES3 = 0x8, 28 | IPL_DEVICES4 = 0x9, 29 | IPL_DEVICES5 = 0xA, 30 | IPL_DEVICES6 = 0xB, 31 | IPL_DEVICES7 = 0xC, 32 | IPL_DEVICES8 = 0xD, 33 | IPL_CLOCK = 0xE, // for clock timers 34 | IPL_NOINTS = 0xF, // total control of the CPU. Interrupts are disabled in this IPL and this IPL only. 35 | IPL_COUNT, 36 | } 37 | KIPL, *PKIPL; 38 | 39 | #endif//BORON_ARCH_IPL_AMD64_H 40 | -------------------------------------------------------------------------------- /boron/include/arch/ipl.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | arch/amd64/ipl.h 7 | 8 | Abstract: 9 | This header file contains includes for the IPL 10 | enum definition for each platform. 11 | 12 | Author: 13 | iProgramInCpp - 8 October 2023 14 | ***/ 15 | #ifndef BORON_ARCH_IPL_H 16 | #define BORON_ARCH_IPL_H 17 | 18 | #ifdef TARGET_AMD64 19 | #include 20 | #else 21 | #error Hello 22 | #endif 23 | 24 | #endif//BORON_ARCH_IPL_H 25 | -------------------------------------------------------------------------------- /boron/include/ex.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ex.h 7 | 8 | Abstract: 9 | This header file defines prototypes for routines from the 10 | extended runtime library. The extended runtime library 11 | contains routines that depend on the kernel, unlike Rtl 12 | which is entirely freestanding. 13 | 14 | Author: 15 | iProgramInCpp - 27 September 2023 16 | ***/ 17 | #ifndef BORON_EX_H 18 | #define BORON_EX_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #endif//BORON_EX_H 28 | -------------------------------------------------------------------------------- /boron/include/ex/internal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | ex/internal.h 7 | 8 | Abstract: 9 | This header file defines executive internal calls. 10 | 11 | This must only be included by the kernel and will not expose 12 | anything if included from a driver. 13 | 14 | Author: 15 | iProgramInCpp - 3 September 2024 16 | ***/ 17 | #pragma once 18 | 19 | #ifdef KERNEL 20 | 21 | // Safely duplicate a string from user space. Use MmFreePool to free the space allocated by the string. 22 | BSTATUS ExiDuplicateUserString(char** OutNewString, const char* UserString, size_t StringLength); 23 | 24 | // Safely copy an OBJECT_ATTRIBUTES instance. 25 | BSTATUS ExiCopySafeObjectAttributes(POBJECT_ATTRIBUTES OutNewAttributes, POBJECT_ATTRIBUTES UserAttributes); 26 | 27 | // Dispose of a copied OBJECT_ATTRIBUTES instance. 28 | void ExiDisposeCopiedObjectAttributes(POBJECT_ATTRIBUTES Attributes); 29 | 30 | // Create an object based on a user system service call. This handles safety in all aspects, including 31 | // copying the object attributes to kernel pool, dereferencing the root directory, copying the handle into 32 | // the OutHandle pointer, etc. 33 | BSTATUS ExCreateObjectUserCall( 34 | PHANDLE OutHandle, 35 | POBJECT_ATTRIBUTES ObjectAttributes, 36 | POBJECT_TYPE ObjectType, 37 | size_t ObjectBodySize, 38 | EX_OBJECT_CREATE_METHOD CreateMethod, 39 | void* CreateContext, 40 | int PoolFlag, 41 | bool TrustHandlePointer 42 | ); 43 | 44 | // Opens an object from a user system service call. This ensures that code is not duplicated. 45 | BSTATUS ExOpenObjectUserCall( 46 | PHANDLE OutHandle, 47 | POBJECT_ATTRIBUTES ObjectAttributes, 48 | POBJECT_TYPE ObjectType 49 | ); 50 | 51 | #else 52 | #error Only the kernel may include this 53 | #endif 54 | -------------------------------------------------------------------------------- /boron/include/ex/object.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | ex/object.h 7 | 8 | Abstract: 9 | This header defines prototypes for executive dispatch 10 | object manipulation functions. 11 | 12 | Author: 13 | iProgramInCpp - 9 August 2024 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | #ifdef KERNEL 20 | 21 | // Does the same operation as ObReferenceObjectByHandle, except translates 22 | // special handle values to references to the actual object. 23 | // (e.g. CURRENT_PROCESS_HANDLE is translated to the current process) 24 | BSTATUS ExReferenceObjectByHandle(HANDLE Handle, POBJECT_TYPE ExpectedType, void** OutObject); 25 | 26 | typedef BSTATUS(*EX_OBJECT_CREATE_METHOD)(void* Object, void* Context); 27 | 28 | // Create an object based on a user system service call. This handles safety in all aspects, including 29 | // copying the object attributes to kernel pool, dereferencing the root directory, copying the handle into 30 | // the OutHandle pointer, etc. 31 | BSTATUS ExCreateObjectUserCall( 32 | PHANDLE OutHandle, 33 | POBJECT_ATTRIBUTES ObjectAttributes, 34 | POBJECT_TYPE ObjectType, 35 | size_t ObjectBodySize, 36 | EX_OBJECT_CREATE_METHOD CreateMethod, 37 | void* CreateContext, 38 | int PoolFlag, 39 | bool TrustHandlePointer 40 | ); 41 | 42 | // Opens an object from a user system service call. This ensures that code is not duplicated. 43 | BSTATUS ExOpenObjectUserCall( 44 | PHANDLE OutHandle, 45 | POBJECT_ATTRIBUTES ObjectAttributes, 46 | POBJECT_TYPE ObjectType 47 | ); 48 | 49 | #endif 50 | 51 | #define EX_DISPATCH_BOOST ((KPRIORITY) 1) 52 | 53 | BSTATUS OSClose(HANDLE Handle); 54 | 55 | BSTATUS OSCreateMutex(PHANDLE OutHandle, POBJECT_ATTRIBUTES ObjectAttributes); 56 | 57 | BSTATUS OSOpenMutex(PHANDLE OutHandle, POBJECT_ATTRIBUTES ObjectAttributes); 58 | 59 | BSTATUS OSReleaseMutex(HANDLE MutexHandle); 60 | 61 | BSTATUS OSQueryMutex(HANDLE MutexHandle, int* MutexState); 62 | 63 | BSTATUS OSCreateEvent(PHANDLE OutHandle, POBJECT_ATTRIBUTES ObjectAttributes, int EventType, bool State); 64 | 65 | BSTATUS OSOpenEvent(PHANDLE OutHandle, POBJECT_ATTRIBUTES ObjectAttributes); 66 | 67 | BSTATUS OSSetEvent(HANDLE EventHandle); 68 | 69 | BSTATUS OSResetEvent(HANDLE EventHandle); 70 | 71 | BSTATUS OSPulseEvent(HANDLE EventHandle); 72 | 73 | BSTATUS OSQueryEvent(HANDLE EventHandle, int* EventState); 74 | 75 | BSTATUS OSWaitForMultipleObjects( 76 | int ObjectCount, 77 | PHANDLE ObjectsArray, 78 | int WaitType, 79 | bool Alertable, 80 | int TimeoutMS 81 | ); 82 | 83 | BSTATUS OSWaitForSingleObject( 84 | HANDLE Handle, 85 | bool Alertable, 86 | int TimeoutMS 87 | ); -------------------------------------------------------------------------------- /boron/include/ex/process.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | ex/process.h 7 | 8 | Abstract: 9 | This header file defines the executive process structure. 10 | 11 | Author: 12 | iProgramInCpp - 8 January 2024 13 | ***/ 14 | #pragma once 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | typedef struct EPROCESS_tag EPROCESS, *PEPROCESS; 21 | 22 | struct EPROCESS_tag 23 | { 24 | // The kernel side process. 25 | KPROCESS Pcb; 26 | 27 | // The Virtual Address Descriptor list of this process. 28 | MMVAD_LIST VadList; 29 | 30 | // The heap manager for this process. 31 | MMHEAP Heap; 32 | 33 | // Rwlock that guards the address space of the process. 34 | // TODO: Perhaps this should be replaced by the VAD list lock? 35 | EX_RW_LOCK AddressLock; 36 | 37 | // Object handle table. This handle table manages objects opened by the process. 38 | void* HandleTable; 39 | }; 40 | 41 | #define PsGetCurrentProcess() ((PEPROCESS)KeGetCurrentProcess()) 42 | 43 | // Attaches to or detaches from a process, on behalf of the current thread. 44 | // 45 | // If NewProcess is NULL, then the current thread is detached from the 46 | // processes and the active address space will be the address space of 47 | // the host process. 48 | PEPROCESS PsSetAttachedProcess(PEPROCESS NewProcess); 49 | 50 | PEPROCESS PsGetAttachedProcess(); 51 | -------------------------------------------------------------------------------- /boron/include/ex/rwlock.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | ex/rwlock.h 7 | 8 | Abstract: 9 | This header file defines the rwlock struct and its 10 | action functions. 11 | 12 | Author: 13 | iProgramInCpp - 11 January 2024 14 | ***/ 15 | #pragma once 16 | #include 17 | 18 | typedef struct _EX_RW_LOCK_OWNER 19 | { 20 | int Locked; 21 | LIST_ENTRY Entry; 22 | PKTHREAD OwnerThread; 23 | } 24 | EX_RW_LOCK_OWNER, *PEX_RW_LOCK_OWNER; 25 | 26 | typedef struct _EX_RW_LOCK 27 | { 28 | // Lock that guards the structure. 29 | KSPIN_LOCK GuardLock; 30 | // An exclusive owner. 31 | EX_RW_LOCK_OWNER ExclusiveOwner; 32 | 33 | EX_RW_LOCK_OWNER SharedOwner; 34 | 35 | PEX_RW_LOCK_OWNER OwnerTable; 36 | 37 | KSEMAPHORE SharedSemaphore; 38 | 39 | KEVENT ExclusiveSyncEvent; 40 | 41 | int OwnerTableSize; 42 | 43 | int SharedOwnerCount; 44 | 45 | int SharedWaiterCount; 46 | 47 | int ExclusiveWaiterCount; 48 | 49 | int HeldCount; 50 | } 51 | EX_RW_LOCK, *PEX_RW_LOCK; 52 | 53 | // Initializes the RW-lock structure. 54 | void ExInitializeRwLock(PEX_RW_LOCK Lock); 55 | 56 | // De-initializes an RW-lock. 57 | void ExDeinitializeRwLock(PEX_RW_LOCK Lock); 58 | 59 | // Acquires an RW-lock in exclusive mode. 60 | BSTATUS ExAcquireExclusiveRwLock(PEX_RW_LOCK Lock, bool DontBlock, bool Alertable); 61 | 62 | // Acquires an RW-lock in shared mode. 63 | BSTATUS ExAcquireSharedRwLock(PEX_RW_LOCK Lock, bool DontBlock, bool Alertable, bool CanStarve); 64 | 65 | // Atomically demotes ownership of the current thread over 66 | // the lock from exclusive to shared. 67 | void ExDemoteToSharedRwLock(PEX_RW_LOCK Lock); 68 | 69 | // Releases an owned RW-lock. 70 | void ExReleaseRwLock(PEX_RW_LOCK Lock); 71 | -------------------------------------------------------------------------------- /boron/include/except.h: -------------------------------------------------------------------------------- 1 | // Boron64 - Exception handling 2 | #ifndef NS64_EXCEPT_H 3 | #define NS64_EXCEPT_H 4 | 5 | #include 6 | 7 | void KeOnUnknownInterrupt(PKREGISTERS); 8 | void KeOnDoubleFault(PKREGISTERS); 9 | void KeOnProtectionFault(PKREGISTERS); 10 | void KeOnPageFault(PKREGISTERS); 11 | 12 | #endif//NS64_EXCEPT_H 13 | -------------------------------------------------------------------------------- /boron/include/hal.h: -------------------------------------------------------------------------------- 1 | // Boron - Hardware abstraction for x86_64. 2 | // In the future this module is planned to be linked separately to the kernel. 3 | #ifndef NS64_HAL_H 4 | #define NS64_HAL_H 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define HAL_IPI_BROADCAST (1 << 0) 14 | #define HAL_IPI_SELF (1 << 1) 15 | 16 | bool HalWasInitted(); 17 | 18 | // HAL API. See hal/init.h 19 | void HalEndOfInterrupt(); 20 | void HalRequestIpi(uint32_t LapicId, uint32_t Flags, int Vector); 21 | void HalInitSystemUP(); 22 | void HalInitSystemMP(); 23 | void HalDisplayString(const char* Message); 24 | void HalCrashSystem(const char* Message); 25 | bool HalUseOneShotIntTimer(); 26 | void HalProcessorCrashed() NO_RETURN; 27 | uint64_t HalGetIntTimerFrequency(); 28 | uint64_t HalGetTickCount(); 29 | uint64_t HalGetTickFrequency(); 30 | uint64_t HalGetIntTimerDeltaTicks(); 31 | void HalIoApicSetIrqRedirect(uint8_t Vector, uint8_t Irq, uint32_t LapicId, bool Status); 32 | 33 | #ifdef IS_HAL 34 | void HalSetVftable(const HAL_VFTABLE* Table); 35 | #endif 36 | 37 | 38 | // Outdated and will be removed: 39 | 40 | 41 | // ==== Terminal ==== 42 | // Warning: Only run these on the BSP 43 | void HalInitTerminal(void); 44 | bool HalIsTerminalInitted(); 45 | 46 | // Warning: You need to lock KiPrintLock to use this: 47 | void HalPrintString(const char* str); 48 | 49 | // Warning: You need to lock KiDebugPrintLock to use this: 50 | void HalPrintStringDebug(const char* str); 51 | 52 | // ==== Crashing ==== 53 | // don't use. Use KeCrash instead 54 | NO_RETURN void HalCrashSystem(const char* message); 55 | 56 | // ==== Initialization ==== 57 | void HalUPInit(); 58 | void HalMPInit(); 59 | 60 | // ==== AMD64 specific features ==== 61 | #ifdef TARGET_AMD64 62 | void HalEnableApic(); 63 | #endif 64 | 65 | #endif//NS64_HAL_H 66 | -------------------------------------------------------------------------------- /boron/include/hal/data.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | hal/timer.h 7 | 8 | Abstract: 9 | This header file contains the definition for the processor 10 | specific HAL data structure. 11 | 12 | Author: 13 | iProgramInCpp - 29 September 2023 14 | ***/ 15 | #ifndef BORON_HAL_DATA_H 16 | #define BORON_HAL_DATA_H 17 | 18 | // HAL Control Block 19 | typedef struct KHALCB_tag 20 | { 21 | // LAPIC and TSC frequencies, in ticks/ms. 22 | uint64_t LapicFrequency; 23 | uint64_t TscFrequency; 24 | } 25 | KHALCB, *PKHALCB; 26 | 27 | PKHALCB KeGetCurrentHalCB(); 28 | 29 | #endif//BORON_HAL_DATA_H 30 | -------------------------------------------------------------------------------- /boron/include/hal/init.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | hal/init.h 7 | 8 | Abstract: 9 | This header file contains the definition for the 10 | HAL function pointer structure and miscellaneous 11 | HAL initialization details. 12 | 13 | Author: 14 | iProgramInCpp - 27 October 2023 15 | ***/ 16 | #ifndef BORON_HAL_INIT_H 17 | #define BORON_HAL_INIT_H 18 | 19 | #include 20 | 21 | #define HAL_VFTABLE_LOADED (1 << 0) 22 | 23 | // Function pointer definitions 24 | typedef void(*PFHAL_END_OF_INTERRUPT)(void); 25 | typedef void(*PFHAL_REQUEST_INTERRUPT_IN_TICKS)(uint64_t Ticks); 26 | typedef void(*PFHAL_REQUEST_IPI)(uint32_t LapicId, uint32_t Flags, int Vector); 27 | typedef void(*PFHAL_INIT_SYSTEM_UP)(void); 28 | typedef void(*PFHAL_INIT_SYSTEM_MP)(void); 29 | typedef void(*PFHAL_DISPLAY_STRING)(const char* Message); 30 | typedef void(*PFHAL_CRASH_SYSTEM)(const char* Message) NO_RETURN; 31 | typedef bool(*PFHAL_USE_ONE_SHOT_INT_TIMER)(void); 32 | typedef void(*PFHAL_PROCESSOR_CRASHED)(void); 33 | typedef uint64_t(*PFHAL_GET_INT_TIMER_FREQUENCY)(void); 34 | typedef uint64_t(*PFHAL_GET_TICK_COUNT)(void); 35 | typedef uint64_t(*PFHAL_GET_TICK_FREQUENCY)(void); 36 | typedef uint64_t(*PFHAL_GET_INT_TIMER_DELTA_TICKS)(void); 37 | 38 | #ifdef TARGET_AMD64 39 | 40 | typedef void(*PFHAL_IOAPIC_SET_IRQ_REDIRECT)(uint8_t Vector, uint8_t Irq, uint32_t LapicId, bool Status); 41 | 42 | #include "pci.h" 43 | 44 | #endif 45 | 46 | typedef struct 47 | { 48 | uint64_t Flags; 49 | 50 | PFHAL_END_OF_INTERRUPT EndOfInterrupt; 51 | PFHAL_REQUEST_INTERRUPT_IN_TICKS RequestInterruptInTicks; 52 | PFHAL_REQUEST_IPI RequestIpi; 53 | PFHAL_INIT_SYSTEM_UP InitSystemUP; 54 | PFHAL_INIT_SYSTEM_MP InitSystemMP; 55 | PFHAL_DISPLAY_STRING DisplayString; 56 | PFHAL_CRASH_SYSTEM CrashSystem; 57 | PFHAL_USE_ONE_SHOT_INT_TIMER UseOneShotIntTimer; 58 | PFHAL_PROCESSOR_CRASHED ProcessorCrashed; 59 | PFHAL_GET_INT_TIMER_FREQUENCY GetIntTimerFrequency; 60 | PFHAL_GET_TICK_COUNT GetTickCount; 61 | PFHAL_GET_TICK_FREQUENCY GetTickFrequency; 62 | PFHAL_GET_INT_TIMER_DELTA_TICKS GetIntTimerDeltaTicks; 63 | 64 | #ifdef TARGET_AMD64 65 | PFHAL_IOAPIC_SET_IRQ_REDIRECT IoApicSetIrqRedirect; 66 | PFHAL_PCI_ENUMERATE PciEnumerate; 67 | PFHAL_PCI_CONFIG_READ_DWORD PciConfigReadDword; 68 | PFHAL_PCI_CONFIG_READ_WORD PciConfigReadWord; 69 | PFHAL_PCI_CONFIG_WRITE_DWORD PciConfigWriteDword; 70 | PFHAL_PCI_READ_DEVICE_IDENTIFIER PciReadDeviceIdentifier; 71 | PFHAL_PCI_READ_BAR PciReadBar; 72 | PFHAL_PCI_READ_BAR_ADDRESS PciReadBarAddress; 73 | PFHAL_PCI_READ_BAR_IO_ADDRESS PciReadBarIoAddress; 74 | #endif 75 | } 76 | HAL_VFTABLE, *PHAL_VFTABLE; 77 | 78 | void HalInitializeTemporary(); 79 | 80 | #endif//BORON_HAL_INIT_H 81 | -------------------------------------------------------------------------------- /boron/include/hal/timer.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | hal/timer.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the API 10 | for the generic system timer (GST) implemented by the 11 | HAL. 12 | 13 | Author: 14 | iProgramInCpp - 29 September 2023 15 | ***/ 16 | #ifndef BORON_HAL_TIMER_H 17 | #define BORON_HAL_TIMER_H 18 | 19 | // 20 | // The timer interface is split into two parts: 21 | // * Monotonic timer (MT) 22 | // * One shot timer (OST) 23 | // * Periodic Timer (PT) 24 | // 25 | // With the MT, you get a monotonically increasing tick count whose frequency 26 | // never changes. However, you can't set up any kind of interrupt. 27 | // 28 | // With the OST, you get a timer that, when a set number of ticks passes, fires 29 | // an interrupt. However, you don't get a monotonically increasing tick count. 30 | // 31 | // The OST is mutually exclusive to the PT (there can't be both at the same time), 32 | // and HalUseOneShotTimer() determines whether to program for the OST or the PT. 33 | // 34 | // Both the OST and PT are called "interrupt timers" (IT). Use the IT term when 35 | // referring to both at the same time, such as in HalGetItTicksPerSecond(). 36 | // 37 | 38 | // ==== Monotonic timer ==== 39 | // Gets the frequency of the monotonic timer. 40 | uint64_t HalGetTickFrequency(); 41 | 42 | // Gets the number of ticks elapsed since the monotonic timer was setup. 43 | uint64_t HalGetTickCount(); 44 | 45 | // ==== Interrupt timer (OST + PT common) ==== 46 | // Get the frequency of the interrupt timer. 47 | uint64_t HalGetIntTimerFrequency(); 48 | 49 | // Whether to use the OST (true) or the PT (false). 50 | bool HalUseOneShotTimer(); 51 | 52 | // ==== One Shot Timer ==== 53 | // Requests an interrupt in a certain amount of ticks. 54 | // This is a feature of the OST only, don't call this if HalUseOneShotTimer() is false. 55 | void HalRequestInterruptInTicks(uint64_t ticks); 56 | 57 | // ==== Periodic Timer ==== 58 | // Get the time (in ticks) between interrupts. 59 | // If 1, then every tick represents an interrupt, and HalGetItTicksPerSecond() essentially 60 | // represents the amount of interrupts in a second. 61 | uint64_t HalGetInterruptDeltaTime(); 62 | 63 | #endif//BORON_HAL_TIMER_H 64 | -------------------------------------------------------------------------------- /boron/include/io.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | io.h 7 | 8 | Abstract: 9 | This header file contains the definitions related to 10 | the Boron kernel I/O manager. 11 | 12 | Author: 13 | iProgramInCpp - 15 February 2024 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | typedef struct _DEVICE_OBJECT DEVICE_OBJECT, *PDEVICE_OBJECT; 23 | typedef struct _DRIVER_OBJECT DRIVER_OBJECT, *PDRIVER_OBJECT; 24 | typedef struct _CONTROLLER_OBJECT CONTROLLER_OBJECT, *PCONTROLLER_OBJECT; 25 | typedef struct _FILE_OBJECT FILE_OBJECT, *PFILE_OBJECT; 26 | typedef struct _FCB FCB, *PFCB; 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | // These aren't meant to be used directly. Instead, they're used 37 | // by the IoGetBuiltInData function. If the compile unit including 38 | // this header is not part of the kernel, what would normally link 39 | // to extern global variables would instead call IoGetBuiltInData. 40 | enum { 41 | __IO_DRIVER_TYPE = 0, 42 | __IO_DEVICE_TYPE = 1, 43 | __IO_FILE_TYPE = 2, 44 | __IO_DEVICES_DIR = 3, 45 | __IO_DRIVERS_DIR = 4, 46 | __IO_CNTRLR_TYPE = 5, 47 | }; 48 | 49 | void* IoGetBuiltInData(int Number); 50 | 51 | #ifdef KERNEL 52 | 53 | // The kernel can use these directly. 54 | extern POBJECT_TYPE IoDriverType, IoDeviceType, IoFileType, IoControllerType; 55 | extern POBJECT_DIRECTORY IoDriversDir, IoDevicesDir; 56 | 57 | #else 58 | 59 | // Due to a limitation of the driver dynamic linker (Ldr), have to do this: 60 | #define IoDriverType ((POBJECT_TYPE) IoGetBuiltInData(__IO_DRIVER_TYPE)) 61 | #define IoDeviceType ((POBJECT_TYPE) IoGetBuiltInData(__IO_DEVICE_TYPE)) 62 | #define IoFileType ((POBJECT_TYPE) IoGetBuiltInData(__IO_FILE_TYPE)) 63 | #define IoDriversDir ((POBJECT_DIRECTORY) IoGetBuiltInData(__IO_DRIVERS_DIR)) 64 | #define IoDevicesDir ((POBJECT_DIRECTORY) IoGetBuiltInData(__IO_CNTRLR_TYPE)) 65 | #define IoControllerType ((POBJECT_DIRECTORY) IoGetBuiltInData(__IO_DEVICES_DIR)) 66 | 67 | #endif 68 | 69 | bool IoInitSystem(); 70 | 71 | -------------------------------------------------------------------------------- /boron/include/io/cntrobj.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | io/cntrobj.h 7 | 8 | Abstract: 9 | This header file defines the I/O controller object structure. 10 | 11 | Author: 12 | iProgramInCpp - 9 July 2024 13 | ***/ 14 | #pragma once 15 | 16 | #include 17 | 18 | typedef struct _CONTROLLER_OBJECT 19 | { 20 | PDRIVER_OBJECT DriverObject; 21 | 22 | KMUTEX DeviceTreeMutex; 23 | 24 | // Keyed by a driver specific uintptr-sized key. For example, 25 | // the slot number occupied by a device can be used as a key. 26 | RBTREE DeviceTree; 27 | 28 | char Extension[]; 29 | } 30 | CONTROLLER_OBJECT, *PCONTROLLER_OBJECT; 31 | 32 | BSTATUS IoCreateController( 33 | PDRIVER_OBJECT DriverObject, 34 | size_t ControllerExtensionSize, 35 | const char* ControllerName, 36 | bool Permanent, 37 | PCONTROLLER_OBJECT* OutControllerObject 38 | ); 39 | 40 | PDEVICE_OBJECT IoGetDeviceController( 41 | PCONTROLLER_OBJECT Controller, 42 | uintptr_t Key 43 | ); 44 | 45 | // NOTE: Does not add 1 to the reference count of either the device or the 46 | // controller. After the call there can be two deletion scenarios: 47 | // 48 | // 1. The device is deleted. It will then be removed from the controller 49 | // by the device's delete handler. This is probably a driver-initiated 50 | // deletion anyway. 51 | // 52 | // 2. The controller is deleted. For each device still connected, its 53 | // controller links are cleared. The devices will be deleted when their 54 | // final reference is deleted. 55 | BSTATUS IoAddDeviceController( 56 | PCONTROLLER_OBJECT Controller, 57 | uintptr_t Key, 58 | PDEVICE_OBJECT Device 59 | ); 60 | 61 | BSTATUS IoRemoveDeviceController( 62 | PCONTROLLER_OBJECT Controller, 63 | PDEVICE_OBJECT Device 64 | ); 65 | -------------------------------------------------------------------------------- /boron/include/io/devobj.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | io/devobj.h 7 | 8 | Abstract: 9 | This header file defines the I/O device object structure. 10 | 11 | Author: 12 | iProgramInCpp - 16 February 2024 13 | ***/ 14 | #pragma once 15 | 16 | #include "dispatch.h" 17 | 18 | // Supported types of devices: 19 | typedef enum _DEVICE_TYPE 20 | { 21 | DEVICE_TYPE_UNKNOWN, 22 | DEVICE_TYPE_CHARACTER, // Terminals, keyboards, mice, etc. 23 | DEVICE_TYPE_BLOCK, // Disk drives, CD-ROM drives, etc. 24 | DEVICE_TYPE_VIDEO, // Frame buffer devices 25 | DEVICE_TYPE_NETWORK, // Network adapter devices 26 | } 27 | DEVICE_TYPE; 28 | 29 | struct _DEVICE_OBJECT 30 | { 31 | // The type of device object this is. 32 | DEVICE_TYPE DeviceType; 33 | 34 | // The driver object that we belong to. 35 | PDRIVER_OBJECT DriverObject; 36 | 37 | // The entry in the driver object's list of devices. 38 | LIST_ENTRY ListEntry; 39 | 40 | // A pointer to the I/O operation dispatch table. 41 | PIO_DISPATCH_TABLE DispatchTable; 42 | 43 | PFCB Fcb; 44 | 45 | // If this is part of a controller, this is the pointer to that controller. 46 | PCONTROLLER_OBJECT ParentController; 47 | 48 | // If this is part of a controller, this is the entry into the controller's 49 | // device tree. 50 | RBTREE_ENTRY DeviceTreeEntry; 51 | 52 | // If this is a partition, this is the device object this one belongs to 53 | // (Note: This object is referenced for the lifetime of this device) 54 | PDEVICE_OBJECT ParentDevice; 55 | 56 | // If this is a mounted partition, this is the file object pointing to the 57 | // root of said mount. 58 | // TODO: Maybe this belongs in a separate object? 59 | PFILE_OBJECT MountRoot; 60 | 61 | // If this is a partitionable device, this is an entry into the list of 62 | // partitionable objects. 63 | LIST_ENTRY PartitionableListEntry; 64 | 65 | // Extension data. 66 | size_t ExtensionSize; 67 | char Extension[]; 68 | }; 69 | 70 | BSTATUS IoCreateDevice( 71 | PDRIVER_OBJECT DriverObject, 72 | size_t DeviceExtensionSize, 73 | size_t FcbExtensionSize, 74 | const char* DeviceName, 75 | DEVICE_TYPE Type, 76 | bool Permanent, 77 | PIO_DISPATCH_TABLE DispatchTable, 78 | PDEVICE_OBJECT* OutDeviceObject 79 | ); 80 | 81 | BSTATUS IoReadDevice( 82 | PIO_STATUS_BLOCK Iosb, 83 | PDEVICE_OBJECT DeviceObject, 84 | PMDL Mdl, 85 | uint64_t FileOffset, 86 | bool Cached 87 | ); 88 | 89 | BSTATUS IoWriteDevice( 90 | PIO_STATUS_BLOCK Iosb, 91 | PDEVICE_OBJECT DeviceObject, 92 | PMDL Mdl, 93 | uint64_t FileOffset, 94 | bool Cached 95 | ); 96 | -------------------------------------------------------------------------------- /boron/include/io/drvobj.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | io/drvobj.h 7 | 8 | Abstract: 9 | This header file defines the I/O driver object structure. 10 | 11 | Author: 12 | iProgramInCpp - 16 February 2024 13 | ***/ 14 | #pragma once 15 | 16 | #include "dispatch.h" 17 | 18 | typedef BSTATUS(*PDRIVER_ENTRY)(PDRIVER_OBJECT Object); 19 | typedef BSTATUS(*PDRIVER_UNLOAD)(PDRIVER_OBJECT Object); 20 | typedef BSTATUS(*PDRIVER_ADD_DEVICE)(PDRIVER_OBJECT Object, PDEVICE_OBJECT Device); 21 | 22 | struct _DRIVER_OBJECT 23 | { 24 | // Flags. 25 | uint32_t Flags; 26 | uint32_t Available; 27 | 28 | // Name of the driver. Assigned by the driver loader. 29 | const char* DriverName; 30 | 31 | // Pointer to extended data stored by the driver. The kernel does 32 | // not use this pointer - it's entirely driver-controlled. 33 | void* DriverExtension; 34 | 35 | // List of device objects implemented by this driver. 36 | LIST_ENTRY DeviceList; 37 | KSPIN_LOCK DeviceListLock; 38 | 39 | // The entry point of the driver. 40 | PDRIVER_ENTRY DriverEntry; 41 | 42 | // The routine called when the driver is to be unloaded. If can't 43 | // be unloaded, this is NULL. 44 | PDRIVER_UNLOAD Unload; 45 | 46 | // The routine called when a device is added. This is called in 47 | // the case that the driver passes off the request to look for 48 | // specific devices to the kernel. For example, a driver that 49 | // operates devices on the PCI bus with a specific vendor and 50 | // device ID can simply tell the kernel to lookup the specific 51 | // devices and add them. 52 | PDRIVER_ADD_DEVICE AddDevice; 53 | }; 54 | -------------------------------------------------------------------------------- /boron/include/io/fileobj.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | io/fileobj.h 7 | 8 | Abstract: 9 | This header defines the structure of the opened file object. 10 | 11 | Author: 12 | iProgramInCpp - 22 June 2024 13 | ***/ 14 | #pragma once 15 | 16 | typedef struct _IO_STATUS_BLOCK IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; 17 | 18 | enum 19 | { 20 | FILE_FLAG_APPEND_ONLY = (1 << 0), 21 | }; 22 | 23 | typedef struct _FILE_OBJECT 24 | { 25 | PFCB Fcb; 26 | 27 | void* Context1; 28 | void* Context2; 29 | 30 | uint64_t Offset; 31 | uint32_t Flags; 32 | uint32_t OpenFlags; 33 | } 34 | FILE_OBJECT, *PFILE_OBJECT; 35 | 36 | bool IoIsSeekable(PFILE_OBJECT Object); 37 | 38 | BSTATUS IoReadFileObject( 39 | PIO_STATUS_BLOCK Iosb, 40 | PFILE_OBJECT FileObject, 41 | PMDL Mdl, 42 | uint64_t FileOffset, 43 | bool Cached 44 | ); 45 | 46 | BSTATUS IoWriteFileObject( 47 | PIO_STATUS_BLOCK Iosb, 48 | PFILE_OBJECT FileObject, 49 | PMDL Mdl, 50 | uint64_t FileOffset, 51 | bool Cached 52 | ); 53 | -------------------------------------------------------------------------------- /boron/include/io/part.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | main.c 7 | 8 | Abstract: 9 | This header defines prototypes for the partition manager 10 | API in Boron. 11 | 12 | Author: 13 | iProgramInCpp - 30 April 2025 14 | ***/ 15 | #pragma once 16 | 17 | void IoRegisterPartitionableDevice(PDEVICE_OBJECT DeviceObject); 18 | 19 | void IoRegisterFileSystemDriver(PIO_DISPATCH_TABLE DispatchTable); 20 | -------------------------------------------------------------------------------- /boron/include/io/rdwr.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | io/rdwr.h 7 | 8 | Abstract: 9 | This header defines the I/O manager's user-facing 10 | I/O functions, such as reading and writing. 11 | 12 | Author: 13 | iProgramInCpp - 2 July 2024 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | #ifdef KERNEL 20 | 21 | // Performs a direct read operation over a file object. This is only 22 | // for use by the kernel and should not be used by device drivers. 23 | 24 | BSTATUS IoPerformPagingRead( 25 | PIO_STATUS_BLOCK Iosb, 26 | PFILE_OBJECT FileObject, 27 | PMDL Mdl, 28 | uint64_t FileOffset 29 | ); 30 | 31 | #endif 32 | 33 | BSTATUS IoReadFile(PIO_STATUS_BLOCK Iosb, HANDLE Handle, PMDL Mdl, uint32_t Flags); 34 | 35 | BSTATUS IoWriteFile(PIO_STATUS_BLOCK Iosb, HANDLE Handle, PMDL Mdl, uint32_t Flags); 36 | 37 | BSTATUS IoTouchFile(HANDLE Handle, bool IsWrite); 38 | 39 | BSTATUS IoGetAlignmentInfo(HANDLE Handle, size_t* AlignmentOut); 40 | 41 | BSTATUS OSReadFile(PIO_STATUS_BLOCK Iosb, HANDLE Handle, void* Buffer, size_t Length, uint32_t Flags); 42 | 43 | BSTATUS OSWriteFile(PIO_STATUS_BLOCK Iosb, HANDLE Handle, const void* Buffer, size_t Length, uint32_t Flags); 44 | 45 | BSTATUS OSOpenFile(PHANDLE OutHandle, POBJECT_ATTRIBUTES ObjectAttributes); 46 | 47 | BSTATUS OSSeekFile(HANDLE FileHandle, int64_t NewPosition, int SeekWhence); 48 | 49 | BSTATUS OSGetLengthFile(HANDLE FileHandle, uint64_t* Length); 50 | -------------------------------------------------------------------------------- /boron/include/ke.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke.h 7 | 8 | Abstract: 9 | This header file contains the amalgam include file 10 | for the kernel core. 11 | 12 | Author: 13 | iProgramInCpp - 20 August 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | -------------------------------------------------------------------------------- /boron/include/ke/apc.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | ke/apc.h 7 | 8 | Abstract: 9 | This module contains the definitions related to the 10 | asynchronous procedure call system. 11 | 12 | Author: 13 | iProgramInCpp - 21 February 2024 14 | ***/ 15 | #pragma once 16 | 17 | typedef struct _KAPC KAPC, *PKAPC; 18 | typedef struct KTHREAD_tag KTHREAD, *PKTHREAD; 19 | 20 | // Pointer to routine to be executed in the specified context. 21 | typedef void(*PKAPC_NORMAL_ROUTINE)(void* Context, void* SystemArgument1, void* SystemArgument2); 22 | 23 | // Pointer to routine to be executed in kernel mode, at IPL_APC. 24 | typedef void(*PKAPC_KERNEL_ROUTINE)( 25 | PKAPC Apc, 26 | PKAPC_NORMAL_ROUTINE* InOutNormalRoutine, 27 | void** InOutNormalContext, 28 | void** InOutSystemArgument1, 29 | void** InOutSystemArgument2 30 | ); 31 | 32 | struct _KAPC 33 | { 34 | // The thread the APC belongs to. 35 | PKTHREAD Thread; 36 | 37 | // A special APC can break into thread execution any time the thread is running 38 | // at normal IPL. Normal APCs can only break into thread execution while it is 39 | // running at normal IPL, and there isn't a normal APC currently running. 40 | // 41 | // During execution of special APCs, kernel services are available, but not all 42 | // system services may be available. 43 | // 44 | // A special APC is a kernel-mode APC that lacks a normal routine. 45 | 46 | // Routine to be executed in kernel mode at IPL APC. 47 | PKAPC_KERNEL_ROUTINE KernelRoutine; 48 | 49 | // Routine to be executed in the specified APC mode (kernel or user), as well 50 | // as parameters. They are set by KeInitializeApc, and can be modified by the 51 | // KernelRoutine. 52 | PKAPC_NORMAL_ROUTINE NormalRoutine; 53 | void* NormalContext; 54 | void* SystemArgument1; 55 | void* SystemArgument2; 56 | 57 | KPROCESSOR_MODE ApcMode; 58 | 59 | // Entry into the thread's list of APCs. 60 | LIST_ENTRY ListEntry; 61 | 62 | // Whether the APC is enqueued. 63 | bool Enqueued; 64 | }; 65 | 66 | void KeInitializeApc( 67 | PKAPC Apc, 68 | PKTHREAD Thread, 69 | PKAPC_KERNEL_ROUTINE KernelRoutine, 70 | PKAPC_NORMAL_ROUTINE NormalRoutine, 71 | void* NormalContext, 72 | KPROCESSOR_MODE ApcMode 73 | ); 74 | 75 | bool KeInsertQueueApc( 76 | PKAPC Apc, 77 | void* SystemArgument1, 78 | void* SystemArgument2, 79 | KPRIORITY Increment 80 | ); 81 | -------------------------------------------------------------------------------- /boron/include/ke/crash.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/crash.h 7 | 8 | Abstract: 9 | This header file contains the definitions related 10 | to the crash functions. 11 | 12 | Author: 13 | iProgramInCpp - 28 October 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | NO_RETURN void KeCrash(const char* message, ...); 20 | NO_RETURN void KeCrashBeforeSMPInit(const char* message, ...); 21 | 22 | #ifdef IS_HAL 23 | NO_RETURN void KeCrashConclusion(const char* Message); 24 | #endif 25 | -------------------------------------------------------------------------------- /boron/include/ke/dbg.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/dbg.h 7 | 8 | Abstract: 9 | This header file contains the definitions 10 | related to the DLL loader. 11 | 12 | Author: 13 | iProgramInCpp - 28 October 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | #ifdef DEBUG 20 | 21 | void DbgInit(); 22 | 23 | void DbgPrintString(const char* str); 24 | 25 | void DbgPrintStringLocked(const char* str); 26 | 27 | #else 28 | 29 | #define DbgInit() 30 | #define DbgPrintString(str) 31 | #define DbgPrintStringLocked(str) 32 | 33 | #endif 34 | 35 | void DbgPrintStackTrace(uintptr_t Frame); 36 | 37 | uintptr_t DbgLookUpAddress(const char* Name); 38 | 39 | const char* DbgLookUpRoutineNameByAddressExact(uintptr_t Address); 40 | 41 | const char* DbgLookUpRoutineNameByAddress(uintptr_t Address, uintptr_t* BaseAddressOut); 42 | -------------------------------------------------------------------------------- /boron/include/ke/dispatch.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/dispatch.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | dispatch objects. 11 | 12 | Author: 13 | iProgramInCpp - 30 October 2023 14 | ***/ 15 | #pragma once 16 | 17 | #define TIMEOUT_INFINITE (0x7FFFFFFF) 18 | 19 | #include 20 | 21 | typedef struct KTHREAD_tag KTHREAD, *PKTHREAD; 22 | 23 | typedef struct KDISPATCH_HEADER_tag 24 | { 25 | uint8_t Type; 26 | uint8_t Spare1; 27 | short Signaled; 28 | 29 | LIST_ENTRY WaitBlockList; 30 | } 31 | KDISPATCH_HEADER, *PKDISPATCH_HEADER; 32 | 33 | enum 34 | { 35 | DISPATCH_EVENT, 36 | DISPATCH_TIMER, 37 | DISPATCH_MUTEX, 38 | DISPATCH_SEMAPHORE, 39 | DISPATCH_THREAD, 40 | DISPATCH_PROCESS, 41 | }; 42 | 43 | enum 44 | { 45 | WAIT_TYPE_ALL, 46 | WAIT_TYPE_ANY, 47 | }; 48 | 49 | typedef struct KWAIT_BLOCK_tag 50 | { 51 | LIST_ENTRY Entry; // Entry into the linked list of threads waiting for an object. 52 | PKDISPATCH_HEADER Object; // The object that the containing thread waits on. 53 | PKTHREAD Thread; // The thread that the wait block is part of. 54 | } 55 | KWAIT_BLOCK, *PKWAIT_BLOCK; 56 | 57 | #include "wait.h" 58 | 59 | // Initialize the dispatcher header. 60 | void KeInitializeDispatchHeader(PKDISPATCH_HEADER Object, int Type); 61 | 62 | // Dispatch objects 63 | #include "timer.h" 64 | #include "event.h" 65 | #include "mutex.h" 66 | #include "semaphor.h" 67 | #include "process.h" 68 | -------------------------------------------------------------------------------- /boron/include/ke/dpc.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/dpc.h 7 | 8 | Abstract: 9 | This module contains the definitions related to the 10 | deferred procedure call system. 11 | 12 | Author: 13 | iProgramInCpp - 3 October 2023 14 | ***/ 15 | #ifndef BORON_KE_DPC_H 16 | #define BORON_KE_DPC_H 17 | 18 | #include 19 | #include <_limine.h> 20 | 21 | typedef struct KDPC_tag KDPC, *PKDPC; 22 | 23 | typedef void(*PKDEFERRED_ROUTINE)(PKDPC Dpc, void* Context, void* SA1, void* SA2); 24 | 25 | struct KDPC_tag 26 | { 27 | LIST_ENTRY List; 28 | 29 | PKDEFERRED_ROUTINE Routine; 30 | 31 | void* DeferredContext; 32 | void* SystemArgument1; 33 | void* SystemArgument2; 34 | 35 | bool Initialized; 36 | bool Enqueued; 37 | bool Important; 38 | }; 39 | 40 | typedef struct KDPC_QUEUE_tag 41 | { 42 | LIST_ENTRY List; 43 | } 44 | KDPC_QUEUE, *PKDPC_QUEUE; 45 | 46 | // Initialize a DPC object. 47 | void KeInitializeDpc(PKDPC Dpc, PKDEFERRED_ROUTINE Routine, void* DeferredContext); 48 | 49 | // Set the importance of the DPC object. 50 | // Note! You *must* call this BEFORE enqueuing the DPC, otherwise the 51 | // behavior is undefined. Even if the DPC is still enqueued, its place 52 | // in the queue won't be changed. 53 | void KeSetImportantDpc(PKDPC Dpc, bool Important); 54 | 55 | // Enqueues the DPC object. 56 | // Note! After calling this, consider the object invalid, until you know exactly 57 | // that the DPC is valid again (not cleaned up by the deferred routine), and no 58 | // longer held within the queue. 59 | void KeEnqueueDpc(PKDPC Dpc, void* SysArg1, void* SysArg2); 60 | 61 | #ifdef KERNEL 62 | // Dispatch DPCs. Don't use if you're not the self IPI handler! 63 | void KiDispatchDpcs(); 64 | #endif 65 | 66 | #endif // BORON_KE_DPC_H 67 | -------------------------------------------------------------------------------- /boron/include/ke/event.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/event.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | event dispatch object. 11 | 12 | Author: 13 | iProgramInCpp - 11 November 2023 14 | ***/ 15 | #pragma once 16 | 17 | enum // [1] 18 | { 19 | EVENT_SYNCHRONIZATION, 20 | EVENT_NOTIFICATION, 21 | }; 22 | 23 | typedef struct KEVENT_tag 24 | { 25 | KDISPATCH_HEADER Header; 26 | 27 | int Type; // [1] 28 | } 29 | KEVENT, *PKEVENT; 30 | 31 | #define ASSERT_EVENT(Event) ASSERT((Event)->Header.Type == DISPATCH_EVENT) 32 | 33 | void KeInitializeEvent(PKEVENT Event, int EventType, bool State); 34 | 35 | bool KeReadStateEvent(PKEVENT Event); 36 | 37 | void KeSetEvent(PKEVENT Event, KPRIORITY Increment); 38 | 39 | void KeResetEvent(PKEVENT Event); 40 | 41 | void KePulseEvent(PKEVENT Event, KPRIORITY Increment); 42 | 43 | #ifdef KERNEL 44 | // Don't use. 45 | // 46 | // This API is supposed to be called at IPL_DPC and above. Doing so at a lower 47 | // IPL could cause a crash in debug mode, or a potentially invalid thread pointer 48 | // in release mode. 49 | // 50 | // Good thing that this API is only used in the rwlock implementation. 51 | PKTHREAD KeSetEventAndGetWaiter(PKEVENT Event, KPRIORITY Increment); 52 | #endif 53 | -------------------------------------------------------------------------------- /boron/include/ke/ipl.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/ipl.h 7 | 8 | Abstract: 9 | This header file contains the IPL manipulation function 10 | prototypes. 11 | 12 | Author: 13 | iProgramInCpp - 28 September 2023 14 | ***/ 15 | #ifndef BORON_KE_IPL_H 16 | #define BORON_KE_IPL_H 17 | 18 | #include 19 | 20 | // To raise the IPL temporarily, opt for the following structure; 21 | // eIPL oldIPL = KeRaiseIPL(IPL_WHATEVER); 22 | // .... your code here 23 | // KeLowerIPL(oldIPL); 24 | 25 | // Raise the IPL of the current processor. 26 | // Don't pass an IPL higher than the current IPL. 27 | KIPL KeRaiseIPL(KIPL newIPL); 28 | 29 | // Raise the IPL of the current processor to the new IPL, but if the current 30 | // IPL is higher or equal to the current IPL, the current IPL remains. 31 | KIPL KeRaiseIPLIfNeeded(KIPL newIPL); 32 | 33 | // Lower the IPL of the current processor back to the level before KeRaiseIPL. 34 | KIPL KeLowerIPL(KIPL newIPL); 35 | 36 | #endif//BORON_KE_IPL_H -------------------------------------------------------------------------------- /boron/include/ke/irq.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | ke/irq.h 7 | 8 | Abstract: 9 | This header file defines the kernel internal interrupt 10 | interface. Device drivers should use the interface 11 | defined in ke/int.h. 12 | 13 | Author: 14 | iProgramInCpp - 28 October 2023 15 | ***/ 16 | #ifndef NS64_KE_IRQ_H 17 | #define NS64_KE_IRQ_H 18 | 19 | #include 20 | #include 21 | 22 | // Allocate an interrupt vector for the specified IPL. 23 | int KeAllocateInterruptVector(KIPL Ipl); 24 | 25 | // 26 | // WARNING! 27 | // 28 | // These programming interfaces are NOT to be used for drivers. They are only designed 29 | // for the kernel and the HAL. Use the interrupt object interface (ke/int.h) in order to 30 | // use interrupts in your device driver. 31 | // 32 | 33 | #if defined KERNEL || defined IS_HAL 34 | 35 | // Note! The interrupt handler doesn't ACTUALLY deal in KREGISTERS 36 | // pointers. It just so happens that what we pass in as parameter 37 | // and what we return are PKREGISTERS instances! In reality the pointer 38 | // is actually located within the current thread's stack. 39 | // 40 | // Don't return an instance to PKREGISTERS like I did - since the exit part of the 41 | // trap handler calls KiExitHardwareInterrupt, it's going to go into addresses less 42 | // than that which you return!! 43 | typedef PKREGISTERS(*PKINTERRUPT_HANDLER)(PKREGISTERS); 44 | 45 | // Note - This API is to be used during single processor initialization (UP-Init) only. 46 | // Behavior is not defined during MP-Init initialization. 47 | 48 | void KeRegisterInterrupt(int Vector, PKINTERRUPT_HANDLER Handler); 49 | 50 | void KeSetInterruptIPL(int Vector, KIPL Ipl); 51 | 52 | #ifdef KERNEL 53 | 54 | // The HAL can't use these directly. 55 | extern 56 | int KiVectorCrash, 57 | KiVectorTlbShootdown; 58 | 59 | #else 60 | 61 | #define KiVectorCrash (KeGetSystemInterruptVector(KGSIV_CRASH)) 62 | #define KiVectorTlbShootdown (KeGetSystemInterruptVector(KGSIV_TLB_SHOOTDOWN)) 63 | 64 | #endif 65 | 66 | // This is destined for use in the HAL. 67 | // The linker doesn't seem to export global value references 68 | // as external dependencies. It's pretty weird. 69 | enum 70 | { 71 | KGSIV_NONE = 0, 72 | KGSIV_CRASH, 73 | KGSIV_TLB_SHOOTDOWN, 74 | }; 75 | 76 | int KeGetSystemInterruptVector(int Number); 77 | 78 | #endif 79 | 80 | #endif//NS64_KE_IRQ_H 81 | -------------------------------------------------------------------------------- /boron/include/ke/locks.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/locks.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | locking primitives used in the kernel. 11 | 12 | Author: 13 | iProgramInCpp - 28 September 2023 14 | ***/ 15 | #ifndef BORON_KE_LOCKS_H 16 | #define BORON_KE_LOCKS_H 17 | 18 | #include 19 | 20 | // simple spin locks, for when contention is rare 21 | typedef struct 22 | { 23 | bool Locked; 24 | #if defined(DEBUG) && defined(SPINLOCK_TRACK_PC) 25 | uint64_t Pc : 48; // Locking program counter - debug only 26 | #endif 27 | } 28 | KSPIN_LOCK, *PKSPIN_LOCK; 29 | 30 | void KeInitializeSpinLock(PKSPIN_LOCK); 31 | void KeAcquireSpinLock(PKSPIN_LOCK, PKIPL OldIpl); 32 | void KeReleaseSpinLock(PKSPIN_LOCK, KIPL OldIpl); 33 | bool KeAttemptAcquireSpinLock(PKSPIN_LOCK, PKIPL OldIpl); 34 | 35 | // ticket locks, for when contention is definitely possible 36 | typedef struct 37 | { 38 | int NowServing; 39 | int NextNumber; 40 | } 41 | KTICKET_LOCK, *PKTICKET_LOCK; 42 | 43 | void KeInitializeTicketLock(PKTICKET_LOCK); 44 | void KeAcquireTicketLock(PKTICKET_LOCK, PKIPL OldIpl); 45 | void KeReleaseTicketLock(PKTICKET_LOCK, KIPL OldIpl); 46 | 47 | #endif//BORON_KE_LOCKS_H 48 | -------------------------------------------------------------------------------- /boron/include/ke/mode.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/mode.h 7 | 8 | Abstract: 9 | This module defines the KPROCESSOR_MODE enum 10 | 11 | Author: 12 | iProgramInCpp - 27 November 2023 13 | ***/ 14 | #pragma once 15 | 16 | typedef enum KPROCESSOR_MODE_tag 17 | { 18 | MODE_KERNEL, 19 | MODE_USER, 20 | } 21 | KPROCESSOR_MODE, *PKPROCESSOR_MODE; 22 | 23 | // Gets the previous processor mode. This is MODE_USER if a user 24 | // system service request or page fault brought the thread back 25 | // up to kernel mode. 26 | KPROCESSOR_MODE KeGetPreviousMode(); 27 | 28 | // Sets the mode (kernel or user) that the kernel uses when 29 | // validating addresses when calling into system services. 30 | // 31 | // Use this very carefully. Only use this if ALL of the addresses 32 | // you are about to pass into a system service are kernel mode 33 | // addresses (such as part of the kernel stack or something). 34 | KPROCESSOR_MODE KeSetAddressMode(KPROCESSOR_MODE NewMode); 35 | -------------------------------------------------------------------------------- /boron/include/ke/mutex.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/mutex.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | mutex dispatch object. 11 | 12 | Author: 13 | iProgramInCpp - 18 November 2023 14 | ***/ 15 | #pragma once 16 | 17 | // The return value of KeReadStateMutex, if the mutex is signaled. 18 | #define MUTEX_SIGNALED (0) 19 | 20 | typedef struct KMUTEX_tag 21 | { 22 | KDISPATCH_HEADER Header; 23 | 24 | // Level debugging is performed in debug checked mode. 25 | #ifdef DEBUG 26 | int Level; 27 | #endif 28 | 29 | PKTHREAD OwnerThread; 30 | 31 | LIST_ENTRY MutexListEntry; 32 | } 33 | KMUTEX, *PKMUTEX; 34 | 35 | void KeInitializeMutex(PKMUTEX Mutex, int Level); 36 | 37 | int KeReadStateMutex(PKMUTEX Mutex); 38 | 39 | void KeReleaseMutex(PKMUTEX Mutex); 40 | 41 | // Locking a mutex is done by waiting on it. 42 | -------------------------------------------------------------------------------- /boron/include/ke/process.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/process.h 7 | 8 | Abstract: 9 | This header file defines the kernel process object 10 | and its manipulation functions. 11 | 12 | Author: 13 | iProgramInCpp - 22 November 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | typedef struct KPROCESS_tag KPROCESS, *PKPROCESS; 21 | 22 | struct KPROCESS_tag 23 | { 24 | // Dispatch object header. 25 | KDISPATCH_HEADER Header; 26 | 27 | // Pointer to common address map 28 | HPAGEMAP PageMap; 29 | 30 | // List of child threads 31 | LIST_ENTRY ThreadList; 32 | 33 | // Total accumulated time for all threads 34 | uint64_t AccumulatedTime; 35 | 36 | // Default thread priority 37 | int DefaultPriority; 38 | 39 | // Default thread affinity 40 | KAFFINITY DefaultAffinity; 41 | }; 42 | 43 | // Allocate an uninitialized process instance. Use when you want to detach the process. 44 | PKPROCESS KeAllocateProcess(); 45 | 46 | // Get the system process. 47 | PKPROCESS KeGetSystemProcess(); 48 | 49 | // Deallocate a process allocated with KeAllocateProcess. 50 | void KeDeallocateProcess(PKPROCESS Process); 51 | 52 | // Initialize the process. 53 | void KeInitializeProcess(PKPROCESS Process, int BasePriority, KAFFINITY BaseAffinity); 54 | 55 | // Attach to or detach from a process, on behalf of the current thread. 56 | // 57 | // If Process is NULL, the thread is detached from any process 58 | // it was attached to, and the active address space will be the 59 | // address space of the host process. 60 | PKPROCESS KeSetAttachedProcess(PKPROCESS Process); 61 | 62 | // Get a pointer to the current process. 63 | PKPROCESS KeGetCurrentProcess(); 64 | -------------------------------------------------------------------------------- /boron/include/ke/sched.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/sched.h 7 | 8 | Abstract: 9 | This header file contains the scheduler object and 10 | its manipulation functions. 11 | 12 | Author: 13 | iProgramInCpp - 7 October 2023 14 | ***/ 15 | #ifndef BORON_KE_SCHED_H 16 | #define BORON_KE_SCHED_H 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #define QUEUE_BIT(x) (1U << (x)) 25 | typedef uint32_t QUEUE_MASK; 26 | 27 | enum 28 | { 29 | // The idle priority class has just one spot. 30 | PRIORITY_IDLE = 0, 31 | 32 | // The low priority class has 7 spots. 33 | PRIORITY_LOW = 1, 34 | PRIORITY_LOW_MAX = 7, 35 | 36 | // The normal priority class has 12 spots. 37 | PRIORITY_NORMAL = 8, 38 | PRIORITY_NORMAL_MAX = 19, 39 | 40 | // The high priority class has 7 spots. 41 | PRIORITY_HIGH = 20, 42 | PRIORITY_HIGH_MAX = 26, 43 | 44 | // The realtime priority class has 5 spots. 45 | PRIORITY_REALTIME = 27, 46 | PRIORITY_REALTIME_MAX = 31, 47 | 48 | PRIORITY_COUNT = 32, 49 | }; 50 | 51 | typedef struct 52 | { 53 | 54 | // Execution queue mask. If a bit is set, that means that a thread 55 | // of the priority corresponding to that bit exists in the queue. 56 | QUEUE_MASK ExecQueueMask; 57 | 58 | LIST_ENTRY ExecQueue[PRIORITY_COUNT]; 59 | 60 | PKTHREAD CurrentThread; 61 | PKTHREAD NextThread; 62 | 63 | PKTHREAD IdleThread; 64 | 65 | RBTREE TimerTree; 66 | 67 | void* IdleThreadStackTop; 68 | 69 | int ThreadsOnQueueCount; 70 | 71 | uint64_t TicksSpentNonIdle; 72 | 73 | // in ticks, copy of CurrentThread->QuantumUntil unless 74 | // CurrentThread is null, in which case it's zero 75 | uint64_t QuantumUntil; 76 | } 77 | KSCHEDULER, *PKSCHEDULER; 78 | 79 | void KeSetPriorityThread(PKTHREAD Thread, int Priority); 80 | 81 | void KeSchedulerInitUP(); 82 | 83 | void KeSchedulerInit(); 84 | 85 | NO_RETURN void KeSchedulerCommit(); 86 | 87 | void KeTimerTick(); 88 | 89 | #endif//BORON_KE_SCHED_H 90 | -------------------------------------------------------------------------------- /boron/include/ke/semaphor.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/semaphor.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | semaphore dispatch object. 11 | 12 | Author: 13 | iProgramInCpp - 18 November 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | typedef struct KSEMAPHORE_tag 20 | { 21 | KDISPATCH_HEADER Header; 22 | 23 | int Limit; 24 | } 25 | KSEMAPHORE, *PKSEMAPHORE; 26 | 27 | #define ASSERT_SEMAPHORE(Semaphore) ASSERT((Semaphore)->Header.Type == DISPATCH_SEMAPHORE) 28 | #define SEMAPHORE_LIMIT_NONE (0x7FFFFFFE) 29 | 30 | void KeInitializeSemaphore(PKSEMAPHORE Semaphore, int Count, int Limit); 31 | 32 | // Returns the current state of the semaphore. 33 | // If zero, the semaphore is not signaled. 34 | int KeReadStateSemaphore(PKSEMAPHORE Semaphore); 35 | 36 | void KeReleaseSemaphore(PKSEMAPHORE Semaphore, int Adjustment, KPRIORITY Increment); 37 | -------------------------------------------------------------------------------- /boron/include/ke/smp.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/smp.h 7 | 8 | Abstract: 9 | This header file contains the definitions related 10 | to the SMP part of the kernel core. 11 | 12 | Author: 13 | iProgramInCpp - 28 October 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | NO_RETURN void KeInitSMP(void); 20 | void KeInitArchUP(); 21 | void KeInitArchMP(); 22 | -------------------------------------------------------------------------------- /boron/include/ke/stats.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/stats.h 7 | 8 | Abstract: 9 | This header file contains the statistics object and 10 | manipulation functions for it. 11 | 12 | Author: 13 | iProgramInCpp - 14 October 2023 14 | ***/ 15 | #ifndef BORON_KE_STATS_H 16 | #define BORON_KE_STATS_H 17 | 18 | // Note. This object is global, that means there's one single 19 | // instance of this object at a time and you should use atomic 20 | // writes to write to the statistics object. 21 | typedef struct KSTATISTICS_tag 22 | { 23 | int ContextSwitches; 24 | } 25 | KSTATISTICS, *PKSTATISTICS; 26 | 27 | // Modify 28 | void KeStatsAddContextSwitch(); 29 | 30 | 31 | // Read 32 | int KeStatsGetContextSwitchCount(); 33 | 34 | #endif//BORON_KE_STATS_H -------------------------------------------------------------------------------- /boron/include/ke/timer.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/timer.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | timer dispatch object. 11 | 12 | Author: 13 | iProgramInCpp - 30 October 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | typedef struct KTIMER_tag 20 | { 21 | KDISPATCH_HEADER Header; 22 | 23 | RBTREE_ENTRY EntryTree; // Entry in the global timer tree 24 | 25 | uint64_t ExpiryTick; // Time at which the timer expires 26 | 27 | bool IsEnqueued; 28 | 29 | PKDPC Dpc; // DPC to be enqueued when timer is due 30 | } 31 | KTIMER, *PKTIMER; 32 | 33 | #define ASSERT_TIMER(Timer) ASSERT((Timer)->Header.Type == DISPATCH_TIMER) 34 | 35 | void KeInitializeTimer(PKTIMER Timer); 36 | 37 | bool KeCancelTimer(PKTIMER Timer); 38 | 39 | bool KeReadStateTimer(PKTIMER Timer); 40 | 41 | bool KeSetTimer(PKTIMER Timer, uint64_t DueTimeMs, PKDPC Dpc); 42 | 43 | #ifdef KERNEL 44 | // Internal version of KiSetTimer that must be run with the dispatcher 45 | // locked (such as in a DPC, or in an internal dispatcher function) 46 | bool KiSetTimer(PKTIMER Timer, uint64_t DueTimeMs, PKDPC Dpc); 47 | 48 | // Ditto with KeCancelTimer. 49 | bool KiCancelTimer(PKTIMER Timer); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /boron/include/ke/types.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023-2024 iProgramInCpp 4 | 5 | Module name: 6 | ke/types.h 7 | 8 | Abstract: 9 | This header file defines basic types used throughout ke.h. 10 | 11 | Author: 12 | iProgramInCpp - 23 November 2023 13 | ***/ 14 | #pragma once 15 | 16 | // TODO: Define as uint32_t on 32-bit architectures. 17 | typedef uint64_t KAFFINITY; 18 | 19 | // Note. We define it as a qword, and cast it down later if needed. 20 | #define AFFINITY_ALL ((KAFFINITY) ~0ULL) 21 | 22 | typedef int KPRIORITY; 23 | -------------------------------------------------------------------------------- /boron/include/ke/ver.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/ver.h 7 | 8 | Abstract: 9 | This header file contains the definitions 10 | related to the versioning of the operating system. 11 | 12 | Author: 13 | iProgramInCpp - 28 October 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | int KeGetVersionNumber(); 20 | -------------------------------------------------------------------------------- /boron/include/ke/wait.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/wait.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | available wait operations. 11 | 12 | Author: 13 | iProgramInCpp - 11 November 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | // Wait for multiple objects at once. 20 | // Use a value of zero to poll the objects. 21 | // Use a value of TIMEOUT_INFINITE to specify that timeout isn't needed. 22 | int KeWaitForMultipleObjects( 23 | int Count, 24 | void* Objects[], 25 | int WaitType, 26 | bool Alertable, 27 | int TimeoutMS, 28 | PKWAIT_BLOCK WaitBlockArray, 29 | KPROCESSOR_MODE WaitMode); 30 | 31 | // Wait for a single object. 32 | int KeWaitForSingleObject(void* Object, bool Alertable, int TimeoutMS, KPROCESSOR_MODE WaitMode); 33 | -------------------------------------------------------------------------------- /boron/include/ldr.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ldr.h 7 | 8 | Abstract: 9 | This header file contains the definitions 10 | related to the DLL loader. 11 | 12 | Author: 13 | iProgramInCpp - 22 October 2023 14 | ***/ 15 | #ifndef NS64_LDR_H 16 | #define NS64_LDR_H 17 | 18 | #include 19 | #include 20 | 21 | typedef struct limine_file LIMINE_FILE, *PLIMINE_FILE; 22 | 23 | typedef int(*PDLL_ENTRY_POINT)(PDRIVER_OBJECT DriverObject); 24 | 25 | typedef struct 26 | { 27 | const char* Name; // should be == LimineFile->path 28 | PLIMINE_FILE LimineFile; 29 | uintptr_t ImageBase; 30 | size_t ImageSize; 31 | PDLL_ENTRY_POINT EntryPoint; 32 | const char* StringTable; 33 | void* SymbolTable; 34 | size_t SymbolTableSize; 35 | PDRIVER_OBJECT DriverObject; 36 | } 37 | LOADED_DLL, *PLOADED_DLL; 38 | 39 | #ifdef KERNEL 40 | extern LOADED_DLL KeLoadedDLLs[]; 41 | extern int KeLoadedDLLCount; 42 | #else 43 | // Expose this if needed 44 | #endif 45 | 46 | void LdrInit(); 47 | 48 | void LdrInitializeHal(); 49 | 50 | void LdrInitializeDrivers(); 51 | 52 | const char* LdrLookUpRoutineNameByAddress(PLOADED_DLL LoadedDll, uintptr_t Address, uintptr_t* BaseAddress); 53 | 54 | #ifdef KERNEL 55 | void LdrInitAfterHal(); 56 | #endif 57 | 58 | bool LdrPrepareInitialRoot(); 59 | 60 | #endif//NS64_LDR_H 61 | -------------------------------------------------------------------------------- /boron/include/limreq.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | limreq.h 7 | 8 | Abstract: 9 | This header file contains forward declarations for all Limine 10 | bootloader requests. 11 | 12 | Author: 13 | iProgramInCpp - 28 August 2023 14 | ***/ 15 | #ifndef BORON_LIMREQ_H 16 | #define BORON_LIMREQ_H 17 | 18 | #include <_limine.h> 19 | 20 | // Request IDs, for use in the HAL: 21 | enum 22 | { 23 | KLGR_NONE = 0, 24 | KLGR_HHDM, 25 | KLGR_FRAMEBUFFER, 26 | KLGR_MEMMAP, 27 | KLGR_MODULE, 28 | KLGR_RSDP, 29 | KLGR_SMP, 30 | KLGR_KERNELFILE, 31 | KLGR_COUNT, 32 | }; 33 | 34 | #ifdef KERNEL 35 | 36 | extern volatile struct limine_hhdm_request KeLimineHhdmRequest; 37 | extern volatile struct limine_framebuffer_request KeLimineFramebufferRequest; 38 | extern volatile struct limine_memmap_request KeLimineMemMapRequest; 39 | extern volatile struct limine_smp_request KeLimineSmpRequest; 40 | extern volatile struct limine_rsdp_request KeLimineRsdpRequest; 41 | extern volatile struct limine_module_request KeLimineModuleRequest; 42 | extern volatile struct limine_kernel_file_request KeLimineKernelFileRequest; 43 | 44 | #else 45 | 46 | volatile void* KeLimineGetRequest(int RequestId); 47 | 48 | #define KeLimineHhdmRequest (*(volatile struct limine_hhdm_request *)KeLimineGetRequest(KLGR_HHDM)) 49 | #define KeLimineFramebufferRequest (*(volatile struct limine_framebuffer_request*)KeLimineGetRequest(KLGR_FRAMEBUFFER)) 50 | #define KeLimineMemMapRequest (*(volatile struct limine_memmap_request *)KeLimineGetRequest(KLGR_MEMMAP)) 51 | #define KeLimineSmpRequest (*(volatile struct limine_smp_request *)KeLimineGetRequest(KLGR_SMP)) 52 | #define KeLimineRsdpRequest (*(volatile struct limine_rsdp_request *)KeLimineGetRequest(KLGR_RSDP)) 53 | #define KeLimineModuleRequest (*(volatile struct limine_module_request *)KeLimineGetRequest(KLGR_MODULE)) 54 | #define KeLimineKernelFileRequest (*(volatile struct limine_kernel_file_request*)KeLimineGetRequest(KLGR_KERNELFILE)) 55 | 56 | #endif 57 | 58 | #endif//BORON_LIMREQ_H -------------------------------------------------------------------------------- /boron/include/mm.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023-2025 iProgramInCpp 4 | 5 | Module name: 6 | mm.h 7 | 8 | Abstract: 9 | This header file includes every subsystem of the 10 | Boron Memory Manager. 11 | 12 | Author: 13 | iProgramInCpp - 28 August 2023 14 | ***/ 15 | #ifndef NS64_MM_H 16 | #define NS64_MM_H 17 | 18 | #include 19 | #include 20 | 21 | // Debug flags. Use if something's gone awry 22 | #define MM_DBG_NO_DEMAND_PAGING (0) 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #ifdef KERNEL 39 | // Initialize the allocators. 40 | void MmInitAllocators(); 41 | #endif 42 | 43 | #endif//NS64_MM_H -------------------------------------------------------------------------------- /boron/include/mm/addrnode.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | mm/addrnode.h 7 | 8 | Abstract: 9 | This header defines the address node structure. It is used by both the heap 10 | manager and the virtual address descriptor manager. 11 | 12 | Author: 13 | iProgramInCpp - 22 September 2024 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | typedef struct 20 | { 21 | union { 22 | RBTREE_ENTRY Entry; 23 | struct { 24 | // These correspond to the three rbe_link members of the tree. 25 | uintptr_t A, B, C; 26 | 27 | // The StartVa is a virtual address (not a VPN). 28 | uintptr_t StartVa; 29 | }; 30 | }; 31 | 32 | // VAD/heap node common fields 33 | 34 | // The size is represented in pages. 35 | size_t Size; 36 | } 37 | MMADDRESS_NODE, *PMMADDRESS_NODE; 38 | 39 | #define Node_EndVa(Node) ((Node)->StartVa + (Node)->Size * PAGE_SIZE) 40 | 41 | static_assert(offsetof(MMADDRESS_NODE, StartVa) == offsetof(MMADDRESS_NODE, Entry.Key), "these should be the same offset"); 42 | -------------------------------------------------------------------------------- /boron/include/mm/heap.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | mm/heap.h 7 | 8 | Abstract: 9 | This header defines the heap manager specific functions. 10 | 11 | The heap manager does the job of managing FREE address regions for 12 | user space. For the USED address region manager, see mm/vad.h. 13 | 14 | Author: 15 | iProgramInCpp - 22 September 2024 16 | ***/ 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | // The MMHEAP struct describes a tree of FREE ranges. The VAD list describes a list of USED ranges. 23 | typedef struct 24 | { 25 | RBTREE Tree; 26 | KMUTEX Mutex; 27 | size_t ItemSize; 28 | } 29 | MMHEAP, *PMMHEAP; 30 | 31 | // Initializes a heap. 32 | // 33 | // The heap manages items of size ItemSize, done this way to allow MMVADs 34 | // to be administered and dished out without reallocations. 35 | // 36 | // It initializes the heap with one free segment which starts at 37 | // InitialVa (which is a VPN), and spans InitialSize pages. 38 | void MmInitializeHeap(PMMHEAP Heap, size_t ItemSize, uintptr_t InitialVa, size_t InitialSize); 39 | 40 | // Allocates a segment of address space from the heap. This returns its MMADDRESS_NODE. 41 | // 42 | // Ways this can fail: 43 | // - If the entry needed to be split up and another MMADDRESS_NODE couldn't be allocated. 44 | // (STATUS_INSUFFICIENT_MEMORY) 45 | // - If there are no segments big enough to fit. (STATUS_INSUFFICIENT_VA_SPACE) 46 | // 47 | // Returns the MMADDRESS_NODE associated with that address, or the reason why virtual address 48 | // allocation failed. It should be reused for the VAD list. 49 | BSTATUS MmAllocateAddressSpace(PMMHEAP Heap, size_t SizePages, bool TopDown, PMMADDRESS_NODE* OutNode); 50 | 51 | // Carves out a segment of address space from the heap. This returns its MMADDRESS_NODE. 52 | // 53 | // Ways this can fail: 54 | // - If the range overlaps multiple heap nodes (STATUS_CONFLICTING_ADDRESS) 55 | // - If it overlaps a region that isn't managed by the heap (STATUS_CONFLICTING_ADDRESS) 56 | // - If the entry needed to split up the found range (up to two MMADDRESS_NODEs) couldn't be allocated 57 | // (STATUS_INSUFFICIENT_MEMORY) 58 | // 59 | // Returns the MMADDRESS_NODE associated with the address, or the reason why virtual address 60 | // allocation failed. It should be reused for the VAD list. 61 | BSTATUS MmAllocateAddressRange(PMMHEAP Heap, uintptr_t Va, size_t SizePages, PMMADDRESS_NODE* OutNode); 62 | 63 | // Returns a segment of memory back to the heap, marking it free. Does not unmap the pages 64 | // or anything like that. 65 | // 66 | // The segment passed in MUST have been REMOVED from the VAD list. 67 | BSTATUS MmFreeAddressSpace(PMMHEAP Heap, PMMADDRESS_NODE Node); 68 | 69 | // Debug dump heap. 70 | void MmDebugDumpHeap(); 71 | -------------------------------------------------------------------------------- /boron/include/mm/pfn.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | mm/pfn.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | page frame number (PFN) database. 11 | 12 | Author: 13 | iProgramInCpp - 28 September 2023 14 | ***/ 15 | #ifndef BORON_MM_PFN_H 16 | #define BORON_MM_PFN_H 17 | 18 | #include 19 | 20 | // Page frame number. 21 | // 22 | // TODO: An 'int' PFN is sufficient for now. It allows up to 16 TB 23 | // of physical memory to be represented right now, which is 1024 times 24 | // what's in my computer. But if needed, you should change this to 25 | // a uintptr_t. 26 | typedef int MMPFN, *PMMPFN; 27 | 28 | // Page frame database entry structure. 29 | // 30 | // Keep this structure's size a power of 2. 31 | typedef struct 32 | { 33 | // Flags for the specifically referenced page frame. 34 | struct 35 | { 36 | unsigned Type : 4; 37 | 38 | // Flags 39 | 40 | // If this flag is set, then, when every reference is removed from 41 | // the page frame, and it's part of a CCB, then this page is placed 42 | // on the modified page list and will be written to the referenced 43 | // file. 44 | unsigned Modified : 1; 45 | 46 | unsigned Spare : 27; 47 | }; 48 | 49 | // Disregard if this is allocated. Eventually these will be part of a union 50 | // where they will take on different roles depending on the role of the page. 51 | MMPFN NextFrame; 52 | MMPFN PrevFrame; 53 | 54 | // Disregard if this is free. Eventually this will be part of a union 55 | // where it will take on different roles depending on the role of the 56 | // page. 57 | int RefCount; 58 | 59 | // Prototype PTE. This points to the entry in an FCB's page cache, if this 60 | // page is found on the standby list. 61 | uint64_t PrototypePte; 62 | 63 | // Unused for now. 64 | uint64_t qword3; 65 | } 66 | MMPFDBE, *PMMPFDBE; 67 | 68 | #define PFN_FLAG_CAPTURED (1 << 0) 69 | 70 | enum 71 | { 72 | PF_TYPE_FREE, 73 | PF_TYPE_ZEROED, 74 | PF_TYPE_USED, 75 | PF_TYPE_RECLAIM, 76 | PF_TYPE_TRANSITION, 77 | }; 78 | 79 | #define PFN_INVALID ((MMPFN)-1) 80 | 81 | static_assert((sizeof(MMPFDBE) & (sizeof(MMPFDBE) - 1)) == 0, "The page frame struct should be a power of two"); 82 | 83 | #endif//BORON_MM_PFN_H 84 | -------------------------------------------------------------------------------- /boron/include/mm/pmm.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | mm/pmm.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | physical memory manager (PMM). 11 | 12 | Author: 13 | iProgramInCpp - 28 September 2023 14 | ***/ 15 | #ifndef BORON_MM_PMM_H 16 | #define BORON_MM_PMM_H 17 | 18 | #include 19 | 20 | #ifdef KERNEL 21 | 22 | // Initialize the physical memory manager. 23 | void MiInitPMM(void); 24 | 25 | // Reclaims the init text section. This may be performed only once. 26 | void MiReclaimInitText(); 27 | 28 | #endif 29 | 30 | // Get the base address of the HHDM (higher half direct map) 31 | uint8_t* MmGetHHDMBase(void); 32 | 33 | // Converts a physical address into an HHDM address. 34 | void* MmGetHHDMOffsetAddr(uintptr_t PhysAddr); 35 | 36 | // Converts an HHDM based address into a physical address. 37 | uintptr_t MmGetHHDMOffsetFromAddr(void* Addr); 38 | 39 | // Converts a physical address to a page frame number (PFN). 40 | MMPFN MmPhysPageToPFN(uintptr_t PhysAddr); 41 | 42 | // Converts a page frame number (PFN) to a physical page. 43 | uintptr_t MmPFNToPhysPage(MMPFN Pfn); 44 | 45 | // This returns a PFN, use MmPFNToPhysPage to convert it to 46 | // a physical address, and MmGetHHDMOffsetAddr to address into it directly 47 | MMPFN MmAllocatePhysicalPage(void); 48 | 49 | // Adds a reference to a PFN. 50 | void MmPageAddReference(MMPFN Pfn); 51 | 52 | // Assign a prototype PTE address to the page frame. 53 | void MmSetPrototypePtePfn(MMPFN Pfn, uintptr_t* PrototypePte); 54 | 55 | // This expects a PFN. Use MmPhysPageToPFN if you have a physically 56 | // addressed page to free. Decrements the reference counter of the physical page. 57 | // When zero, the page is freed from physical memory and can be used again. 58 | void MmFreePhysicalPage(MMPFN Pfn); 59 | 60 | // Same as MmAllocatePhysicalPage, but returns an HHDM based address. 61 | void* MmAllocatePhysicalPageHHDM(void); 62 | 63 | // Same as MmFreePhysicalPage, but takes in an address from MmAllocatePhysicalPageHHDM 64 | // instead of a PFN. 65 | void MmFreePhysicalPageHHDM(void* Page); 66 | 67 | // Gets the total amount of free pages. 68 | size_t MmGetTotalFreePages(); 69 | 70 | #endif//BORON_MM_PMM_H 71 | -------------------------------------------------------------------------------- /boron/include/mm/pool.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | mm/pool.h 7 | 8 | Abstract: 9 | This header file defines the pool allocator's API. 10 | 11 | Author: 12 | iProgramInCpp - 27 November 2023 13 | ***/ 14 | #pragma once 15 | 16 | typedef int POOL_TYPE; 17 | 18 | // If the allocation is not paged. 19 | #define POOL_FLAG_NON_PAGED (1 << 0) 20 | 21 | #define POOL_NONPAGED POOL_FLAG_NON_PAGED 22 | 23 | // If the pool allocation should only return the range itself, 24 | // but the range itself is unmapped 25 | #define POOL_FLAG_CALLER_CONTROLLED (1 << 1) 26 | 27 | // Redundant, could just pass 0 28 | #define POOL_PAGED (0) 29 | 30 | #define POOL_TAG(x) *((int*)x) 31 | 32 | // ******* Big Pool ******* 33 | // The big pool is a pool allocation system which returns page 34 | // aligned addresses within the pool area of memory. 35 | 36 | void* MmAllocatePoolBig(int PoolFlags, size_t PageCount, int Tag); 37 | 38 | void MmFreePoolBig(void* Address); 39 | 40 | size_t MmGetSizeFromPoolAddress(void* Address); 41 | 42 | // Maps physical memory with certain caching attributes into pool space. To free this I/O space, 43 | // simply call MmFreePoolBig. This function is thread-safe. 44 | // 45 | // The PermissionsAndCaching parameter is ORed onto the PTEs that will map this physical area. 46 | void* MmMapIoSpace(uintptr_t PhysicalAddress, size_t NumberOfPages, uintptr_t PermissionsAndCaching, int Tag); 47 | 48 | // ******* Little Pool ******* 49 | // The little pool is a pool allocation system implemented on top 50 | // of the big pool. It is backed by a slab allocator. 51 | // The little pool allocator is *guaranteed* to return QWORD aligned 52 | // addresses, but not page aligned addresses. For that, use the big pool. 53 | 54 | // Allocate pool memory. 55 | // * The POOL_FLAG_CALLER_CONTROLLED flag is not supported and will return NULL. 56 | void* MmAllocatePool(int PoolFlags, size_t Size); 57 | 58 | void MmFreePool(void* Pointer); 59 | 60 | // Shorthand function to allocate a thread's kernel stack using default parameters. 61 | FORCE_INLINE 62 | void* MmAllocateKernelStack() 63 | { 64 | return MmAllocatePoolBig(POOL_FLAG_NON_PAGED, KERNEL_STACK_SIZE / PAGE_SIZE, POOL_TAG("ThSt")); 65 | } 66 | 67 | #define MmFreeThreadStack(p) MmFreePoolBig(p) 68 | -------------------------------------------------------------------------------- /boron/include/mm/probe.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | mm/probe.h 7 | 8 | Abstract: 9 | This header file defines the high level routine for address probing. 10 | 11 | Author: 12 | iProgramInCpp - 25 November 2023 13 | ***/ 14 | #pragma once 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | // Rationale: 21 | // 22 | // It can be kind of expensive to use an MDL every time we read a non-scalar 23 | // data type from the user. Most of the time we don't need prolonged access 24 | // to the memory - in fact, the only time we really do need such access is when 25 | // finishing I/O requests, when the device driver writes the read-in data to 26 | // that memory, or writes the data to the disk from that memory. 27 | // 28 | // An MDL makes that job easy because it "pins" the pages into physical memory. 29 | // However, oftentimes it isn't necessary to keep the memory pinned for a longer 30 | // amount of time. 31 | // 32 | // Sometimes it is only necessary to have access to the memory during system 33 | // service processing. In this case, it is sufficient to perform a single probe 34 | // at the beginning, and a safe copy at the end. The idea is, even if another 35 | // thread unmaps the memory during the system service, the final safe copy will 36 | // prevent a crash from kernel mode. 37 | 38 | // Probes an address, to check if none of the specified area will cause an 39 | // invalid page fault. Does not make any attempt to remap or anything. 40 | // An MDL can be used if remapping functionality is needed. See above note 41 | // for details. 42 | BSTATUS MmProbeAddress(void* Address, size_t Length, bool ProbeWrite, KPROCESSOR_MODE AccessMode); 43 | 44 | // Performs a memory copy in a safe way. Returns an error code if 45 | // copying was interrupted by an invalid page fault. 46 | // 47 | // If VerifyDest is true, then Address is checked for validity. 48 | // Otherwise, Source is checked for validity. 49 | BSTATUS MmSafeCopy(void* Address, const void* Source, size_t Length, KPROCESSOR_MODE AccessMode, bool VerifyDest); 50 | 51 | // Check if the specified address range can be used at all. For example, on AMD64, 52 | // the area between 0x0000800000000000 and 0xFFFF7FFFFFFFFFFF is considered 53 | // noncanonical, and any attempt to access it will actually throw a #GP, not a #PF. 54 | bool MmIsAddressRangeValid(uintptr_t Address, size_t Size, KPROCESSOR_MODE AccessMode); 55 | -------------------------------------------------------------------------------- /boron/include/mm/section.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | mm/section.h 7 | 8 | Abstract: 9 | This header defines the memory manager section object. 10 | 11 | Author: 12 | iProgramInCpp - 6 September 2024 13 | ***/ 14 | #pragma once 15 | 16 | typedef struct 17 | { 18 | // TODO 19 | int X; 20 | } 21 | MMSECTION, *PMMSECTION; 22 | -------------------------------------------------------------------------------- /boron/include/mm/services.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | mm/services.h 7 | 8 | Abstract: 9 | This header defines the Boron memory manager's 10 | exposed system services. 11 | 12 | Author: 13 | iProgramInCpp - 13 March 2025 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | // Allocation Types 20 | enum 21 | { 22 | MEM_RESERVE = 0x0001, // The memory range will be reserved. 23 | MEM_COMMIT = 0x0002, // The memory range will be committed. 24 | MEM_SHARED = 0x0004, // The memory range will be shared and will be passed down in forks. 25 | MEM_TOP_DOWN = 0x0008, // Addresses near the top of the user address space are preferred. 26 | MEM_DECOMMIT = 0x0010, // The memory range will be decommitted. 27 | MEM_RELEASE = 0x0020, // The memory range will be released. 28 | MEM_COW = 0x0040, // The memory will be copied on write, instead of any writes being committed to the backing file. 29 | }; 30 | 31 | BSTATUS OSAllocateVirtualMemory( 32 | HANDLE ProcessHandle, 33 | void** BaseAddressInOut, 34 | size_t* RegionSizeInOut, 35 | int AllocationType, 36 | int Protection 37 | ); 38 | 39 | BSTATUS OSFreeVirtualMemory( 40 | HANDLE ProcessHandle, 41 | void* BaseAddress, 42 | size_t RegionSize, 43 | int FreeType 44 | ); 45 | 46 | BSTATUS OSMapViewOfObject( 47 | HANDLE ProcessHandle, 48 | HANDLE MappedObject, 49 | void** BaseAddressInOut, 50 | size_t ViewSize, 51 | int AllocationType, 52 | uint64_t SectionOffset, 53 | int Protection 54 | ); 55 | -------------------------------------------------------------------------------- /boron/include/mm/view.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | mm/view.h 7 | 8 | Abstract: 9 | This header defines function prototypes for the memory 10 | view manager. 11 | 12 | Author: 13 | iProgramInCpp - 5 April 2025 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | BSTATUS MmMapViewOfObject( 20 | HANDLE MappedObject, 21 | void** BaseAddressOut, 22 | size_t ViewSize, 23 | int AllocationType, 24 | uint64_t SectionOffset, 25 | int Protection 26 | ); 27 | 28 | BSTATUS MmMapViewOfFileInSystemSpace( 29 | PFILE_OBJECT FileObject, 30 | void** BaseAddressOut, 31 | size_t ViewSize, 32 | int AllocationType, 33 | uint64_t SectionOffset, 34 | int Protection 35 | ); 36 | 37 | void MmUnmapViewOfFileInSystemSpace(void* ViewPointer); 38 | -------------------------------------------------------------------------------- /boron/include/ps.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ps.h 7 | 8 | Abstract: 9 | This header file contains the definitions related to 10 | the Boron process management system. 11 | 12 | Author: 13 | iProgramInCpp - 26 November 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #ifdef KERNEL 25 | 26 | extern POBJECT_TYPE 27 | PsThreadObjectType, 28 | PsProcessObjectType; 29 | 30 | #else 31 | 32 | // TODO: PsGetBuiltInType, ExGetBuiltInType 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /boron/include/ps/pebteb.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ps/process.h 7 | 8 | Abstract: 9 | This header file defines the PEB structure, also known 10 | as the Process Environment Block. This structure is 11 | likely going to be one page (4 KB) long and offers 12 | information about the created process. Most of it is 13 | given through the OSSetProcessEnvironmentData() system 14 | service. 15 | 16 | It also defines the TEB (Thread Environment Block) struct 17 | created for each thread. 18 | 19 | Author: 20 | iProgramInCpp - 15 April 2025 21 | ***/ 22 | #pragma once 23 | 24 | #define MAX_COMMAND_LINE_LEN (4096) 25 | 26 | typedef struct 27 | { 28 | void *UserProcessParameters; 29 | 30 | // TODO: need anything more? 31 | } 32 | PEB, *PPEB; 33 | 34 | typedef struct 35 | { 36 | PPEB Peb; 37 | } 38 | TEB, *PTEB; 39 | -------------------------------------------------------------------------------- /boron/include/ps/process.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ps/process.h 7 | 8 | Abstract: 9 | This header file defines the EPROCESS structure, which is an 10 | extension of KPROCESS, and is exposed by the object manager. 11 | 12 | Author: 13 | iProgramInCpp - 26 November 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | typedef struct _OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; 20 | 21 | PEPROCESS PsGetSystemProcess(); 22 | 23 | // Gets the currently attached process, or if there is no 24 | // attached process, the currently running process. 25 | PEPROCESS PsGetAttachedProcess(); 26 | 27 | void PsInitSystemProcess(); 28 | 29 | bool PsInitSystem(); 30 | 31 | bool PsInitSystemPart2(); 32 | 33 | void PsAttachToProcess(PEPROCESS Process); 34 | 35 | void PsDetachFromProcess(); 36 | 37 | BSTATUS OSCreateProcess( 38 | PHANDLE OutHandle, 39 | POBJECT_ATTRIBUTES ObjectAttributes, 40 | HANDLE ParentProcessHandle, 41 | bool InheritHandles 42 | ); 43 | 44 | #ifdef KERNEL 45 | extern EPROCESS PsSystemProcess; 46 | #else 47 | #define PsSystemProcess (*PsGetSystemProcess()) 48 | #endif 49 | -------------------------------------------------------------------------------- /boron/include/ps/services.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | ps/services.h 7 | 8 | Abstract: 9 | This header file defines most of the Ps-offered 10 | system service functions. 11 | 12 | Author: 13 | iProgramInCpp - 22 April 2025 14 | ***/ 15 | #pragma once 16 | 17 | BSTATUS OSExitThread(); 18 | -------------------------------------------------------------------------------- /boron/include/ps/thread.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ps/thread.h 7 | 8 | Abstract: 9 | This header file defines the ETHREAD structure, which is an 10 | extension of KTHREAD, and is exposed by the object manager. 11 | 12 | Author: 13 | iProgramInCpp - 26 November 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | typedef struct ETHREAD_tag 20 | { 21 | KTHREAD Tcb; 22 | 23 | PEPROCESS Process; 24 | 25 | void* UserStack; 26 | 27 | size_t UserStackSize; 28 | 29 | bool Initialized; 30 | } 31 | ETHREAD, *PETHREAD; 32 | 33 | #define PsGetCurrentThread() ((PETHREAD) KeGetCurrentThread()) 34 | 35 | BSTATUS PsCreateSystemThreadFast( 36 | PETHREAD* OutThread, 37 | PKTHREAD_START StartRoutine, 38 | void* StartContext, 39 | bool CreateSuspended 40 | ); 41 | 42 | BSTATUS PsCreateSystemThread( 43 | PHANDLE OutHandle, 44 | POBJECT_ATTRIBUTES ObjectAttributes, 45 | HANDLE ProcessHandle, 46 | PKTHREAD_START StartRoutine, 47 | void* StartContext, 48 | bool CreateSuspended 49 | ); 50 | 51 | BSTATUS OSCreateThread( 52 | PHANDLE OutHandle, 53 | HANDLE ProcessHandle, 54 | POBJECT_ATTRIBUTES ObjectAttributes, 55 | PKTHREAD_START ThreadStart, 56 | void* ThreadContext, 57 | bool CreateSuspended 58 | ); 59 | 60 | // TODO: Need I do anything more? 61 | #define PsTerminateThread() KeTerminateThread(1) 62 | -------------------------------------------------------------------------------- /boron/include/string.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | string.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | runtime string library. 11 | 12 | Author: 13 | iProgramInCpp - 20 August 2023 14 | ***/ 15 | #ifndef NS64_STRING_H 16 | #define NS64_STRING_H 17 | 18 | #include 19 | 20 | // Include stb printf so we have definitions ready 21 | #define STB_SPRINTF_NOFLOAT 22 | #define STB_SPRINTF_DECORATE // don't decorate 23 | #include "_stb_sprintf.h" 24 | 25 | void* memcpy(void* dst, const void* src, size_t n); 26 | void* memquadcpy(uint64_t* dst, const uint64_t* src, size_t n); 27 | void* memset(void* dst, int c, size_t n); 28 | size_t strlen(const char * s); 29 | char* strcpy(char* s, const char * d); 30 | char* strcat(char* s, const char * src); 31 | int memcmp(const void* s1, const void* s2, size_t n); 32 | int strcmp(const char* s1, const char* s2); 33 | char* strncpy(char* d, const char* s, size_t sz); 34 | 35 | #endif//NS64_STRING_H -------------------------------------------------------------------------------- /boron/linker.ld: -------------------------------------------------------------------------------- 1 | /* Tell the linker that we want an x86_64 ELF64 output file */ 2 | OUTPUT_FORMAT(elf64-x86-64) 3 | OUTPUT_ARCH(i386:x86-64) 4 | 5 | /* We want the symbol KiSystemStartup to be our entry point */ 6 | ENTRY(KiSystemStartup) 7 | 8 | /* Define the program headers we want so the bootloader gives us the right */ 9 | /* MMU permissions */ 10 | PHDRS 11 | { 12 | text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ 13 | rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ 14 | data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ 15 | } 16 | 17 | SECTIONS 18 | { 19 | /* We want to be placed in the topmost 2GiB of the address space, for optimizations, and because that is what the Limine spec mandates. */ 20 | /* Any address in this region will do, but often 0xffffffff80000000 is chosen as that is the beginning of the region. */ 21 | . = 0xffffffff80000000; 22 | 23 | /* Define the regular text section. */ 24 | .text : { 25 | *(.text) 26 | } :text 27 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 28 | 29 | /* Define the initialization text section, which will be permanently reclaimed after system initialization. */ 30 | KiTextInitStart = .; 31 | .text.init : { 32 | *(.text.init) 33 | } :text 34 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 35 | KiTextInitEnd = .; 36 | 37 | /* Define the paged text section, which may not be resident at all times, pages may be swapped out and 38 | back in at the memory manager's discretion. */ 39 | KiTextPageStart = .; 40 | .text.page : { 41 | *(.text.page) 42 | } :text 43 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 44 | KiTextPageEnd = .; 45 | 46 | /* Glob all of the other text sections into .text. */ 47 | .text : { 48 | *(.text.*) 49 | } : text 50 | 51 | /* Move to the next memory page for .rodata */ 52 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 53 | 54 | .rodata : { 55 | *(.rodata .rodata.*) 56 | PROVIDE(KiSymbolTable = .); 57 | PROVIDE(KiSymbolTableEnd = .); 58 | } :rodata 59 | 60 | /* Move to the next memory page for .data */ 61 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 62 | 63 | /* Global constructor array. */ 64 | .init_array : { 65 | g_init_array_start = .; 66 | *(.init_array) 67 | g_init_array_end = .; 68 | } 69 | 70 | /* Global destructor array. */ 71 | .fini_array : { 72 | g_fini_array_start = .; 73 | *(.fini_array) 74 | g_fini_array_end = .; 75 | } 76 | 77 | .data : { 78 | *(.data .data.*) 79 | } :data 80 | 81 | .bss : { 82 | *(COMMON) 83 | *(.bss .bss.*) 84 | 85 | /* Hack to keep the PsSystemProcess symbol while adding an object header on top */ 86 | PROVIDE(PsSystemProcess = PspSystemProcessObject + 64); 87 | } :data 88 | 89 | /* Discard .note.* and .eh_frame since they may cause issues on some hosts. */ 90 | /DISCARD/ : { 91 | *(.eh_frame) 92 | *(.note .note.*) 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /boron/scripts/generate_symbols.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # The Boron Operating System - Copyright (C) 2023 iProgramInCpp 3 | # 4 | # This Python script generates the symbol definitions. 5 | # Note: The input piped into it MUST be the output of `nm` with the `-P` switch. 6 | 7 | import sys 8 | 9 | def SymKey(s): 10 | return s[0] # Return the address member 11 | 12 | print('; ********** The Boron Operating System **********/') 13 | print('section .rodata') 14 | print('global KiSymbolTable') 15 | print('global KiSymbolTableEnd') 16 | print('KiSymbolTable:') 17 | 18 | Names = "section .rodata\n" 19 | 20 | SymbolList = [] 21 | 22 | for Line in sys.stdin: 23 | Line = Line.rstrip() 24 | Tokens = Line.split() 25 | 26 | Name = Tokens[0] 27 | Type = Tokens[1] 28 | Address = int(Tokens[2], 16) 29 | 30 | if len(Tokens) < 4: 31 | size = 1 32 | else: 33 | Size = int(Tokens[3], 16) 34 | 35 | if Type == 'T' or Type == 't': 36 | SymbolList.append((Address, Size, Name)) 37 | 38 | SymbolList.sort(key=SymKey) 39 | 40 | Count = 0 41 | for Symbol in SymbolList: 42 | Address = Symbol[0] 43 | Size = Symbol[1] 44 | Name = Symbol[2] 45 | 46 | if Count < len(SymbolList) - 1: 47 | UpdateSize = False 48 | 49 | # Attempt to correct the size of small asm functions 50 | # that aren't aligned to sixteen bytes. Their size is reported 51 | # as bigger than it actually is for some reason 52 | if Address + Size > SymbolList[Count + 1][0]: 53 | UpdateSize = True 54 | 55 | # If the symbol has at most 15 bytes until the next symbol, 56 | # expand the size to include the padding. 57 | # Some no_return functions are missed without this fix. 58 | Thing = (Address + Size + 0xF) & 0xFFFFFFFFFFFFFFF0 59 | 60 | if Thing == SymbolList[Count + 1][0]: 61 | UpdateSize = True 62 | 63 | # TODO FIXME: If we're KiTrapCommon or siblings, update the size anyway 64 | if Name.startswith('KiTrapCommon'): 65 | UpdateSize = True 66 | 67 | if UpdateSize: 68 | Size = SymbolList[Count + 1][0] - Address 69 | 70 | 71 | print(f'dq 0x{Address:x}') 72 | print(f'dq 0x{Size:x}') 73 | print(f'dq name_{Count}') 74 | Names += f'name_{Count}: db "{Name}", 0\n' 75 | Count += 1 76 | 77 | print('KiSymbolTableEnd:') 78 | print(Names) 79 | -------------------------------------------------------------------------------- /boron/source/ex/exp.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | ex/exp.h 7 | 8 | Abstract: 9 | This header file defines private executive support data, 10 | and includes some header files that are usually included. 11 | 12 | Author: 13 | iProgramInCpp - 10 December 2023 14 | ***/ 15 | #pragma once 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #define EX_MUTEX_LEVEL 0 22 | 23 | extern POBJECT_TYPE 24 | ExMutexObjectType, 25 | ExEventObjectType, 26 | ExSemaphoreObjectType, 27 | ExTimerObjectType; 28 | 29 | bool ExpCreateMutexType(); 30 | bool ExpCreateEventType(); 31 | bool ExpCreateSemaphoreType(); 32 | bool ExpCreateTimerType(); 33 | bool ExpCreateThreadType(); 34 | bool ExpCreateProcessType(); 35 | 36 | #include 37 | -------------------------------------------------------------------------------- /boron/source/ex/init.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023-2025 iProgramInCpp 4 | 5 | Module name: 6 | ex/init.c 7 | 8 | Abstract: 9 | This module implements the initialization of the executive. 10 | The executive is defined as the non-core part of the kernel. 11 | 12 | Author: 13 | iProgramInCpp - 18 December 2023 14 | ***/ 15 | #include "exp.h" 16 | #include 17 | #include 18 | #include 19 | 20 | INIT 21 | bool ExInitSystem() 22 | { 23 | if (!ExpCreateMutexType()) 24 | return false; 25 | 26 | if (!ExpCreateEventType()) 27 | return false; 28 | 29 | #if 0 30 | if (!ExpCreateSemaphoreType()) 31 | return false; 32 | 33 | if (!ExpCreateTimerType()) 34 | return false; 35 | #endif 36 | 37 | // TODO: 38 | // After creating the process type, create the System process? 39 | // Three ways to do this: 40 | // 1. Shift all references from PsInitProcess to the new object. 41 | // 2. Make the System process a shadow of PsSystemProcess or 42 | // 3. Don't create a process object for the system at all. 43 | return true; 44 | } 45 | 46 | // This routine initializes the executive layer, that is, the part 47 | // of the kernel that's implemented on top of the kernel core. 48 | INIT 49 | NO_RETURN void ExpInitializeExecutive(UNUSED void* Context) 50 | { 51 | if (!ObInitSystem()) 52 | KeCrash("Could not initialize object manager"); 53 | 54 | if (!ExInitSystem()) 55 | KeCrash("Could not initialize executive"); 56 | 57 | if (!PsInitSystem()) 58 | KeCrash("Could not initialize process manager"); 59 | 60 | if (!IoInitSystem()) 61 | KeCrash("Could not initialize I/O manager"); 62 | 63 | if (!LdrPrepareInitialRoot()) 64 | KeCrash("Could not prepare initial root"); 65 | 66 | if (!PsInitSystemPart2()) 67 | KeCrash("Could not initialize process manager - part 2"); 68 | 69 | KeTerminateThread(0); 70 | } 71 | 72 | -------------------------------------------------------------------------------- /boron/source/ex/mutex.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | ex/mutex.c 7 | 8 | Abstract: 9 | This module implements the Mutex executive dispatch object. 10 | 11 | Author: 12 | iProgramInCpp - 9 August 2024 13 | ***/ 14 | #include "exp.h" 15 | 16 | POBJECT_TYPE ExMutexObjectType; 17 | 18 | bool ExpCreateMutexType() 19 | { 20 | OBJECT_TYPE_INFO ObjectInfo; 21 | memset (&ObjectInfo, 0, sizeof ObjectInfo); 22 | 23 | ObjectInfo.NonPagedPool = true; 24 | ObjectInfo.MaintainHandleCount = true; 25 | 26 | BSTATUS Status = ObCreateObjectType( 27 | "Mutex", 28 | &ObjectInfo, 29 | &ExMutexObjectType 30 | ); 31 | 32 | if (FAILED(Status)) 33 | { 34 | DbgPrint("Could not create Mutex type: %d", Status); 35 | return false; 36 | } 37 | 38 | return true; 39 | } 40 | 41 | BSTATUS OSReleaseMutex(HANDLE MutexHandle) 42 | { 43 | BSTATUS Status; 44 | void* MutexV; 45 | 46 | Status = ObReferenceObjectByHandle(MutexHandle, ExMutexObjectType, &MutexV); 47 | 48 | if (SUCCEEDED(Status)) 49 | { 50 | KeReleaseMutex((PKMUTEX) MutexV); 51 | ObDereferenceObject(MutexV); 52 | } 53 | 54 | return Status; 55 | } 56 | 57 | BSTATUS OSQueryMutex(HANDLE MutexHandle, int* MutexState) 58 | { 59 | if (!MutexState) 60 | return STATUS_INVALID_PARAMETER; 61 | 62 | BSTATUS Status; 63 | void* MutexV; 64 | 65 | Status = MmProbeAddress(MutexState, sizeof(int), true, KeGetPreviousMode()); 66 | if (FAILED(Status)) 67 | return Status; 68 | 69 | Status = ObReferenceObjectByHandle(MutexHandle, ExMutexObjectType, &MutexV); 70 | 71 | if (SUCCEEDED(Status)) 72 | { 73 | int State = KeReadStateMutex((PKMUTEX) MutexV); 74 | Status = MmSafeCopy(MutexState, &State, sizeof(int), KeGetPreviousMode(), true); 75 | ObDereferenceObject(MutexV); 76 | } 77 | 78 | return Status; 79 | } 80 | 81 | static BSTATUS ExpInitializeMutexObject(void* MutexV, UNUSED void* Context) 82 | { 83 | KeInitializeMutex((PKMUTEX) MutexV, EX_MUTEX_LEVEL); 84 | return STATUS_SUCCESS; 85 | } 86 | 87 | BSTATUS OSCreateMutex(PHANDLE OutHandle, POBJECT_ATTRIBUTES ObjectAttributes) 88 | { 89 | return ExCreateObjectUserCall(OutHandle, ObjectAttributes, ExMutexObjectType, sizeof(KMUTEX), ExpInitializeMutexObject, NULL, POOL_NONPAGED, false); 90 | } 91 | 92 | BSTATUS OSOpenMutex(PHANDLE OutHandle, POBJECT_ATTRIBUTES ObjectAttributes) 93 | { 94 | return ExOpenObjectUserCall(OutHandle, ObjectAttributes, ExMutexObjectType); 95 | } 96 | -------------------------------------------------------------------------------- /boron/source/hal/dbg.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | hal/dbg.c 7 | 8 | Abstract: 9 | This module implements the debug terminal functions for 10 | the AMD64 platform. 11 | 12 | Author: 13 | iProgramInCpp - 15 October 2023 14 | ***/ 15 | #include 16 | 17 | #ifdef DEBUG 18 | void DbgPrintString(const char* str); 19 | #endif 20 | 21 | void HalPrintStringDebug(const char* str) 22 | { 23 | #ifdef DEBUG 24 | DbgPrintString(str); 25 | #else 26 | (void) str; 27 | #endif 28 | } 29 | -------------------------------------------------------------------------------- /boron/source/io/driver.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | io/driver.c 7 | 8 | Abstract: 9 | This module implements the I/O Driver object type. 10 | 11 | Author: 12 | iProgramInCpp - 16 March 2024 13 | ***/ 14 | #include "iop.h" 15 | 16 | INIT 17 | bool IopInitializeDriversDir() 18 | { 19 | BSTATUS Status = ObCreateDirectoryObject( 20 | &IoDriversDir, 21 | NULL, 22 | "\\Drivers", 23 | OB_FLAG_KERNEL | OB_FLAG_PERMANENT 24 | ); 25 | 26 | if (FAILED(Status)) 27 | { 28 | DbgPrint("IO: Failed to create \\Drivers directory"); 29 | return false; 30 | } 31 | 32 | // The drivers directory is now created. 33 | // N.B. We keep a permanent reference to it at all times, will be useful. 34 | 35 | return true; 36 | } 37 | 38 | void IopDeleteDriver(void* Object) 39 | { 40 | // TODO 41 | DbgPrint("UNIMPLEMENTED: IopDeleteDriver(%p)", Object); 42 | } 43 | -------------------------------------------------------------------------------- /boron/source/io/fcb.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | io/fcb.c 7 | 8 | Abstract: 9 | This module implements the I/O manager specific part of the FCB structure. 10 | 11 | Author: 12 | iProgramInCpp - 29 June 2024 13 | ***/ 14 | #include "iop.h" 15 | 16 | PFCB IoAllocateFcb(PDEVICE_OBJECT DeviceObject, size_t ExtensionSize, bool NonPaged) 17 | { 18 | // Allocate the actual FCB object. 19 | PFCB Fcb = MmAllocatePool (NonPaged ? POOL_NONPAGED : POOL_PAGED, sizeof(FCB) + ExtensionSize); 20 | 21 | if (!Fcb) 22 | return NULL; 23 | 24 | Fcb->DeviceObject = DeviceObject; 25 | Fcb->DispatchTable = DeviceObject->DispatchTable; 26 | Fcb->ExtensionSize = ExtensionSize; 27 | 28 | MmInitializeCcb (&Fcb->PageCache); 29 | ExInitializeRwLock (&Fcb->RwLock); 30 | KeInitializeSpinLock (&Fcb->ViewCacheLock); 31 | 32 | return Fcb; 33 | } 34 | 35 | void IoFreeFcb(PFCB Fcb) 36 | { 37 | ExDeinitializeRwLock(&Fcb->RwLock); 38 | 39 | MmFreePool(Fcb); 40 | } 41 | 42 | void IoDereferenceFcb(PFCB Fcb) 43 | { 44 | IO_DEREFERENCE_METHOD DerefMethod = Fcb->DispatchTable->Dereference; 45 | 46 | if (DerefMethod) 47 | DerefMethod(Fcb); 48 | } 49 | -------------------------------------------------------------------------------- /boron/source/io/iop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | typedef struct 11 | { 12 | uint8_t BootIndicator; 13 | uint8_t StartCHS[3]; // unused by Boron 14 | uint8_t PartTypeDesc; 15 | uint8_t EndCHS[3]; // unused by Boron 16 | uint32_t StartLBA; 17 | uint32_t PartSizeSectors; 18 | } 19 | PACKED 20 | MBR_PARTITION, *PMBR_PARTITION; 21 | 22 | // Master Boot Record 23 | typedef struct 24 | { 25 | uint8_t BootloaderCode [446]; 26 | MBR_PARTITION Partitions[4]; 27 | uint16_t BootSignature; // must be 0xAA55 28 | } 29 | PACKED 30 | MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD; 31 | 32 | #define MBR_BOOT_SIGNATURE 0xAA55 33 | 34 | #define IOSB_STATUS(iosb, stat) (iosb->Status = stat) 35 | 36 | extern POBJECT_TYPE IoDriverType, IoDeviceType, IoFileType; 37 | 38 | // Driver object operations 39 | void IopDeleteDriver(void* Object); 40 | 41 | // Device object operations 42 | void IopDeleteDevice(void* Object); 43 | BSTATUS IopParseDevice(void* Object, const char** Name, void* Context, int LoopCount, void** OutObject); 44 | 45 | // Controller object operations 46 | void IopDeleteController(void* Object); 47 | 48 | // File object operations 49 | BSTATUS IopOpenFile(void* Object, UNUSED int HandleCount, UNUSED OB_OPEN_REASON OpenReason); 50 | void IopDeleteFile(void* Object); 51 | void IopCloseFile(void* Object, int HandleCount); 52 | BSTATUS IopParseFile(void* Object, const char** Name, void* Context, int LoopCount, void** OutObject); 53 | 54 | bool IopInitializeDevicesDir(); 55 | bool IopInitializeDriversDir(); 56 | bool IopInitializeDeviceType(); 57 | bool IopInitializeDriverType(); 58 | bool IopInitializeFileType(); 59 | 60 | // Create a file object. This doesn't actually open the object. 61 | BSTATUS IopCreateFileObject(PFCB Fcb, PFILE_OBJECT* OutObject, uint32_t Flags, uint32_t OpenFlags); 62 | 63 | BSTATUS IopCreateDeviceFileObject(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT* OutObject, uint32_t Flags, uint32_t OpenFlags); 64 | 65 | // Initializes the partition manager mutexes. 66 | void IopInitPartitionManager(); 67 | 68 | // Initializes the partition driver object. 69 | void IopInitializePartitionDriverObject(); 70 | 71 | // Scans for file systems. 72 | void IoScanForFileSystems(); 73 | 74 | // Create a partition from a block device. 75 | BSTATUS IoCreatePartition(PDEVICE_OBJECT* OutDevice, PDEVICE_OBJECT InDevice, uint64_t Offset, uint64_t Size, size_t Number); 76 | -------------------------------------------------------------------------------- /boron/source/ke/amd64/archi.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/amd64/archi.h 7 | 8 | Abstract: 9 | This header file contains the internal definitions for 10 | the "Architecture" component of the kernel core. 11 | 12 | Author: 13 | iProgramInCpp - 28 October 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | extern 20 | int KiVectorCrash, 21 | KiVectorTlbShootdown, 22 | KiVectorDpcIpi; 23 | 24 | PKREGISTERS KiHandleApcIpi(PKREGISTERS Regs); 25 | PKREGISTERS KiHandleDpcIpi(PKREGISTERS Regs); 26 | PKREGISTERS KiHandleCrashIpi(PKREGISTERS Regs); 27 | PKREGISTERS KiHandleTlbShootdownIpi(PKREGISTERS Regs); 28 | PKREGISTERS KiHandleTlbShootdownIpiA(PKREGISTERS Regs); 29 | 30 | void KiInitializeInterruptSystem(); 31 | -------------------------------------------------------------------------------- /boron/source/ke/amd64/init.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/amd64/init.c 7 | 8 | Abstract: 9 | This module implements the architecture specific UP-init 10 | and MP-init routines. 11 | 12 | Author: 13 | iProgramInCpp - 27 October 2023 14 | ***/ 15 | #include 16 | #include 17 | #include "archi.h" 18 | 19 | int KiVectorCrash, 20 | KiVectorTlbShootdown; 21 | 22 | // Used by drivers. The kernel uses the values directly. 23 | int KeGetSystemInterruptVector(int Number) 24 | { 25 | switch (Number) 26 | { 27 | case KGSIV_NONE: 28 | default: return 0; 29 | case KGSIV_CRASH: return KiVectorCrash; 30 | case KGSIV_TLB_SHOOTDOWN: return KiVectorTlbShootdown; 31 | } 32 | } 33 | 34 | void KiSetupIdt(); 35 | 36 | INIT 37 | void KeInitArchUP() 38 | { 39 | KiSetupIdt(); 40 | 41 | // Initialize interrupt vectors for certain things 42 | KiVectorCrash = KeAllocateInterruptVector(IPL_NOINTS); 43 | KiVectorTlbShootdown = KeAllocateInterruptVector(IPL_NOINTS); 44 | 45 | KeRegisterInterrupt(KiVectorTlbShootdown, KiHandleTlbShootdownIpiA); 46 | KeRegisterInterrupt(KiVectorCrash, KiHandleCrashIpi); 47 | 48 | KiInitializeInterruptSystem(); 49 | } 50 | 51 | INIT 52 | void KeInitArchMP() 53 | { 54 | KeInitCPU(); 55 | KeLowerIPL(IPL_NORMAL); 56 | HalInitSystemMP(); 57 | } 58 | -------------------------------------------------------------------------------- /boron/source/ke/amd64/intlist.inc: -------------------------------------------------------------------------------- 1 | ; 2 | ; The Boron Operating System 3 | ; Copyright (C) 2023 iProgramInCpp 4 | ; 5 | ; Module name: 6 | ; ke/amd64/intlist.inc 7 | ; 8 | ; Abstract: 9 | ; This is a define file. It is used to loop through all 10 | ; 256 interrupt vectors through the macro INT,2 in a way 11 | ; that doesn't repeat itself too much. 12 | ; 13 | ; Author: 14 | ; iProgramInCpp - 27 October 2023 15 | ; 16 | 17 | INT 00, N 18 | INT 01, N 19 | INT 02, N 20 | INT 03, N 21 | INT 04, N 22 | INT 05, N 23 | INT 06, N 24 | INT 07, N 25 | INT 08, Y 26 | INT 09, N 27 | INT 0A, Y 28 | INT 0B, Y 29 | INT 0C, Y 30 | INT 0D, Y 31 | INT 0E, Y 32 | INT 0F, N 33 | INT 10, N 34 | INT 11, Y 35 | INT 12, N 36 | INT 13, N 37 | INT 14, N 38 | INT 15, N 39 | INT 16, N 40 | INT 17, Y 41 | INT 18, N 42 | INT 19, N 43 | INT 1A, N 44 | INT 1B, Y 45 | INT 1C, Y 46 | INT 1D, N 47 | INT 1E, N 48 | INT 1F, N 49 | 50 | %macro INTGRP 1 51 | INT %{1}0, N 52 | INT %{1}1, N 53 | INT %{1}2, N 54 | INT %{1}3, N 55 | INT %{1}4, N 56 | INT %{1}5, N 57 | INT %{1}6, N 58 | INT %{1}7, N 59 | INT %{1}8, N 60 | INT %{1}9, N 61 | INT %{1}A, N 62 | INT %{1}B, N 63 | INT %{1}C, N 64 | INT %{1}D, N 65 | INT %{1}E, N 66 | INT %{1}F, N 67 | %endmacro 68 | 69 | INTGRP 2 70 | INTGRP 3 71 | INTGRP 4 72 | INTGRP 5 73 | INTGRP 6 74 | INTGRP 7 75 | INTGRP 8 76 | INTGRP 9 77 | INTGRP A 78 | INTGRP B 79 | INTGRP C 80 | INTGRP D 81 | INTGRP E 82 | INTGRP F 83 | 84 | %unmacro INTGRP 1 85 | -------------------------------------------------------------------------------- /boron/source/ke/amd64/pio.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/amd64/pio.c 7 | 8 | Abstract: 9 | This module implements x86 specific Port I/O functions. 10 | 11 | Author: 12 | iProgramInCpp - 7 September 2023 13 | ***/ 14 | #include 15 | 16 | uint8_t KePortReadByte(uint16_t portNo) 17 | { 18 | uint8_t rv; 19 | ASM("inb %1, %0" : "=a" (rv) : "dN" (portNo)); 20 | return rv; 21 | } 22 | 23 | void KePortWriteByte(uint16_t portNo, uint8_t data) 24 | { 25 | ASM("outb %0, %1"::"a"((uint8_t)data),"Nd"((uint16_t)portNo)); 26 | } 27 | 28 | uint16_t KePortReadWord(uint16_t portNo) 29 | { 30 | uint16_t rv; 31 | ASM("inw %1, %0" : "=a" (rv) : "dN" (portNo)); 32 | return rv; 33 | } 34 | 35 | void KePortWriteWord(uint16_t portNo, uint16_t data) 36 | { 37 | ASM("outw %0, %1"::"a"((uint16_t)data),"Nd"((uint16_t)portNo)); 38 | } 39 | 40 | 41 | uint32_t KePortReadDword(uint16_t portNo) 42 | { 43 | uint32_t rv; 44 | ASM("inl %1, %0" : "=a" (rv) : "dN" (portNo)); 45 | return rv; 46 | } 47 | 48 | void KePortWriteDword(uint16_t portNo, uint32_t data) 49 | { 50 | ASM("outl %0, %1"::"a"((uint32_t)data),"Nd"((uint16_t)portNo)); 51 | } 52 | -------------------------------------------------------------------------------- /boron/source/ke/amd64/thredsup.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/amd64/thredsup.c 7 | 8 | Abstract: 9 | This module implements the architecture specific 10 | thread state setup routine. 11 | 12 | Author: 13 | iProgramInCpp - 9 October 2023 14 | ***/ 15 | #include 16 | #include 17 | #include 18 | 19 | NO_RETURN void KiThreadEntryPoint(); 20 | 21 | void KiSetupRegistersThread(PKTHREAD Thread) 22 | { 23 | // Subtract 10 from the stack pointer to keep the final stack frame valid. 24 | uintptr_t StackBottom = ((uintptr_t) Thread->Stack.Top + (uintptr_t) Thread->Stack.Size - 0x10) & ~0xF; 25 | 26 | uint64_t* StackPointer = (uint64_t*) StackBottom; 27 | 28 | *(--StackPointer) = (uint64_t) KiThreadEntryPoint; // Set return address 29 | *(--StackPointer) = 0x200; // Set IF when entering the thread 30 | *(--StackPointer) = 0; // Set RBP 31 | *(--StackPointer) = (uint64_t) Thread->StartRoutine; // Set RBX 32 | *(--StackPointer) = (uint64_t) Thread->StartContext; // Set R12 33 | *(--StackPointer) = 0; // Set R13 34 | *(--StackPointer) = 0; // Set R14 35 | *(--StackPointer) = 0; // Set R15 36 | 37 | Thread->StackPointer = StackPointer; 38 | } 39 | -------------------------------------------------------------------------------- /boron/source/ke/amd64/traplist.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; The Boron Operating System 3 | ; Copyright (C) 2023 iProgramInCpp 4 | ; 5 | ; Module name: 6 | ; ke/amd64/trap.asm 7 | ; 8 | ; Abstract: 9 | ; This module contains the implementation for each of the 10 | ; individual trap handlers, which call into the common 11 | ; trap handler. 12 | ; 13 | ; Author: 14 | ; iProgramInCpp - 27 October 2023 15 | ; 16 | bits 64 17 | section .text 18 | 19 | ; NOTE: This uses 5120 bytes of data. Is that bad? I don't know. 20 | 21 | ; Arguments: 22 | ; 0 - Interrupt number in hexadecimal 23 | ; 1 - If the interrupt has an error code, Y, otherwise, N 24 | ; %macro INT 2 25 | 26 | extern KiTrapCommon 27 | 28 | %macro INT 2 29 | global KiTestTrap%1 30 | KiTestTrap%1: 31 | %ifidn %2, N 32 | push qword 0 ; Push a fake error code 33 | %endif 34 | push qword 0x%1 ; Push the interrupt number 35 | jmp KiTrapCommon ; Jump to the common trap handler 36 | %endmacro 37 | 38 | %include "ke/amd64/intlist.inc" 39 | 40 | %unmacro INT 2 41 | 42 | %macro INT 2 43 | extern KiTestTrap%1 44 | %endmacro 45 | %include "ke/amd64/intlist.inc" 46 | %unmacro INT 2 47 | 48 | 49 | section .rodata 50 | 51 | global KiTrapList 52 | KiTrapList: 53 | %macro INT 2 54 | dq KiTestTrap%1 55 | %endmacro 56 | %include "ke/amd64/intlist.inc" 57 | %unmacro INT 2 58 | -------------------------------------------------------------------------------- /boron/source/ke/crash.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/crash.c 7 | 8 | Abstract: 9 | This module contains the crash handler thunk. 10 | Its job is to format the message and invoke the HAL 11 | to perform the crash itself. 12 | 13 | Author: 14 | iProgramInCpp - 16 September 2023 15 | ***/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | extern bool KiSmpInitted; 23 | 24 | void KeCrash(const char* message, ...) 25 | { 26 | if (!KiSmpInitted) { 27 | KeCrashBeforeSMPInit("called KeCrash before SMP init?! (message: %s, RA: %p)", message, __builtin_return_address(0)); 28 | } 29 | 30 | // format the message 31 | va_list va; 32 | va_start(va, message); 33 | char buffer[1024]; // may be a beefier message than a garden variety LogMsg 34 | buffer[sizeof buffer - 3] = 0; 35 | int chars = vsnprintf(buffer, sizeof buffer - 3, message, va); 36 | strcpy(buffer + chars, "\n"); 37 | va_end(va); 38 | 39 | HalCrashSystem(buffer); 40 | } 41 | 42 | extern KSPIN_LOCK KiPrintLock; 43 | extern KSPIN_LOCK KiDebugPrintLock; 44 | 45 | void KeCrashConclusion(const char* Message) 46 | { 47 | static char CrashBuffer[4096]; 48 | 49 | // NOTE: We are running in a single processor context - all other processors were shut down 50 | KiPrintLock.Locked = 0; 51 | KiDebugPrintLock.Locked = 0; 52 | 53 | snprintf(CrashBuffer, sizeof CrashBuffer, "\n\x1B[91m*** STOP (CPU %u): \x1B[0m %s\n", KeGetCurrentPRCB()->LapicId, Message); 54 | 55 | HalDisplayString(CrashBuffer); 56 | 57 | #ifdef DEBUG 58 | DbgPrintString(CrashBuffer); 59 | #endif 60 | 61 | // List each loaded DLL's base 62 | LogMsg("Dll Base Name"); 63 | for (int i = 0; i < KeLoadedDLLCount; i++) 64 | { 65 | PLOADED_DLL LoadedDll = &KeLoadedDLLs[i]; 66 | 67 | LogMsg("%p %s", LoadedDll->ImageBase, LoadedDll->Name); 68 | } 69 | 70 | LogMsg("\n"); 71 | 72 | DbgPrintStackTrace(0); 73 | 74 | // Now that all that's done, HALT! 75 | KeStopCurrentCPU(); 76 | } 77 | -------------------------------------------------------------------------------- /boron/source/ke/init.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/init.c 7 | 8 | Abstract: 9 | This module implements the system startup function. 10 | 11 | Author: 12 | iProgramInCpp - 28 August 2023 13 | ***/ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "ki.h" 21 | #include 22 | 23 | // The entry point to our kernel. 24 | NO_RETURN INIT 25 | void KiSystemStartup(void) 26 | { 27 | DbgInit(); 28 | MiInitPMM(); 29 | MmInitAllocators(); 30 | KeSchedulerInitUP(); 31 | KeInitArchUP(); 32 | LdrInit(); 33 | LdrInitializeHal(); 34 | HalInitSystemUP(); 35 | LdrInitAfterHal(); 36 | KeInitSMP(); // no return 37 | } 38 | -------------------------------------------------------------------------------- /boron/source/ke/limreq.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/limreq.c 7 | 8 | Abstract: 9 | This module contains the list of Limine bootloader requests. 10 | 11 | Author: 12 | iProgramInCpp - 23 September 2023 13 | ***/ 14 | #include 15 | #include <_limine.h> 16 | #include 17 | 18 | volatile struct limine_hhdm_request KeLimineHhdmRequest = 19 | { 20 | .id = LIMINE_HHDM_REQUEST, 21 | .revision = 0, 22 | .response = NULL, 23 | }; 24 | volatile struct limine_framebuffer_request KeLimineFramebufferRequest = 25 | { 26 | .id = LIMINE_FRAMEBUFFER_REQUEST, 27 | .revision = 0, 28 | .response = NULL, 29 | }; 30 | volatile struct limine_memmap_request KeLimineMemMapRequest = 31 | { 32 | .id = LIMINE_MEMMAP_REQUEST, 33 | .revision = 0, 34 | .response = NULL, 35 | }; 36 | volatile struct limine_module_request KeLimineModuleRequest = 37 | { 38 | .id = LIMINE_MODULE_REQUEST, 39 | .revision = 0, 40 | .response = NULL, 41 | }; 42 | volatile struct limine_smp_request KeLimineSmpRequest = 43 | { 44 | .id = LIMINE_SMP_REQUEST, 45 | .revision = 0, 46 | .response = NULL, 47 | .flags = 0, 48 | }; 49 | volatile struct limine_rsdp_request KeLimineRsdpRequest = 50 | { 51 | .id = LIMINE_RSDP_REQUEST, 52 | .revision = 0, 53 | .response = NULL, 54 | }; 55 | volatile struct limine_kernel_file_request KeLimineKernelFileRequest = 56 | { 57 | .id = LIMINE_KERNEL_FILE_REQUEST, 58 | .revision = 0, 59 | .response = NULL, 60 | }; 61 | 62 | // NOTE: Requesting the kernel file for two reasons: 63 | // - 1. It's a possibility that I'll be phasing out the existing symbol table system and 64 | // - 2. It seems like Limine unconditionally occupies bootloader reclaimable memory with the kernel file. 65 | 66 | // Note: This MUST match the order of the KLGR enum. 67 | static volatile void* const KepLimineRequestTable[] = 68 | { 69 | NULL, 70 | &KeLimineHhdmRequest, 71 | &KeLimineFramebufferRequest, 72 | &KeLimineMemMapRequest, 73 | &KeLimineSmpRequest, 74 | &KeLimineRsdpRequest, 75 | &KeLimineModuleRequest, 76 | &KeLimineKernelFileRequest, 77 | }; 78 | 79 | volatile void* KeLimineGetRequest(int RequestId) 80 | { 81 | if (RequestId <= KLGR_NONE || RequestId >= KLGR_COUNT) 82 | return NULL; 83 | 84 | return KepLimineRequestTable[RequestId]; 85 | } 86 | -------------------------------------------------------------------------------- /boron/source/ke/mode.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/mode.c 7 | 8 | Abstract: 9 | This module implements the code regarding processor 10 | execution modes. 11 | 12 | Author: 13 | iProgramInCpp - 27 November 2023 14 | ***/ 15 | #include 16 | 17 | KPROCESSOR_MODE KeGetPreviousMode() 18 | { 19 | // Only true during initialization 20 | if (!KeGetCurrentThread()) 21 | return MODE_KERNEL; 22 | 23 | return KeGetCurrentThread()->Mode; 24 | } 25 | 26 | KPROCESSOR_MODE KeSetAddressMode(KPROCESSOR_MODE NewMode) 27 | { 28 | if (!KeGetCurrentThread()) 29 | return MODE_KERNEL; 30 | 31 | KPROCESSOR_MODE OldMode = KeGetCurrentThread()->Mode; 32 | KeGetCurrentThread()->Mode = NewMode; 33 | return OldMode; 34 | } 35 | -------------------------------------------------------------------------------- /boron/source/ke/mutex.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/mutex.c 7 | 8 | Abstract: 9 | This module implements the mutex dispatcher object. 10 | 11 | Author: 12 | iProgramInCpp - 18 November 2023 13 | ***/ 14 | #include "ki.h" 15 | 16 | void KiReleaseMutex(PKMUTEX Mutex) 17 | { 18 | KiAssertOwnDispatcherLock(); 19 | 20 | if (Mutex->OwnerThread != KeGetCurrentThread()) 21 | KeCrash("KiReleaseMutex: mutex %p not owned by current thread %p", Mutex, KeGetCurrentThread()); 22 | 23 | Mutex->Header.Signaled--; 24 | 25 | if (Mutex->Header.Signaled < MUTEX_SIGNALED) 26 | KeCrash("KiReleaseMutex: mutex %p was released more than possible", Mutex); 27 | 28 | // If the thread does not own the mutex at all anymore... 29 | if (Mutex->Header.Signaled == MUTEX_SIGNALED) 30 | { 31 | // Remove this mutex from the thread's mutex list. 32 | RemoveEntryList(&Mutex->MutexListEntry); 33 | 34 | // Set the owner thread of the mutex to NULL. 35 | Mutex->OwnerThread = NULL; 36 | 37 | // Signal the mutex object (i.e. allow another thread to acquire it), if we can. 38 | KiWaitTest(&Mutex->Header, 1); 39 | } 40 | } 41 | 42 | // -------- Exposed API -------- 43 | 44 | void KeInitializeMutex(PKMUTEX Mutex, int Level) 45 | { 46 | KeInitializeDispatchHeader(&Mutex->Header, DISPATCH_MUTEX); 47 | 48 | #ifdef DEBUG 49 | Mutex->Level = Level; 50 | #endif 51 | 52 | Mutex->Header.Signaled = MUTEX_SIGNALED; 53 | 54 | Mutex->OwnerThread = NULL; 55 | } 56 | 57 | int KeReadStateMutex(PKMUTEX Mutex) 58 | { 59 | return AtLoad(Mutex->Header.Signaled); 60 | } 61 | 62 | // TODO: Add a priority boost parameter 63 | void KeReleaseMutex(PKMUTEX Mutex) 64 | { 65 | KIPL Ipl = KiLockDispatcher(); 66 | 67 | KiReleaseMutex(Mutex); 68 | 69 | KiUnlockDispatcher(Ipl); 70 | } 71 | -------------------------------------------------------------------------------- /boron/source/ke/process.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/process.c 7 | 8 | Abstract: 9 | This module implements the kernel process object. Functions 10 | to initialize, attach-to, detach-from, detach, allocate, 11 | deallocate, and get-current are provided. 12 | 13 | Author: 14 | iProgramInCpp - 23 November 2023 15 | ***/ 16 | #include "ki.h" 17 | #include 18 | 19 | void KiSwitchToAddressSpaceProcess(PKPROCESS Process) 20 | { 21 | KeSetCurrentPageTable(Process->PageMap); 22 | } 23 | 24 | void KiOnKillProcess(PKPROCESS Process) 25 | { 26 | // Process was killed. This is called from the last thread's DPC routine. 27 | // The thread's kernel stack is no longer used and we've long since switched 28 | // to a different process' address space. 29 | ASSERT(KeGetCurrentProcess() != Process); 30 | 31 | // Signal all threads that are waiting on this process. 32 | // Here it's simpler because this IS where the process is killed! 33 | Process->Header.Signaled = true; 34 | KiWaitTest(&Process->Header, 0); 35 | } 36 | 37 | // ------- Exposed API ------- 38 | 39 | PKPROCESS KeGetCurrentProcess() 40 | { 41 | return KeGetCurrentThread()->Process; 42 | } 43 | 44 | PKPROCESS KeGetSystemProcess() 45 | { 46 | return &PsGetSystemProcess()->Pcb; 47 | } 48 | 49 | PKPROCESS KeAllocateProcess() 50 | { 51 | PKPROCESS Process = MmAllocatePool(POOL_FLAG_NON_PAGED, sizeof(KPROCESS)); 52 | if (!Process) 53 | return NULL; 54 | 55 | memset(Process, 0, sizeof *Process); 56 | 57 | return Process; 58 | } 59 | 60 | void KeDeallocateProcess(PKPROCESS Process) 61 | { 62 | MmFreePool(Process); 63 | } 64 | 65 | void KeInitializeProcess(PKPROCESS Process, int BasePriority, KAFFINITY BaseAffinity) 66 | { 67 | KeInitializeDispatchHeader(&Process->Header, DISPATCH_PROCESS); 68 | 69 | Process->PageMap = MiCreatePageMapping(KeGetCurrentPageTable()); 70 | 71 | InitializeListHead(&Process->ThreadList); 72 | 73 | Process->AccumulatedTime = 0; 74 | 75 | Process->DefaultPriority = BasePriority; 76 | 77 | Process->DefaultAffinity = BaseAffinity; 78 | } 79 | 80 | PKPROCESS KeSetAttachedProcess(PKPROCESS Process) 81 | { 82 | PKTHREAD Thread = KeGetCurrentThread(); 83 | PKPROCESS OldProcess = Thread->AttachedProcess; 84 | 85 | Thread->AttachedProcess = Process; 86 | 87 | KiSwitchToAddressSpaceProcess(Process ? Process : Thread->Process); 88 | return OldProcess; 89 | } 90 | -------------------------------------------------------------------------------- /boron/source/ke/semaphor.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/semaphor.c 7 | 8 | Abstract: 9 | This module implements the kernel semaphore dispatcher 10 | object. It provides initialize, read state, and release 11 | functions. 12 | 13 | N.B. Acquiring a semaphore is done by performing a wait 14 | operation on it. 15 | 16 | Author: 17 | iProgramInCpp - 18 November 2023 18 | ***/ 19 | #include "ki.h" 20 | 21 | void KiReleaseSemaphore(PKSEMAPHORE Semaphore, int Adjustment, KPRIORITY Increment) 22 | { 23 | ASSERT(Adjustment > 0); 24 | KiAssertOwnDispatcherLock(); 25 | 26 | // Increment the signaled state of the object. 27 | Semaphore->Header.Signaled += Adjustment; 28 | 29 | if (Semaphore->Header.Signaled < 0) 30 | KeCrash("KiReleaseSemaphore: overflow"); 31 | 32 | // Assert that we are signaled. 33 | // A signal state of less than zero is a bug. 34 | ASSERT(Semaphore->Header.Signaled > 0); 35 | 36 | // Signal the object - maybe we'll wake something up. 37 | KiWaitTest(&Semaphore->Header, Increment); 38 | } 39 | 40 | // -------- Exposed API -------- 41 | 42 | void KeInitializeSemaphore(PKSEMAPHORE Semaphore, int Count, int Limit) 43 | { 44 | KeInitializeDispatchHeader(&Semaphore->Header, DISPATCH_SEMAPHORE); 45 | 46 | Semaphore->Header.Signaled = Count; 47 | 48 | Semaphore->Limit = Limit; 49 | } 50 | 51 | int KeReadStateSemaphore(PKSEMAPHORE Semaphore) 52 | { 53 | ASSERT_SEMAPHORE(Semaphore); 54 | 55 | return AtLoad(Semaphore->Header.Signaled); 56 | } 57 | 58 | void KeReleaseSemaphore(PKSEMAPHORE Semaphore, int Adjustment, KPRIORITY Increment) 59 | { 60 | ASSERT_SEMAPHORE(Semaphore); 61 | KIPL Ipl = KiLockDispatcher(); 62 | KiReleaseSemaphore(Semaphore, Adjustment, Increment); 63 | KiUnlockDispatcher(Ipl); 64 | } -------------------------------------------------------------------------------- /boron/source/ke/stats.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/stats.c 7 | 8 | Abstract: 9 | This module file implements the statistics object. 10 | 11 | Author: 12 | iProgramInCpp - 14 October 2023 13 | ***/ 14 | #include 15 | 16 | KSTATISTICS KiStatistics; 17 | 18 | void KeStatsAddContextSwitch() 19 | { 20 | AtAddFetch(KiStatistics.ContextSwitches, 1); 21 | } 22 | 23 | int KeStatsGetContextSwitchCount() 24 | { 25 | return AtLoad(KiStatistics.ContextSwitches); 26 | } 27 | -------------------------------------------------------------------------------- /boron/source/ke/stop.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/stop.c 7 | 8 | Abstract: 9 | This module implements the function to stop the current CPU. 10 | 11 | Author: 12 | iProgramInCpp - 20 August 2023 13 | ***/ 14 | 15 | #include 16 | #include 17 | 18 | // Stops the current CPU 19 | void KeStopCurrentCPU() 20 | { 21 | DISABLE_INTERRUPTS(); 22 | 23 | while (true) 24 | KeWaitForNextInterrupt(); 25 | } 26 | -------------------------------------------------------------------------------- /boron/source/ke/symbols.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ke/symbols.c 7 | 8 | Abstract: 9 | This module contains the implementation for the kernel 10 | symbol lookup routines. 11 | 12 | Author: 13 | iProgramInCpp - 24 October 2023 14 | ***/ 15 | #include 16 | #include 17 | #include 18 | 19 | // TODO: The lookups could be optimized with a sorted list and a binary search. 20 | 21 | uintptr_t DbgLookUpAddress(const char* Name) 22 | { 23 | for (PCKSYMBOL Symbol = KiSymbolTable; Symbol != KiSymbolTableEnd; Symbol++) 24 | { 25 | if (strcmp(Symbol->Name, Name) == 0) 26 | return Symbol->Address; 27 | } 28 | 29 | return 0; 30 | } 31 | 32 | const char* DbgLookUpRoutineNameByAddressExact(uintptr_t Address) 33 | { 34 | for (PCKSYMBOL Symbol = KiSymbolTable; Symbol != KiSymbolTableEnd; Symbol++) 35 | { 36 | if (Symbol->Address == Address) 37 | return Symbol->Name; 38 | } 39 | 40 | return NULL; 41 | } 42 | 43 | const char* DbgLookUpRoutineNameByAddress(uintptr_t Address, uintptr_t* BaseAddressOut) 44 | { 45 | for (PCKSYMBOL Symbol = KiSymbolTable; Symbol != KiSymbolTableEnd; Symbol++) 46 | { 47 | if (Symbol->Address <= Address && Address < Symbol->Address + Symbol->Size) 48 | { 49 | *BaseAddressOut = Symbol->Address; 50 | return Symbol->Name; 51 | } 52 | } 53 | 54 | return NULL; 55 | } 56 | -------------------------------------------------------------------------------- /boron/source/ldr/ldri.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ldr/ldri.h 7 | 8 | Abstract: 9 | This header file contains forward declarations for 10 | DLL loader internals. 11 | 12 | Author: 13 | iProgramInCpp - 22 October 2023 14 | ***/ 15 | #ifndef BORON_LDRI_H 16 | #define BORON_LDRI_H 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | void LdriLoadDll(PLIMINE_FILE File); 26 | 27 | uintptr_t LdrAllocateRange(size_t Size); 28 | 29 | #endif//BORON_LDRI_H -------------------------------------------------------------------------------- /boron/source/mm/map.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | mm/map.c 7 | 8 | Abstract: 9 | 10 | 11 | Author: 12 | iProgramInCpp - 8 September 2024 13 | ***/ 14 | #include "mi.h" 15 | 16 | // BSTATUS MmMapVirtualMemory(void* Address, size_t Length, int Protection, int Flags, HANDLE FileHandle, uint64_t Offset); 17 | // BSTATUS MmUnmapVirtualMemory(void* Address, size_t Length); 18 | 19 | //BSTATUS MmAllocateVirtualMemory(PEPROCESS Process, void* BaseAddress, 20 | 21 | -------------------------------------------------------------------------------- /boron/source/mm/reclaim.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | mm/init.c 7 | 8 | Abstract: 9 | This module implements the code that reclaims the .text.init 10 | section of the kernel for re-use. 11 | 12 | Author: 13 | iProgramInCpp - 15 August 2024 14 | ***/ 15 | #include "mi.h" 16 | 17 | extern char KiTextInitStart[]; 18 | extern char KiTextInitEnd[]; 19 | 20 | void MiReclaimInitText() 21 | { 22 | int Reclaimed = 0; 23 | 24 | MmLockKernelSpaceExclusive(); 25 | for (uintptr_t i = (uintptr_t) KiTextInitStart; i != (uintptr_t) KiTextInitEnd; i += PAGE_SIZE) 26 | { 27 | PMMPTE PtePtr = MiGetPTEPointer(MiGetCurrentPageMap(), i, false); 28 | ASSERT(PtePtr); 29 | 30 | MMPTE Pte = *PtePtr; 31 | ASSERT(Pte); 32 | 33 | // Clear the PTE. A TLB shootdown is normally not necessary because 34 | // the memory region will never be read from again. However, in debug 35 | // mode, a TLB shootdown will be performed anyway. 36 | *PtePtr = 0; 37 | 38 | MMPFN Pfn = (MMPFN)((Pte & MM_PTE_ADDRESSMASK) >> 12); 39 | MmFreePhysicalPage(Pfn); 40 | Reclaimed++; 41 | } 42 | MmUnlockKernelSpace(); 43 | 44 | #ifdef DEBUG 45 | //MmIssueTLBShootDown((uintptr_t) KiTextInitStart, ((uintptr_t)KiTextInitEnd - (uintptr_t)KiTextInitStart + PAGE_SIZE - 1) / PAGE_SIZE); 46 | #endif 47 | 48 | DbgPrint("Reclaimed %d pages from init.", Reclaimed); 49 | } 50 | -------------------------------------------------------------------------------- /boron/source/mm/teardown.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | mm/teardown.c 7 | 8 | Abstract: 9 | This module implements the memory management process 10 | teardown function. 11 | 12 | Author: 13 | iProgramInCpp - 14 April 2025 14 | ***/ 15 | #include "mi.h" 16 | 17 | void MmTearDownProcess(PEPROCESS Process) 18 | { 19 | // This thread will attach to this process to perform teardown on it. 20 | PEPROCESS ProcessRestore = PsSetAttachedProcess(Process); 21 | 22 | // Free every VAD. 23 | PRBTREE_ENTRY Entry = GetFirstEntryRbTree(&Process->VadList.Tree); 24 | do 25 | { 26 | PMMVAD Vad = CONTAINING_RECORD(Entry, MMVAD, Node.Entry); 27 | 28 | // MiDecommitVad and MiReleaseVad require the VAD list lock be 29 | // held, but they release the lock. 30 | // 31 | // The thing is, we are the ONLY thread that has the reference 32 | // to this process. As such, there is no possibility of data 33 | // races or anything nasty like that. 34 | // 35 | // As such, we can get away with just locking the VAD list twice 36 | // and having the two internal calls unlock it. 37 | 38 | MmLockVadList(); 39 | MiDecommitVad(&Process->VadList, Vad, Vad->Node.StartVa, Vad->Node.Size); 40 | 41 | MmLockVadList(); 42 | MiReleaseVad(Vad); 43 | 44 | Entry = GetFirstEntryRbTree(&Process->VadList.Tree); 45 | } 46 | while (Entry); 47 | 48 | // Free every heap item. 49 | Entry = GetFirstEntryRbTree(&Process->Heap.Tree); 50 | do 51 | { 52 | PMMADDRESS_NODE Node = CONTAINING_RECORD(Entry, MMADDRESS_NODE, Entry); 53 | 54 | // All we need to do is remove the item from the tree and free the item's memory. 55 | RemoveItemRbTree(&Process->Heap.Tree, &Node->Entry); 56 | MmFreePool(Node); 57 | 58 | Entry = GetFirstEntryRbTree(&Process->Heap.Tree); 59 | } 60 | while (Entry); 61 | 62 | MiFreeUnusedMappingLevelsInCurrentMap(0, (MM_USER_SPACE_END + 1) >> 12); 63 | 64 | #if defined(DEBUG) && defined(TARGET_AMD64) 65 | 66 | PMMPTE PteScan = MmGetHHDMOffsetAddr(Process->Pcb.PageMap); 67 | 68 | for (int i = 0; i < 256; i++) 69 | ASSERT(~PteScan[i] & MM_PTE_PRESENT); 70 | 71 | #endif 72 | 73 | if (Process->Pcb.PageMap != 0) 74 | MmFreePhysicalPage(MmPhysPageToPFN(Process->Pcb.PageMap)); 75 | 76 | PsSetAttachedProcess(ProcessRestore); 77 | } 78 | -------------------------------------------------------------------------------- /boron/source/ob/init.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ob/init.c 7 | 8 | Abstract: 9 | This module implements the initialization code for the 10 | object manager. 11 | 12 | Author: 13 | iProgramInCpp - 7 December 2023 14 | ***/ 15 | #include "obp.h" 16 | 17 | INIT 18 | bool ObpInitializeBasicMutexes() 19 | { 20 | extern KMUTEX ObpObjectTypeMutex; 21 | extern KMUTEX ObpRootDirectoryMutex; 22 | 23 | KeInitializeMutex(&ObpObjectTypeMutex, OB_MUTEX_LEVEL_OBJECT_TYPES); 24 | KeInitializeMutex(&ObpRootDirectoryMutex, OB_MUTEX_LEVEL_DIRECTORY); 25 | 26 | return true; 27 | } 28 | 29 | INIT 30 | bool ObInitSystem() 31 | { 32 | if (!ObpInitializeBasicMutexes()) 33 | return false; 34 | 35 | if (!ObpInitializeBasicTypes()) 36 | return false; 37 | 38 | if (!ObpInitializeRootDirectory()) 39 | return false; 40 | 41 | if (!ObpInitializeReaperThread()) 42 | return false; 43 | 44 | DbgPrint("Object manager was initialized successfully!"); 45 | 46 | return true; 47 | } 48 | -------------------------------------------------------------------------------- /boron/source/ob/obp.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ob/obp.h 7 | 8 | Abstract: 9 | This header file defines private object manager data, 10 | and includes some header files that are usually included. 11 | 12 | Author: 13 | iProgramInCpp - 7 December 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | #define OB_MUTEX_LEVEL_HANDLE_TABLE (1) 21 | #define OB_MUTEX_LEVEL_DIRECTORY (2) 22 | #define OB_MUTEX_LEVEL_OBJECT_TYPES (3) 23 | 24 | #define OB_MAX_LOOP (16) // Completely arbitrary 25 | 26 | extern KMUTEX ObpRootDirectoryMutex; 27 | 28 | // Private functions 29 | BSTATUS ObpAllocateObject( 30 | POBJECT_TYPE Type, 31 | size_t BodySize, 32 | void* ParseContext, 33 | int Flags, 34 | POBJECT_HEADER* OutObjectHeader 35 | ); 36 | 37 | void ObpFreeObject(POBJECT_HEADER Header); 38 | 39 | BSTATUS ObpNormalizeParentDirectoryAndName( 40 | POBJECT_DIRECTORY* ParentDirectory, 41 | const char** Name 42 | ); 43 | 44 | // NOTE: Assumes that the header is valid, that it's not part of a directory, 45 | // and that the caller checked these things before. They are checked in debug 46 | // builds, though. 47 | BSTATUS ObpAssignName( 48 | POBJECT_HEADER Header, 49 | const char* Name 50 | ); 51 | 52 | // Gets a pointer to the type of this object. 53 | static inline ALWAYS_INLINE 54 | POBJECT_TYPE ObpGetObjectType(void* Object) 55 | { 56 | return OBJECT_GET_HEADER(Object)->NonPagedObjectHeader->ObjectType; 57 | } 58 | 59 | // Performs a path lookup, returns a referenced object if found. 60 | BSTATUS ObpLookUpObjectPath( 61 | void* InitialParseObject, 62 | const char* ObjectName, 63 | POBJECT_TYPE ExpectedType, 64 | int LoopCount, 65 | int OpenFlags, 66 | void** FoundObject 67 | ); 68 | 69 | // Initialization steps 70 | bool ObpInitializeBasicMutexes(); 71 | bool ObpInitializeBasicTypes(); 72 | bool ObpInitializeRootDirectory(); 73 | bool ObpInitializeReaperThread(); 74 | 75 | // Mutexes 76 | void ObpEnterObjectTypeMutex(); 77 | void ObpLeaveObjectTypeMutex(); 78 | void ObpEnterRootDirectoryMutex(); 79 | void ObpLeaveRootDirectoryMutex(); 80 | -------------------------------------------------------------------------------- /boron/source/ps/attach.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | ps/attach.c 7 | 8 | Abstract: 9 | This module implements the process attachment mechanism. 10 | 11 | Author: 12 | iProgramInCpp - 14 April 2025 13 | ***/ 14 | #include "psp.h" 15 | 16 | PEPROCESS PsSetAttachedProcess(PEPROCESS Process) 17 | { 18 | return (PEPROCESS) KeSetAttachedProcess(&Process->Pcb); 19 | } 20 | 21 | PEPROCESS PsGetAttachedProcess() 22 | { 23 | PEPROCESS Process = (PEPROCESS) KeGetCurrentThread()->AttachedProcess; 24 | 25 | if (!Process) 26 | Process = PsGetCurrentProcess(); 27 | 28 | return Process; 29 | } 30 | -------------------------------------------------------------------------------- /boron/source/ps/psp.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ps/psp.h 7 | 8 | Abstract: 9 | This header defines private functions for Boron's 10 | process manager. 11 | 12 | Author: 13 | iProgramInCpp - 30 August 2024 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define USER_STACK_SIZE (256 * 1024) 23 | 24 | // Initial Virtual Address Range 25 | #define INITIAL_BEG_VA 0x0000000000001000 26 | #define INITIAL_END_VA 0x00007FFFFFFFF000 27 | 28 | typedef struct 29 | { 30 | void* InstructionPointer; 31 | void* UserContext; 32 | } 33 | THREAD_START_CONTEXT, *PTHREAD_START_CONTEXT; 34 | 35 | bool PsCreateThreadType(); 36 | 37 | bool PsCreateProcessType(); 38 | 39 | NO_RETURN void PspUserThreadStart(void* Context); 40 | -------------------------------------------------------------------------------- /boron/source/ps/userthrd.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | ps/userthrd.c 7 | 8 | Abstract: 9 | This module implements the user thread management 10 | stuff in Boron. 11 | 12 | Author: 13 | iProgramInCpp - 22 April 2025 14 | ***/ 15 | #include "psp.h" 16 | 17 | NO_RETURN 18 | void PspUserThreadStart(void* ContextV) 19 | { 20 | THREAD_START_CONTEXT Context; 21 | memcpy(&Context, ContextV, sizeof Context); 22 | MmFreePool(ContextV); 23 | 24 | // First, allocate the stack. 25 | void* StackAddress = NULL; 26 | size_t StackSize = USER_STACK_SIZE; 27 | BSTATUS Status = OSAllocateVirtualMemory( 28 | CURRENT_PROCESS_HANDLE, 29 | &StackAddress, 30 | &StackSize, 31 | MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, 32 | PAGE_READ | PAGE_WRITE 33 | ); 34 | 35 | ASSERT(SUCCEEDED(Status) && "TODO: What happens if this fails? Maybe should have set it up earlier?!"); 36 | 37 | PsGetCurrentThread()->UserStack = StackAddress; 38 | PsGetCurrentThread()->UserStackSize = StackSize; 39 | 40 | KeGetCurrentThread()->Mode = MODE_USER; 41 | KeDescendIntoUserMode(Context.InstructionPointer, (uint8_t*) StackAddress + StackSize, Context.UserContext); 42 | } 43 | 44 | NO_RETURN 45 | BSTATUS OSExitThread() 46 | { 47 | BSTATUS Status; 48 | 49 | // Free everything that this thread needed to allocate. 50 | 51 | // TODO: What happens if the user thread partially frees its own kernel-given stack?! 52 | // 53 | // Currently we don't allow that. 54 | Status = OSFreeVirtualMemory( 55 | CURRENT_PROCESS_HANDLE, 56 | PsGetCurrentThread()->UserStack, 57 | PsGetCurrentThread()->UserStackSize, 58 | MEM_RELEASE 59 | ); 60 | 61 | ASSERT(SUCCEEDED(Status)); 62 | 63 | (void) Status; 64 | 65 | PsTerminateThread(); 66 | } 67 | 68 | // TODO: Add OSExitProcess - exits the whole process. 69 | // It destroys every thread! 70 | -------------------------------------------------------------------------------- /boron/source/rtl/assert.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | rtl/assert.c 7 | 8 | Abstract: 9 | This module implements the handler for failed assertions 10 | in debug mode. 11 | 12 | Author: 13 | iProgramInCpp - 11 November 2023 14 | ***/ 15 | #ifdef KERNEL 16 | #include 17 | #else 18 | #include 19 | #endif 20 | 21 | #ifndef KERNEL 22 | 23 | NO_RETURN 24 | void RtlAbort() 25 | { 26 | DbgPrint("** ABORTED\n"); 27 | 28 | // TODO: 29 | //OSExitProcess(); 30 | OSExitThread(); 31 | } 32 | 33 | #endif // !KERNEL 34 | 35 | #ifdef DEBUG 36 | 37 | NO_RETURN 38 | bool RtlAssert(const char* Condition, const char* File, int Line, const char* Message) 39 | { 40 | #ifdef KERNEL 41 | KeCrash("Assertion failed: %s%s%s%s\nAt %s:%d", 42 | Condition, 43 | Message ? " (" : "", 44 | Message ? Message : "", 45 | Message ? ")" : "", 46 | File, 47 | Line); 48 | #else 49 | // TODO 50 | DbgPrint("Assertion failed: %s%s%s%s\nAt %s:%d", 51 | Condition, 52 | Message ? " (" : "", 53 | Message ? Message : "", 54 | Message ? ")" : "", 55 | File, 56 | Line); 57 | 58 | RtlAbort(); 59 | #endif 60 | } 61 | 62 | #endif // DEBUG 63 | -------------------------------------------------------------------------------- /boron/source/rtl/print.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | rtl/print.c 7 | 8 | Abstract: 9 | This module implements the platform independent part of the 10 | printing code. 11 | 12 | Author: 13 | iProgramInCpp - 20 August 2023 14 | ***/ 15 | 16 | #define STB_SPRINTF_IMPLEMENTATION // implement the stb_sprintf right here 17 | 18 | #include 19 | #include 20 | 21 | #ifdef KERNEL 22 | #include 23 | #include 24 | #else 25 | #include 26 | #endif 27 | 28 | #if defined(KERNEL) && defined(DEBUG) 29 | // TODO: Have a worker thread or service? 30 | extern KSPIN_LOCK KiPrintLock; 31 | extern KSPIN_LOCK KiDebugPrintLock; 32 | #endif 33 | 34 | void LogMsg(const char* msg, ...) 35 | { 36 | va_list va; 37 | va_start(va, msg); 38 | char buffer[512]; // should be big enough... 39 | buffer[sizeof buffer - 3] = 0; 40 | int chars = vsnprintf(buffer, sizeof buffer - 3, msg, va); 41 | strcpy(buffer + chars, "\n"); 42 | va_end(va); 43 | 44 | #ifdef KERNEL 45 | HalDisplayString(buffer); 46 | #else 47 | OSOutputDebugString(buffer, strlen(buffer)); 48 | #endif 49 | } 50 | 51 | #ifdef DEBUG 52 | 53 | void DbgPrintString(const char* str); 54 | 55 | void DbgPrint(const char* msg, ...) 56 | { 57 | va_list va; 58 | va_start(va, msg); 59 | char buffer[512]; // should be big enough... 60 | buffer[sizeof buffer - 1] = 0; 61 | int chars = vsnprintf(buffer, sizeof buffer - 1, msg, va); 62 | strcpy(buffer + chars, "\n"); 63 | va_end(va); 64 | 65 | #ifdef KERNEL 66 | // This one goes to the debug log. 67 | // Debug2 turns off the spin locks associated with the debug prints. 68 | #ifndef DEBUG2 69 | KIPL OldIpl; 70 | KeAcquireSpinLock(&KiDebugPrintLock, &OldIpl); 71 | #endif 72 | 73 | HalPrintStringDebug(buffer); 74 | #ifndef DEBUG2 75 | KeReleaseSpinLock(&KiDebugPrintLock, OldIpl); 76 | #endif 77 | 78 | #else // KERNEL 79 | // Libboron.so has a special way of printing messages. 80 | OSOutputDebugString(buffer, strlen(buffer)); 81 | #endif 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /boron/source/system_services.h: -------------------------------------------------------------------------------- 1 | // Temporary list of currently implemented system services. 2 | // This will be removed once the system service dispatch table is implemented. 3 | 4 | BSTATUS OSClose(HANDLE); 5 | BSTATUS OSWaitForSingleObject(HANDLE, bool, int); 6 | BSTATUS OSWaitForMultipleObjects(int, PHANDLE, int, bool, int); 7 | BSTATUS OSCreateMutex(PHANDLE, POBJECT_ATTRIBUTES); 8 | BSTATUS OSOpenMutex(PHANDLE, POBJECT_ATTRIBUTES); 9 | BSTATUS OSReleaseMutex(HANDLE); 10 | BSTATUS OSQueryMutex(HANDLE, int*); 11 | BSTATUS OSCreateEvent(PHANDLE, POBJECT_ATTRIBUTES, int, bool); 12 | BSTATUS OSOpenEvent(PHANDLE, POBJECT_ATTRIBUTES); 13 | BSTATUS OSSetEvent(HANDLE); 14 | BSTATUS OSResetEvent(HANDLE); 15 | BSTATUS OSPulseEvent(HANDLE); 16 | BSTATUS OSQueryEvent(HANDLE, int*); 17 | BSTATUS OSOpenFile(PHANDLE, POBJECT_ATTRIBUTES); 18 | BSTATUS OSReadFile(PIO_STATUS_BLOCK, HANDLE, void*, size_t, uint32_t); 19 | 20 | 21 | -------------------------------------------------------------------------------- /boron/structure.md: -------------------------------------------------------------------------------- 1 | ## The Project Structure of The BORON Kernel 2 | 3 | Currently this is only a plan. 4 | 5 | * `ke/`: Architecture independent 'sub-kernel'-module. Implements SMP, locking, 6 | and the scheduler. 7 | 8 | * `ex/`: Contains the executive initialization routines, as well as extra helpers 9 | that depend on kernel functions. 10 | 11 | * `mm/`: Memory management module - handles page faults, copy-on-write, demand 12 | paging, maybe even compression and swapping in the future 13 | 14 | * `arch/`: Architecture abstractions. These abstract the CPU away from other 15 | parts of the kernel. It handles page table management, context switching, 16 | interrupt priority level setting, and CPU intrinsics 17 | 18 | * `rtl/` - Run-time library - Includes functions such as sprint, memcpy, strcpy. 19 | 20 | * `ldr/` - DLL driver loader. Loads the driver DLLs into the kernel's memory region. 21 | 22 | ### Layering Diagram 23 | 24 | Here is a mockup of the layering in Boron (still a WIP): 25 | 26 | ``` 27 | +-------------------------------------------------+ 28 | | User Mode | 29 | | +---------+ +---------+ +---------+ +---------+ | 30 | | | App | | App | | App | | App | | 31 | | +---------+ +---------+ +---------+ +---------+ | 32 | +-----------------------||------------------------+ 33 | ========================||========================= USER ^ / KERNEL v 34 | +-----------------------||------------------------+ 35 | | System Call Handler | 36 | +-----------------------||------------------------+ 37 | | Executive | 38 | | | 39 | | +--------+ +--------+ +--------+ | 40 | | | Io | | Cc | | Mm 2 | | 41 | | +--------+ +--------+ +--------+ | 42 | | +--------+ +--------+ +--------+ | 43 | | | Ob | | Ps | | Cm | | 44 | | +--------+ +--------+ +--------+ | 45 | +-----------------------||------------------------+ 46 | | Kernel Core | 47 | | | 48 | | +--------+ +--------+ +--------+ +--------+ | 49 | | | Ke | | Arch | | Mm 1 | | Ldr | | 50 | | +--------+ +--------+ +--------+ +--------+ | 51 | +-----------------------||------------------------+ 52 | | Hardware | 53 | +-------------------------------------------------+ 54 | ``` 55 | 56 | 57 | -------------------------------------------------------------------------------- /borondll/include/boron.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "kes.h" 7 | #include "exs.h" 8 | #include "mms.h" 9 | #include "obs.h" 10 | #include "ios.h" 11 | #include "pss.h" 12 | 13 | #include "svcs.h" 14 | -------------------------------------------------------------------------------- /borondll/include/main.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | main.h 7 | 8 | Abstract: 9 | This header file contains the global definitions 10 | for the Boron kernel and drivers. 11 | 12 | Author: 13 | iProgramInCpp - 20 August 2023 14 | ***/ 15 | #ifndef NS64_MAIN_H 16 | #define NS64_MAIN_H 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define PACKED __attribute__((packed)) 24 | #define NO_RETURN __attribute__((noreturn)) 25 | #define RETURNS_TWICE __attribute__((returns_twice)) 26 | #define UNUSED __attribute__((unused)) 27 | #define ALWAYS_INLINE __attribute__((always_inline)) 28 | #define NO_DISCARD __attribute__((warn_unused_result)) 29 | #include 30 | 31 | #define FORCE_INLINE ALWAYS_INLINE static inline 32 | #define BIT(x) (1ULL << (x)) 33 | #define ASM __asm__ __volatile__ 34 | 35 | #define LIKELY(x) __builtin_expect(!!(x), 1) 36 | #define UNLIKELY(x) __builtin_expect(!!(x), 0) 37 | 38 | #define HIDDEN __attribute__((visibility("hidden"))) 39 | 40 | #ifdef DEBUG 41 | #define CHECK_PAGED do { \ 42 | if (KeGetIPL() >= IPL_APC) { \ 43 | KeCrash("%s: Running at IPL %d > IPL_APC", KeGetIPL(), IPL_APC); \ 44 | } \ 45 | } while (0) 46 | #else 47 | #define CHECK_PAGED 48 | #endif 49 | 50 | // We're using C11 51 | #define static_assert _Static_assert 52 | 53 | void LogMsg(const char* msg, ...); 54 | 55 | #ifdef DEBUG 56 | void DbgPrint(const char* msg, ...); 57 | #else 58 | #define DbgPrint(...) 59 | #endif 60 | 61 | #define ARRAY_COUNT(x) (sizeof(x) / sizeof((x)[0])) 62 | 63 | #define IN 64 | #define OUT 65 | #define INOUT 66 | #define OPTIONAL 67 | 68 | #define CallerAddress() ((uintptr_t) __builtin_return_address(0)) 69 | 70 | #define CONTAINING_RECORD(Pointer, Type, Field) ((Type*)((uintptr_t)(Pointer) - (uintptr_t)offsetof(Type, Field))) 71 | 72 | #include 73 | 74 | #endif//NS64_MAIN_H 75 | -------------------------------------------------------------------------------- /borondll/include/svcs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BSTATUS OSClose(HANDLE Handle); 4 | 5 | BSTATUS OSCreateThread( 6 | PHANDLE OutHandle, 7 | HANDLE ProcessHandle, 8 | POBJECT_ATTRIBUTES ObjectAttributes, 9 | PKTHREAD_START ThreadStart, 10 | void* ThreadContext, 11 | bool CreateSuspended 12 | ); 13 | 14 | BSTATUS OSCreateProcess( 15 | PHANDLE OutHandle, 16 | POBJECT_ATTRIBUTES ObjectAttributes, 17 | HANDLE ParentProcessHandle, 18 | bool InheritHandles 19 | ); 20 | 21 | void OSDummy(); 22 | 23 | NO_RETURN void OSExitThread(); 24 | 25 | //TODO: NO_RETURN void OSExitProcess(); 26 | 27 | BSTATUS OSOutputDebugString(const char* String, size_t StringLength); 28 | 29 | void OSWaitForSingleObject(HANDLE Handle, bool Alertable, int TimeoutMS); 30 | 31 | BSTATUS OSWaitForMultipleObjects( 32 | int ObjectCount, 33 | PHANDLE ObjectsArray, 34 | int WaitType, 35 | bool Alertable, 36 | int TimeoutMS 37 | ); 38 | -------------------------------------------------------------------------------- /borondll/src/calls.asm: -------------------------------------------------------------------------------- 1 | ; The Boron Operating System 2 | ; Copyright (C) 2025 iProgramInCpp 3 | 4 | ; Parameters: 5 | ; #1 - Call Number (RAX) 6 | ; #2 - System Call 7 | %macro CALL 2 8 | global %2 9 | %2: 10 | push rbp 11 | mov rbp, rsp 12 | push rbx 13 | push r12 14 | push r13 15 | push r14 16 | push r15 17 | mov r10, rcx 18 | mov rax, %1 19 | syscall 20 | pop r15 21 | pop r14 22 | pop r13 23 | pop r12 24 | pop rbx 25 | pop rbp 26 | ret 27 | %endmacro 28 | 29 | CALL 0, OSClose 30 | CALL 1, OSCreateThread 31 | CALL 2, OSCreateProcess 32 | CALL 3, OSDummy 33 | CALL 4, OSExitThread 34 | CALL 5, OSOutputDebugString 35 | CALL 6, OSWaitForSingleObject 36 | CALL 7, OSWaitForMultipleObjects 37 | -------------------------------------------------------------------------------- /borondll/src/init.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | NO_RETURN 4 | void TestThreadStart(); 5 | 6 | const char HiStr[] = "Hissssssssssss, Viper Lives\n"; 7 | 8 | HIDDEN 9 | void DLLEntryPoint() 10 | { 11 | HANDLE Handle; 12 | BSTATUS Status; 13 | 14 | DbgPrint("Calling OSDummy twice."); 15 | OSDummy(); 16 | OSDummy(); 17 | 18 | // create a new thread for fun 19 | DbgPrint("Creating new thread."); 20 | Status = OSCreateThread( 21 | &Handle, 22 | CURRENT_PROCESS_HANDLE, 23 | NULL, 24 | TestThreadStart, 25 | NULL, 26 | false 27 | ); 28 | 29 | DbgPrint("Got handle %lld, status %d from OSCreateThread: %s", (long long) Handle, Status, RtlGetStatusString(Status)); 30 | 31 | DbgPrint("Waiting on new thread handle."); 32 | OSWaitForSingleObject(Handle, false, WAIT_TIMEOUT_INFINITE); 33 | 34 | DbgPrint("Closing new thread handle."); 35 | OSClose(Handle); 36 | 37 | DbgPrint("Creating a new empty process, then closing it."); 38 | 39 | Status = OSCreateProcess( 40 | &Handle, 41 | NULL, 42 | CURRENT_PROCESS_HANDLE, 43 | false 44 | ); 45 | 46 | DbgPrint("Got handle %lld, status %d from OSCreateProcess: %s", (long long) Handle, Status, RtlGetStatusString(Status)); 47 | 48 | DbgPrint("Closing new thread handle."); 49 | OSClose(Handle); 50 | 51 | DbgPrint("Main Thread exiting."); 52 | OSExitThread(); 53 | } 54 | 55 | NO_RETURN 56 | void TestThreadStart() 57 | { 58 | OSOutputDebugString(HiStr, sizeof HiStr); 59 | 60 | DbgPrint("New Thread exiting."); 61 | OSExitThread(); 62 | } 63 | -------------------------------------------------------------------------------- /borondll/src/rtl: -------------------------------------------------------------------------------- 1 | ../../boron/source/rtl -------------------------------------------------------------------------------- /common/include/exs.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | exs.h 7 | 8 | Abstract: 9 | This header file contains the publicly exposed structure 10 | definitions for Boron's Executive Subsystem. 11 | 12 | Author: 13 | iProgramInCpp - 22 April 2025 14 | ***/ 15 | #pragma once 16 | 17 | #include "handle.h" 18 | 19 | enum 20 | { 21 | WAIT_ALL_OBJECTS, 22 | WAIT_ANY_OBJECT, 23 | __WAIT_TYPE_COUNT, 24 | }; 25 | 26 | #define WAIT_TIMEOUT_INFINITE (0x7FFFFFFF) 27 | 28 | #define CURRENT_PROCESS_HANDLE ((HANDLE) 0xFFFFFFFF) 29 | #define CURRENT_THREAD_HANDLE ((HANDLE) 0xFFFFFFFE) 30 | -------------------------------------------------------------------------------- /common/include/handle.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | handle.h 7 | 8 | Abstract: 9 | This header file defines the handle type. 10 | 11 | Author: 12 | iProgramInCpp - 22 April 2025 13 | ***/ 14 | #pragma once 15 | 16 | typedef uintptr_t HANDLE, *PHANDLE; 17 | 18 | #define HANDLE_NONE (0) 19 | -------------------------------------------------------------------------------- /common/include/ios.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | ios.h 7 | 8 | Abstract: 9 | This header file contains the publicly exposed structure 10 | definitions for Boron's I/O Subsystem. 11 | 12 | Author: 13 | iProgramInCpp - 22 April 2025 14 | ***/ 15 | #pragma once 16 | 17 | typedef struct _IO_STATUS_BLOCK 18 | { 19 | BSTATUS Status; 20 | 21 | union 22 | { 23 | // Generic name 24 | uint64_t Information; 25 | 26 | // ReadFile 27 | uint64_t BytesRead; 28 | 29 | // WriteFile 30 | uint64_t BytesWritten; 31 | 32 | // ReadDir 33 | uint64_t NextOffset; 34 | 35 | // ParseDir 36 | #ifdef KERNEL 37 | struct 38 | { 39 | PFCB FoundFcb; 40 | const char* ReparsePath; 41 | } 42 | ParseDir; 43 | 44 | // BackingMemory 45 | struct 46 | { 47 | void* Start; // Start should be aligned to 4096 bytes 48 | size_t Length; // Length should be a multiple of 4096 49 | } 50 | BackingMemory; 51 | 52 | // GetAlignmentInfo 53 | struct 54 | { 55 | uint32_t BlockSizeLog; 56 | } 57 | AlignmentInfo; 58 | #endif 59 | }; 60 | } 61 | IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; 62 | 63 | enum 64 | { 65 | IO_SEEK_CUR, 66 | IO_SEEK_SET, 67 | IO_SEEK_END, 68 | }; 69 | 70 | #define IO_MAX_NAME (192) 71 | 72 | typedef struct _IO_DIRECTORY_ENTRY 73 | { 74 | // Null-terminated file name. 75 | char Name[IO_MAX_NAME]; 76 | 77 | char Reserved[256 - IO_MAX_NAME]; 78 | } 79 | IO_DIRECTORY_ENTRY, *PIO_DIRECTORY_ENTRY; 80 | -------------------------------------------------------------------------------- /common/include/kes.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | kes.h 7 | 8 | Abstract: 9 | This header file contains the publicly exposed structure 10 | definitions for Boron's Kernel Core Subsystem. 11 | 12 | Author: 13 | iProgramInCpp - 22 April 2025 14 | ***/ 15 | #pragma once 16 | 17 | typedef NO_RETURN void(*PKTHREAD_START)(void* Context); 18 | 19 | -------------------------------------------------------------------------------- /common/include/mms.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | mms.h 7 | 8 | Abstract: 9 | This header file contains the publicly exposed structure 10 | definitions for Boron's Memory Subsystem. 11 | 12 | Author: 13 | iProgramInCpp - 22 April 2025 14 | ***/ 15 | #pragma once 16 | 17 | #include "handle.h" 18 | -------------------------------------------------------------------------------- /common/include/obs.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | obs.h 7 | 8 | Abstract: 9 | This header file contains the publicly exposed structure 10 | definitions for Boron's Object Subsystem. 11 | 12 | Author: 13 | iProgramInCpp - 22 April 2025 14 | ***/ 15 | #pragma once 16 | 17 | #include "handle.h" 18 | 19 | #define OB_PATH_SEPARATOR ('\\') 20 | #define OB_MAX_PATH_LENGTH (256) 21 | 22 | // Object open flags: 23 | enum 24 | { 25 | // Handle may be inherited by child processes. 26 | OB_OPEN_INHERIT = (1 << 0), 27 | // No other process may open this handle while the current process maintains a handle. 28 | OB_OPEN_EXCLUSIVE = (1 << 1), 29 | // If the final path component is a symbolic link, open the symbolic link object itself 30 | // instead of its referenced object (the latter is the default behavior) 31 | OB_OPEN_SYMLINK = (1 << 2), 32 | }; 33 | 34 | typedef struct _OBJECT_ATTRIBUTES 35 | { 36 | HANDLE RootDirectory; 37 | const char* ObjectName; 38 | size_t ObjectNameLength; 39 | int OpenFlags; 40 | } 41 | OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; 42 | -------------------------------------------------------------------------------- /common/include/pss.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | pss.h 7 | 8 | Abstract: 9 | This header file contains the publicly exposed structure 10 | definitions for Boron's Process Subsystem. 11 | 12 | Author: 13 | iProgramInCpp - 22 April 2025 14 | ***/ 15 | #pragma once 16 | 17 | 18 | -------------------------------------------------------------------------------- /common/include/rtl/ansi.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | rtl/ansi.h 7 | 8 | Abstract: 9 | This header file contains ANSI escape code definitions. 10 | 11 | Author: 12 | iProgramInCpp - 25 October 2023 13 | ***/ 14 | #ifndef BORON_RTL_ANSI_H 15 | #define BORON_RTL_ANSI_H 16 | 17 | #define ANSI_HOME "\x1b[H" 18 | #define ANSI_POS(x,y) ("\x1b[" #x ";" #y "H") 19 | #define ANSI_CLEAR "\x1b[2J" 20 | 21 | #define ANSI_RESET "\x1b[0m" 22 | #define ANSI_BOLD "\x1b[1m" 23 | #define ANSI_DEFAULT "\x1b[39m" 24 | #define ANSI_BLACK "\x1b[90m" 25 | #define ANSI_RED "\x1b[91m" 26 | #define ANSI_GREEN "\x1b[92m" 27 | #define ANSI_YELLOW "\x1b[93m" 28 | #define ANSI_BLUE "\x1b[94m" 29 | #define ANSI_MAGENTA "\x1b[95m" 30 | #define ANSI_CYAN "\x1b[96m" 31 | #define ANSI_WHITE "\x1b[97m" 32 | 33 | #endif//BORON_RTL_ANSI_H 34 | -------------------------------------------------------------------------------- /common/include/rtl/assert.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | rtl/assert.h 7 | 8 | Abstract: 9 | This header file implements the assertion logic on debug 10 | checked builds of the Boron kernel. 11 | 12 | Author: 13 | iProgramInCpp - 11 November 2023 14 | ***/ 15 | #ifndef BORON_RTL_ASSERT_H 16 | #define BORON_RTL_ASSERT_H 17 | 18 | // ASSERT: Asserts that a condition is true and crashes otherwise. On release, the condition is still 19 | // emitted. 20 | // 21 | // ASSERT2: Ditto, but displays an extra message 22 | // 23 | // ASSERTN: Same as ASSERT, but on release, is replaced with nothing. 24 | 25 | #ifdef DEBUG 26 | 27 | bool RtlAssert(const char* Condition, const char* File, int Line, const char* Message); 28 | 29 | #define ASSERT(Condition) ((void)((Condition) ? 0 : RtlAssert(#Condition, __FILE__, __LINE__, NULL))) 30 | #define ASSERT2(Condition, Message) ((void)((Condition) ? 0 : RtlAssert(#Condition, __FILE__, __LINE__, Message))) 31 | #define ASSERTN(Condition) ((void)((Condition) ? 0 : RtlAssert(#Condition, __FILE__, __LINE__, NULL))) 32 | 33 | #else 34 | 35 | // Define ASSERT and ASSERT2 as a simple evaluation of the condition (which is likely to 36 | // be optimized out). A release build does not have assertions of any kind. 37 | // 38 | // Define ASSERT3 as nothing. 39 | #define ASSERT(Condition) ((void)(Condition)) 40 | #define ASSERT2(Condition, Message) ((void)(Condition)) 41 | #define ASSERTN(Condition) 42 | 43 | #endif 44 | 45 | #endif//BORON_RTL_ASSERT_H 46 | -------------------------------------------------------------------------------- /common/include/rtl/check64.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | rtl/check64.h 7 | 8 | Abstract: 9 | This header file defines IS_64_BIT on 64-bit platforms, and 10 | IS_32_BIT on 32-bit platforms. 11 | 12 | Author: 13 | iProgramInCpp - 30 April 2024 14 | ***/ 15 | #pragma once 16 | 17 | #ifdef TARGET_AMD64 18 | #define IS_64_BIT 19 | #else 20 | #error Add your platform here! 21 | #endif 22 | 23 | // In the future it should look something like this: 24 | // #if defined TARGET_AMD64 || defined TARGET_RISCV64 || defined TARGET_AARCH64 25 | // # define IS_64_BIT 26 | // #else if defined TARGET_I486 || defined TARGET_ARM || defined TARGET_MIPS 27 | // # define IS_32_BIT 28 | // #else 29 | // # error Add your platform here! 30 | // #endif 31 | -------------------------------------------------------------------------------- /common/include/rtl/elf.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | rtl/elf.h 7 | 8 | Abstract: 9 | This header file defines function prototypes for 10 | ELF loading helpers. 11 | 12 | Author: 13 | iProgramInCpp - 30 April 2024 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | // Struct not part of the ELF format, but part of the loader. 20 | typedef struct ELF_DYNAMIC_INFO_tag 21 | { 22 | const char *DynStrTable; 23 | PELF_SYMBOL DynSymTable; 24 | uintptr_t *GlobalOffsetTable; 25 | size_t GlobalOffsetTableSize; 26 | uintptr_t *GotPlt; 27 | size_t GotPltSize; 28 | const void *PltRelocations; 29 | size_t PltRelocationCount; 30 | ELF_RELA *RelaEntries; 31 | size_t RelaCount; 32 | ELF_REL *RelEntries; 33 | size_t RelCount; 34 | uintptr_t *RelrEntries; 35 | size_t RelrCount; 36 | bool PltUsesRela; 37 | const char *StringTable; 38 | PELF_SYMBOL SymbolTable; 39 | size_t SymbolTableSize; 40 | } 41 | ELF_DYNAMIC_INFO, *PELF_DYNAMIC_INFO; 42 | 43 | bool RtlPerformRelocations(PELF_DYNAMIC_INFO DynInfo, uintptr_t LoadBase); 44 | 45 | bool RtlParseDynamicTable(PELF_DYNAMIC_ITEM DynItem, PELF_DYNAMIC_INFO Info, uintptr_t LoadBase); 46 | 47 | bool RtlLinkPlt(PELF_DYNAMIC_INFO DynInfo, uintptr_t LoadBase, bool AllowKernelLinking, UNUSED const char* FileName); 48 | 49 | bool RtlUpdateGlobalOffsetTable(uintptr_t *Got, size_t Size, uintptr_t LoadBase); 50 | 51 | void RtlParseInterestingSections(uint8_t* FileAddress, PELF_DYNAMIC_INFO DynInfo, uintptr_t LoadBase); 52 | 53 | void RtlRelocateRelrEntries(PELF_DYNAMIC_INFO DynInfo, uintptr_t LoadBase); 54 | -------------------------------------------------------------------------------- /common/include/rtl/rbtree.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | rtl/rbtree.h 7 | 8 | Abstract: 9 | This header file provides definitions for the 10 | implementation of the rank-balanced tree. 11 | 12 | This implementation was adapted from FreeBSD. It's available at: 13 | https://github.com/freebsd/freebsd-src/blob/main/sys/sys/tree.h 14 | 15 | Author: 16 | iProgramInCpp - 13 August 2024 17 | ***/ 18 | #pragma once 19 | 20 | #include 21 | 22 | typedef uintptr_t __uintptr_t; 23 | typedef intptr_t __intptr_t; 24 | 25 | // Include the FreeBSD tree header. 26 | #include "fbsdtree.h" 27 | 28 | typedef struct _RBTREE_ENTRY RBTREE_ENTRY, *PRBTREE_ENTRY; 29 | typedef struct _RBTREE RBTREE, *PRBTREE; 30 | 31 | typedef uintptr_t RBTREE_KEY; 32 | typedef bool (*PRBTREE_TRAVERSAL_FUNCTION) (void* Context, PRBTREE_ENTRY Entry); 33 | 34 | struct _RBTREE_HEAD; 35 | 36 | struct _RBTREE_ENTRY 37 | { 38 | RB_ENTRY(_RBTREE_ENTRY) Entry; 39 | uintptr_t Key; 40 | }; 41 | 42 | struct _RBTREE 43 | { 44 | RB_HEAD(_RBTREE_HEAD, _RBTREE_ENTRY) Head; 45 | }; 46 | 47 | #define InitializeRbTree(Tree) RB_INIT(&(Tree)->Head) 48 | #define IsEmptyRbTree(Tree) RB_EMPTY(&(Tree)->Head) 49 | #define InitializeRbTreeEntry(EntryP) 50 | 51 | bool InsertItemRbTree(PRBTREE Tree, PRBTREE_ENTRY Item); 52 | 53 | bool RemoveItemRbTree(PRBTREE Tree, PRBTREE_ENTRY Item); 54 | 55 | PRBTREE_ENTRY LookUpItemRbTree(PRBTREE Tree, RBTREE_KEY Key); 56 | 57 | PRBTREE_ENTRY LookUpItemApproximateRbTree(PRBTREE Tree, RBTREE_KEY Key); 58 | 59 | PRBTREE_ENTRY GetFirstEntryRbTree(PRBTREE Tree); 60 | 61 | PRBTREE_ENTRY GetLastEntryRbTree(PRBTREE Tree); 62 | 63 | PRBTREE_ENTRY GetRootEntryRbTree(PRBTREE Tree); 64 | 65 | size_t GetItemCountRbTree(PRBTREE Tree); 66 | 67 | void TraverseRbTree( 68 | PRBTREE Tree, 69 | PRBTREE_TRAVERSAL_FUNCTION Function, 70 | void* Context); 71 | 72 | PRBTREE_ENTRY GetNextEntryRbTree(PRBTREE_ENTRY); 73 | PRBTREE_ENTRY GetPrevEntryRbTree(PRBTREE_ENTRY); 74 | -------------------------------------------------------------------------------- /common/include/rtl/symdefs.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023-2024 iProgramInCpp 4 | 5 | Module name: 6 | rtl/symdefs.h 7 | 8 | Abstract: 9 | This header file contains the structure definitions for the 10 | symbol table for Boron. 11 | 12 | Author: 13 | iProgramInCpp - 20 October 2023 14 | ***/ 15 | #ifndef BORON_RTL_SYMDEFS_H 16 | #define BORON_RTL_SYMDEFS_H 17 | 18 | #include 19 | 20 | #ifdef KERNEL 21 | 22 | // Note. Two qwords is how we define it in the assembly version 23 | typedef struct KSYMBOL_tag 24 | { 25 | uintptr_t Address; 26 | uintptr_t Size; 27 | const char* Name; 28 | } 29 | KSYMBOL, *PKSYMBOL; 30 | 31 | typedef const KSYMBOL* PCKSYMBOL; 32 | 33 | extern const KSYMBOL KiSymbolTable[]; 34 | extern const KSYMBOL KiSymbolTableEnd[]; 35 | 36 | #define KiSymbolTableSize (KiSymbolTableEnd - KiSymbolTable) 37 | 38 | #endif 39 | 40 | #endif//BORON_RTL_SYMDEFS_H 41 | -------------------------------------------------------------------------------- /common/include/string.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | string.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | runtime string library. 11 | 12 | Author: 13 | iProgramInCpp - 20 August 2023 14 | ***/ 15 | #ifndef NS64_STRING_H 16 | #define NS64_STRING_H 17 | 18 | #include 19 | 20 | // Include stb printf so we have definitions ready 21 | #define STB_SPRINTF_NOFLOAT 22 | #define STB_SPRINTF_DECORATE // don't decorate 23 | #include "_stb_sprintf.h" 24 | 25 | void* memcpy(void* dst, const void* src, size_t n); 26 | void* memquadcpy(uint64_t* dst, const uint64_t* src, size_t n); 27 | void* memset(void* dst, int c, size_t n); 28 | size_t strlen(const char * s); 29 | char* strcpy(char* s, const char * d); 30 | char* strcat(char* s, const char * src); 31 | int memcmp(const void* s1, const void* s2, size_t n); 32 | int strcmp(const char* s1, const char* s2); 33 | char* strncpy(char* d, const char* s, size_t sz); 34 | 35 | #endif//NS64_STRING_H -------------------------------------------------------------------------------- /drivers/ext2fs/Makefile: -------------------------------------------------------------------------------- 1 | # The Boron Operating System 2 | # Common makefile for all driver targets 3 | 4 | DRIVER_NAME = ext2fs 5 | # DRIVER_ENTRY = DriverEntry 6 | # DEBUG = yes 7 | # DEBUG2 = no 8 | 9 | include ../CommonMakefile 10 | -------------------------------------------------------------------------------- /drivers/ext2fs/linker.ld: -------------------------------------------------------------------------------- 1 | /* Tell the linker that we want an x86_64 ELF64 output file */ 2 | OUTPUT_FORMAT(elf64-x86-64) 3 | OUTPUT_ARCH(i386:x86-64) 4 | 5 | /* We want the symbol DriverEntry to be our entry point */ 6 | ENTRY(DriverEntry) 7 | 8 | /* Define the program headers we want so the bootloader gives us the right */ 9 | /* MMU permissions */ 10 | PHDRS 11 | { 12 | text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ 13 | rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ 14 | data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ 15 | } 16 | 17 | SECTIONS 18 | { 19 | /* We want to be placed in the topmost 2GiB of the address space, for optimizations, and because that is what the Limine spec mandates. */ 20 | /* Any address in this region will do, but often 0xffffffff80000000 is chosen as that is the beginning of the region. */ 21 | . = 0xffffffff80000000; 22 | 23 | .text : { 24 | *(.text .text.*) 25 | } :text 26 | 27 | /* Move to the next memory page for .rodata */ 28 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 29 | 30 | .rodata : { 31 | *(.rodata .rodata.*) 32 | } :rodata 33 | 34 | /* Move to the next memory page for .data */ 35 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 36 | 37 | /* Global constructor array. */ 38 | .init_array : { 39 | g_init_array_start = .; 40 | *(.init_array) 41 | g_init_array_end = .; 42 | } 43 | 44 | /* Global destructor array. */ 45 | .fini_array : { 46 | g_fini_array_start = .; 47 | *(.fini_array) 48 | g_fini_array_end = .; 49 | } 50 | 51 | .data : { 52 | *(.data .data.*) 53 | } :data 54 | 55 | .bss : { 56 | *(COMMON) 57 | *(.bss .bss.*) 58 | } :data 59 | 60 | /* Discard .note.* and .eh_frame since they may cause issues on some hosts. */ 61 | /DISCARD/ : { 62 | *(.eh_frame) 63 | *(.note .note.*) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /drivers/ext2fs/source/ext2.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | ext2.h 7 | 8 | Abstract: 9 | This header defines all of the structures used by 10 | the ext2 file system driver as well as the ext2 11 | I/O dispatch function prototypes. 12 | 13 | Author: 14 | iProgramInCpp - 15 May 2025 15 | ***/ 16 | #pragma once 17 | 18 | #include 19 | #include 20 | 21 | BSTATUS Ext2Mount(PDEVICE_OBJECT BackingDevice); 22 | -------------------------------------------------------------------------------- /drivers/ext2fs/source/main.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | main.c 7 | 8 | Abstract: 9 | This module implements the main function of the 10 | Ext2 File System driver. 11 | 12 | Author: 13 | iProgramInCpp - 30 April 2025 14 | ***/ 15 | #include "ext2.h" 16 | 17 | IO_DISPATCH_TABLE Ext2DispatchTable = 18 | { 19 | .Mount = Ext2Mount, 20 | }; 21 | 22 | BSTATUS DriverEntry(UNUSED PDRIVER_OBJECT Object) 23 | { 24 | IoRegisterFileSystemDriver(&Ext2DispatchTable); 25 | return STATUS_SUCCESS; 26 | } 27 | -------------------------------------------------------------------------------- /drivers/ext2fs/source/mount.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | mount.c 7 | 8 | Abstract: 9 | This module takes care of the process of mounting 10 | an Ext2 partition. 11 | 12 | Author: 13 | iProgramInCpp - 15 May 2025 14 | ***/ 15 | #include "ext2.h" 16 | 17 | BSTATUS Ext2Mount(PDEVICE_OBJECT BackingDevice) 18 | { 19 | // TODO 20 | LogMsg("Ext2: Attempt to mount from %p", BackingDevice); 21 | return STATUS_UNIMPLEMENTED; 22 | } 23 | -------------------------------------------------------------------------------- /drivers/halx86/Makefile: -------------------------------------------------------------------------------- 1 | # The Boron Operating System 2 | # Common makefile for all driver targets 3 | 4 | DRIVER_NAME = halx86 5 | # DRIVER_ENTRY = DriverEntry 6 | # DEBUG = yes 7 | # DEBUG2 = no 8 | USER_DEFINES = -DIS_HAL -DFLANTERM_FB_DISABLE_CANVAS -DFLANTERM_FB_DISABLE_BUMP_ALLOC 9 | 10 | include ../CommonMakefile 11 | -------------------------------------------------------------------------------- /drivers/halx86/linker.ld: -------------------------------------------------------------------------------- 1 | /* Tell the linker that we want an x86_64 ELF64 output file */ 2 | OUTPUT_FORMAT(elf64-x86-64) 3 | OUTPUT_ARCH(i386:x86-64) 4 | 5 | /* We want the symbol DriverEntry to be our entry point */ 6 | ENTRY(DriverEntry) 7 | 8 | /* Define the program headers we want so the bootloader gives us the right */ 9 | /* MMU permissions */ 10 | PHDRS 11 | { 12 | text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ 13 | rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ 14 | data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ 15 | } 16 | 17 | SECTIONS 18 | { 19 | /* We want to be placed in the topmost 2GiB of the address space, for optimizations, and because that is what the Limine spec mandates. */ 20 | /* Any address in this region will do, but often 0xffffffff80000000 is chosen as that is the beginning of the region. */ 21 | . = 0xffffffff80000000; 22 | 23 | .text : { 24 | *(.text .text.*) 25 | } :text 26 | 27 | /* Move to the next memory page for .rodata */ 28 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 29 | 30 | .rodata : { 31 | *(.rodata .rodata.*) 32 | } :rodata 33 | 34 | /* Move to the next memory page for .data */ 35 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 36 | 37 | /* Global constructor array. */ 38 | .init_array : { 39 | g_init_array_start = .; 40 | *(.init_array) 41 | g_init_array_end = .; 42 | } 43 | 44 | /* Global destructor array. */ 45 | .fini_array : { 46 | g_fini_array_start = .; 47 | *(.fini_array) 48 | g_fini_array_end = .; 49 | } 50 | 51 | .data : { 52 | *(.data .data.*) 53 | } :data 54 | 55 | .bss : { 56 | *(COMMON) 57 | *(.bss .bss.*) 58 | } :data 59 | 60 | /* Discard .note.* and .eh_frame since they may cause issues on some hosts. */ 61 | /DISCARD/ : { 62 | *(.eh_frame) 63 | *(.note .note.*) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /drivers/halx86/source/apic.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ha/apic.h 7 | 8 | Abstract: 9 | This module contains support routine prototypes for the APIC. 10 | 11 | Author: 12 | iProgramInCpp - 16 September 2023 13 | ***/ 14 | 15 | #ifndef NS64_HAL_APIC_H 16 | #define NS64_HAL_APIC_H 17 | 18 | void HalEndOfInterrupt(); 19 | 20 | void HalSendIpi(uint32_t Processor, int Vector); 21 | void HalBroadcastIpi(int Vector, bool IncludeSelf); 22 | void HalInitApicUP(); 23 | void HalInitApicMP(); 24 | void HalCalibrateApic(); 25 | bool HalIsApicAvailable(); 26 | void HalApicSetIrqIn(uint64_t Ticks); 27 | void HalInitIoApic(); 28 | 29 | #endif//NS64_HAL_APIC_H 30 | -------------------------------------------------------------------------------- /drivers/halx86/source/crash.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ha/crash.c 7 | 8 | Abstract: 9 | This module contains the AMD64 platform's specific 10 | crash routine. 11 | 12 | Author: 13 | iProgramInCpp - 16 September 2023 14 | ***/ 15 | 16 | #include "hali.h" 17 | #include 18 | #include 19 | #include "apic.h" 20 | 21 | static KSPIN_LOCK HalpCrashLock; 22 | static int HalpCrashedProcessors; 23 | 24 | void HalProcessorCrashed() 25 | { 26 | AtAddFetch(HalpCrashedProcessors, 1); 27 | KeStopCurrentCPU(); 28 | } 29 | 30 | void HalCrashSystem(const char* Message) 31 | { 32 | KIPL Unused; 33 | // lock the crash in so that no one else can crash but us 34 | KeAcquireSpinLock(&HalpCrashLock, &Unused); 35 | AtClear(HalpCrashedProcessors); 36 | AtAddFetch(HalpCrashedProcessors, 1); 37 | 38 | // disable interrupts 39 | DISABLE_INTERRUPTS(); 40 | 41 | int ProcessorCount = KeGetProcessorCount(); 42 | 43 | // pre-lock the print and debug print lock so there are no threading issues later from 44 | // stopping the CPUs. 45 | // TODO: Also lock other important used locks too 46 | //KeAcquireSpinLock(&g_PrintLock); 47 | //KeAcquireSpinLock(&g_DebugPrintLock); 48 | 49 | // Send IPI to the other processors to make them halt. 50 | // Don't send an IPI to ourselves as we already are in the process of crashing. 51 | HalRequestIpi(0, HAL_IPI_BROADCAST, KiVectorCrash); 52 | 53 | //HalPrintStringDebug("CRASH: Waiting for all processors to halt!\n"); 54 | while (AtLoad(HalpCrashedProcessors) != ProcessorCount) 55 | KeSpinningHint(); 56 | 57 | KeCrashConclusion(Message); 58 | } 59 | -------------------------------------------------------------------------------- /drivers/halx86/source/hali.h: -------------------------------------------------------------------------------- 1 | #ifndef BORON_HALX86_HALI_H 2 | #define BORON_HALX86_HALI_H 3 | 4 | #include 5 | 6 | #define HAL_API // specify calling convention here if needed 7 | 8 | #endif//BORON_HALX86_HALI_H 9 | -------------------------------------------------------------------------------- /drivers/halx86/source/hpet.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | hal/iapc/hpet.h 7 | 8 | Abstract: 9 | This header file contains the definitions for the 10 | HPET device driver. 11 | 12 | Author: 13 | iProgramInCpp - 29 September 2023 14 | ***/ 15 | #ifndef BORON_HAL_HPET_H 16 | #define BORON_HAL_HPET_H 17 | 18 | typedef union HPET_GENERAL_CAPS_tag 19 | { 20 | struct 21 | { 22 | unsigned RevID : 8; 23 | unsigned NumTimCap : 5; 24 | unsigned CountSizeCap : 1; 25 | unsigned Reserved : 1; 26 | unsigned LegRouteCap : 1; 27 | unsigned VendorID : 16; 28 | unsigned CounterClockPeriod : 32; 29 | } 30 | PACKED; 31 | 32 | uint64_t Contents; 33 | } 34 | HPET_GENERAL_CAPS, *PHPET_GENERAL_CAPS; 35 | 36 | typedef struct HPET_TIMER_INFO_tag 37 | { 38 | uint64_t ConfigAndCaps; 39 | uint64_t ComparatorValue; 40 | uint64_t FSBInterruptRoute; 41 | uint64_t Reserved; 42 | } 43 | HPET_TIMER_INFO, *PHPET_TIMER_INFO; 44 | 45 | typedef struct HPET_REGISTERS_tag 46 | { 47 | uint64_t GeneralCaps; 48 | uint64_t Reserved8; 49 | uint64_t GeneralConfig; 50 | uint64_t Reserved18; 51 | uint64_t GeneralIrqStatus; 52 | uint64_t Reserved28; 53 | uint64_t ReservedArr[24]; 54 | uint64_t CounterValue; 55 | uint64_t ReservedF8; 56 | HPET_TIMER_INFO Timers[32]; 57 | } 58 | HPET_REGISTERS, *PHPET_REGISTERS; 59 | 60 | void HpetInitialize(); 61 | 62 | bool HpetIsAvailable(); 63 | 64 | uint64_t HpetReadValue(); 65 | 66 | uint64_t HpetGetFrequency(); 67 | 68 | #endif//BORON_HAL_HPET_H 69 | -------------------------------------------------------------------------------- /drivers/halx86/source/ioapic.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | ha/ioapic.h 7 | 8 | Abstract: 9 | This header contains definitions related to the IOAPIC driver. 10 | 11 | Author: 12 | iProgramInCpp - 15 October 2023 13 | ***/ 14 | #ifndef BORON_HAL_IAPC_IOAPIC_H 15 | #define BORON_HAL_IAPC_IOAPIC_H 16 | 17 | void HalIoApicSetIrqRedirect(uint8_t Vector, uint8_t Irq, uint32_t LapicId, bool Status); 18 | 19 | #endif//BORON_HAL_IAPC_IOAPIC_H 20 | -------------------------------------------------------------------------------- /drivers/halx86/source/pci.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | pci.h 7 | 8 | Abstract: 9 | This header defines PCI-related structures and 10 | function prototypes. 11 | 12 | Author: 13 | iProgramInCpp - 4 July 2024 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | #include // includes hal/pci.h which defines certain types 21 | #include 22 | 23 | #define PCI_CONFIG_ADDRESS (0xCF8) 24 | #define PCI_CONFIG_DATA (0xCFC) 25 | 26 | #define PCI_VENDOR_INVALID (0xFFFF) 27 | 28 | // PCI capability IDs. 29 | #define PCI_CAP_PCI_EXPRESS (0x01) 30 | #define PCI_CAP_MSI (0x05) 31 | #define PCI_CAP_MSI_X (0x11) 32 | 33 | #define PCI_MAX_BUS (256) 34 | #define PCI_MAX_SLOT (32) 35 | #define PCI_MAX_FUNC (8) 36 | 37 | void HalInitPci(); 38 | 39 | uint32_t HalPciConfigReadDword(PPCI_ADDRESS Address, uint8_t Offset); 40 | uint16_t HalPciConfigReadWord(PPCI_ADDRESS Address, uint8_t Offset); 41 | void HalPciConfigWriteDword(PPCI_ADDRESS Address, uint8_t Offset, uint32_t Data); 42 | void HalPciReadDeviceIdentifier(PPCI_ADDRESS Address, PPCI_IDENTIFIER OutIdentifier); 43 | uint32_t HalPciReadBar(PPCI_ADDRESS Address, int BarIndex); 44 | uint32_t HalPciReadBarIoAddress(PPCI_ADDRESS Address, int BarIndex); 45 | uintptr_t HalPciReadBarAddress(PPCI_ADDRESS Address, int BarIndex); -------------------------------------------------------------------------------- /drivers/halx86/source/pio.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | arch/amd64/pio.c 7 | 8 | Abstract: 9 | This module implements x86 specific Port I/O functions. 10 | 11 | Author: 12 | iProgramInCpp - 7 September 2023 13 | ***/ 14 | #include 15 | #include "pio.h" 16 | 17 | uint8_t KePortReadByte(uint16_t portNo) 18 | { 19 | uint8_t rv; 20 | ASM("inb %1, %0" : "=a" (rv) : "dN" (portNo)); 21 | return rv; 22 | } 23 | 24 | void KePortWriteByte(uint16_t portNo, uint8_t data) 25 | { 26 | ASM("outb %0, %1"::"a"((uint8_t)data),"Nd"((uint16_t)portNo)); 27 | } 28 | 29 | uint16_t KePortReadWord(uint16_t portNo) 30 | { 31 | uint16_t rv; 32 | ASM("inw %1, %0" : "=a" (rv) : "dN" (portNo)); 33 | return rv; 34 | } 35 | 36 | void KePortWriteWord(uint16_t portNo, uint16_t data) 37 | { 38 | ASM("outw %0, %1"::"a"((uint16_t)data),"Nd"((uint16_t)portNo)); 39 | } 40 | 41 | 42 | uint32_t KePortReadDword(uint16_t portNo) 43 | { 44 | uint32_t rv; 45 | ASM("inl %1, %0" : "=a" (rv) : "dN" (portNo)); 46 | return rv; 47 | } 48 | 49 | void KePortWriteDword(uint16_t portNo, uint32_t data) 50 | { 51 | ASM("outl %0, %1"::"a"((uint32_t)data),"Nd"((uint16_t)portNo)); 52 | } 53 | -------------------------------------------------------------------------------- /drivers/halx86/source/pio.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | arch/amd64/pio.h 7 | 8 | Abstract: 9 | This module implements x86 specific Port I/O functions. 10 | 11 | Author: 12 | iProgramInCpp - 7 September 2023 13 | ***/ 14 | 15 | #ifndef NS64_PIO_H 16 | #define NS64_PIO_H 17 | 18 | #include 19 | 20 | uint8_t KePortReadByte(uint16_t portNo); 21 | void KePortWriteByte(uint16_t portNo, uint8_t data); 22 | uint16_t KePortReadWord(uint16_t portNo); 23 | void KePortWriteWord(uint16_t portNo, uint16_t data); 24 | uint32_t KePortReadDword(uint16_t portNo); 25 | void KePortWriteDword(uint16_t portNo, uint32_t data); 26 | 27 | #endif//NS64_PIO_H 28 | -------------------------------------------------------------------------------- /drivers/halx86/source/pit.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | hal/iapc/pit.c 7 | 8 | Abstract: 9 | This module implements the interface for the PIT device. 10 | Used to calibrate the LAPIC timer. 11 | 12 | Author: 13 | iProgramInCpp - 29 September 2023 14 | ***/ 15 | #include 16 | #include "pit.h" 17 | #include "pio.h" 18 | 19 | #define PIT_DATA_PORT (0x40) // channel 0 20 | #define PIT_COMD_PORT (0x43) // channel 0 21 | 22 | #define PIT_MODE_RATE_GENERATOR (0x04) 23 | #define PIT_MODE_ACCESS_LOHI (0x30) 24 | 25 | uint32_t HalReadPit() 26 | { 27 | uint16_t Data; 28 | 29 | // Access the PIT the following way: 30 | // * Channel 0 31 | // * Latch count value command 32 | KePortWriteByte(PIT_COMD_PORT, 0x00); 33 | 34 | Data = KePortReadByte(PIT_DATA_PORT); 35 | Data |= KePortReadByte(PIT_DATA_PORT) << 8; 36 | 37 | return Data; 38 | } 39 | 40 | void HalWritePit(uint32_t Data) 41 | { 42 | // Access the PIT the following way: 43 | // * Bits 6 and 7 - Channel (0) 44 | // * Bits 4 and 5 - Access type (low byte and high byte) 45 | // * Bits 1 to 3 - Mode of operation (rate generator) 46 | // * Bit 0 - Write mode (0 - 16-bit binary) 47 | KePortWriteByte(PIT_COMD_PORT, PIT_MODE_ACCESS_LOHI | PIT_MODE_RATE_GENERATOR); 48 | 49 | KePortWriteByte(PIT_DATA_PORT, Data & 0xFF); 50 | KePortWriteByte(PIT_DATA_PORT, Data >> 8); 51 | } 52 | -------------------------------------------------------------------------------- /drivers/halx86/source/pit.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | hal/iapc/pit.h 7 | 8 | Abstract: 9 | This header file implements the interface for the 10 | PIT device. Used to calibrate the LAPIC timer. 11 | 12 | Author: 13 | iProgramInCpp - 29 September 2023 14 | ***/ 15 | #ifndef BORON_HAL_IAPC_PIT_H 16 | #define BORON_HAL_IAPC_PIT_H 17 | 18 | uint32_t HalReadPit(); 19 | void HalWritePit(uint32_t Data); 20 | 21 | #endif//BORON_HAL_IAPC_PIT_H 22 | -------------------------------------------------------------------------------- /drivers/halx86/source/tsc.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | hal/iapc/tsc.h 7 | 8 | Abstract: 9 | This module implements the interface for the Time 10 | Stamp Counter. 11 | 12 | Author: 13 | iProgramInCpp - 29 September 2023 14 | ***/ 15 | #include 16 | #include "tsc.h" 17 | 18 | uint64_t HalReadTsc() 19 | { 20 | uint64_t low, high; 21 | 22 | // note: The rdtsc instruction is specified to zero out the top 32 bits of rax and rdx. 23 | ASM("rdtsc":"=a"(low), "=d"(high)); 24 | 25 | // So something like this is fine. 26 | return high << 32 | low; 27 | } -------------------------------------------------------------------------------- /drivers/halx86/source/tsc.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | hal/iapc/tsc.h 7 | 8 | Abstract: 9 | This header file implements the interface for the 10 | Time Stamp Counter. 11 | 12 | Author: 13 | iProgramInCpp - 29 September 2023 14 | ***/ 15 | #ifndef BORON_HAL_IAPC_TSC_H 16 | #define BORON_HAL_IAPC_TSC_H 17 | 18 | uint64_t HalReadTsc(); 19 | 20 | #endif//BORON_HAL_IAPC_TSC_H -------------------------------------------------------------------------------- /drivers/i8042prt/Makefile: -------------------------------------------------------------------------------- 1 | # The Boron Operating System 2 | # Common makefile for all driver targets 3 | 4 | DRIVER_NAME = i8042prt 5 | # DRIVER_ENTRY = DriverEntry 6 | # DEBUG = yes 7 | # DEBUG2 = no 8 | 9 | include ../CommonMakefile 10 | -------------------------------------------------------------------------------- /drivers/i8042prt/linker.ld: -------------------------------------------------------------------------------- 1 | /* Tell the linker that we want an x86_64 ELF64 output file */ 2 | OUTPUT_FORMAT(elf64-x86-64) 3 | OUTPUT_ARCH(i386:x86-64) 4 | 5 | /* We want the symbol DriverEntry to be our entry point */ 6 | ENTRY(DriverEntry) 7 | 8 | /* Define the program headers we want so the bootloader gives us the right */ 9 | /* MMU permissions */ 10 | PHDRS 11 | { 12 | text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ 13 | rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ 14 | data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ 15 | } 16 | 17 | SECTIONS 18 | { 19 | /* We want to be placed in the topmost 2GiB of the address space, for optimizations, and because that is what the Limine spec mandates. */ 20 | /* Any address in this region will do, but often 0xffffffff80000000 is chosen as that is the beginning of the region. */ 21 | . = 0xffffffff80000000; 22 | 23 | .text : { 24 | *(.text .text.*) 25 | } :text 26 | 27 | /* Move to the next memory page for .rodata */ 28 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 29 | 30 | .rodata : { 31 | *(.rodata .rodata.*) 32 | } :rodata 33 | 34 | /* Move to the next memory page for .data */ 35 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 36 | 37 | /* Global constructor array. */ 38 | .init_array : { 39 | g_init_array_start = .; 40 | *(.init_array) 41 | g_init_array_end = .; 42 | } 43 | 44 | /* Global destructor array. */ 45 | .fini_array : { 46 | g_fini_array_start = .; 47 | *(.fini_array) 48 | g_fini_array_end = .; 49 | } 50 | 51 | .data : { 52 | *(.data .data.*) 53 | } :data 54 | 55 | .bss : { 56 | *(COMMON) 57 | *(.bss .bss.*) 58 | } :data 59 | 60 | /* Discard .note.* and .eh_frame since they may cause issues on some hosts. */ 61 | /DISCARD/ : { 62 | *(.eh_frame) 63 | *(.note .note.*) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /drivers/i8042prt/source/i8042.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | i8042.c 7 | 8 | Abstract: 9 | This module implements support for the i8042 10 | controller. 11 | 12 | Author: 13 | iProgramInCpp - 2 April 2024 14 | ***/ 15 | #include "i8042.h" 16 | 17 | void SendByte(uint16_t Port, uint8_t Value) 18 | { 19 | // Stall while the input buffer is empty. 20 | while (KePortReadByte(I8042_PORT_STATUS) & I8042_STATUS_INPUT_EMPTY) 21 | KeSpinningHint(); 22 | 23 | KePortWriteByte(Port, Value); 24 | } 25 | 26 | uint8_t GetByte(uint16_t Port) 27 | { 28 | // Stall while the output buffer is full. 29 | while (~KePortReadByte(I8042_PORT_STATUS) & I8042_STATUS_OUTPUT_FULL) 30 | KeSpinningHint(); 31 | 32 | return KePortReadByte(Port); 33 | } 34 | 35 | uint8_t ReadConfig() 36 | { 37 | SendByte(I8042_PORT_CMD, I8042_CMD_READ_CONFIG); 38 | return GetByte(I8042_PORT_DATA); 39 | } 40 | 41 | void WriteConfig(uint8_t Config) 42 | { 43 | SendByte(I8042_PORT_CMD, I8042_CMD_WRITE_CONFIG); 44 | SendByte(I8042_PORT_DATA, Config); 45 | } 46 | -------------------------------------------------------------------------------- /drivers/i8042prt/source/i8042.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023-2024 iProgramInCpp 4 | 5 | Module name: 6 | i8042.h 7 | 8 | Abstract: 9 | This module defines constants used by the 10 | i8042prt PS/2 controller driver. 11 | 12 | Author: 13 | iProgramInCpp - 2 April 2024 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | 19 | /* Available ports */ 20 | #define I8042_PORT_DATA (0x60) 21 | #define I8042_PORT_STATUS (0x64) 22 | #define I8042_PORT_CMD (0x64) 23 | 24 | /* Status register flags */ 25 | #define I8042_STATUS_OUTPUT_FULL (1 << 0) 26 | #define I8042_STATUS_INPUT_EMPTY (1 << 1) 27 | #define I8042_STATUS_SYSTEM (1 << 2) 28 | #define I8042_STATUS_MODE_DATA (1 << 3) // 0 - PS/2 device, 1 - PS/2 controller 29 | #define I8042_STATUS_TIMEOUT_ERR (1 << 6) 30 | #define I8042_STATUS_PARITY_ERR (1 << 7) 31 | 32 | #define I8042_CMD_READ_CONFIG (0x20) 33 | #define I8042_CMD_WRITE_CONFIG (0x60) 34 | #define I8042_CMD_DISABLE_PORT_1 (0xAD) 35 | #define I8042_CMD_DISABLE_PORT_2 (0xA7) 36 | #define I8042_CMD_ENABLE_PORT_1 (0xAE) 37 | #define I8042_CMD_ENABLE_PORT_2 (0xA8) 38 | 39 | #define I8042_CONFIG_INT_PORT_1 (1 << 0) 40 | #define I8042_CONFIG_INT_PORT_2 (1 << 1) 41 | #define I8042_CONFIG_DISABLE_1 (1 << 4) 42 | #define I8042_CONFIG_DISABLE_2 (1 << 5) 43 | #define I8042_CONFIG_TRANSLATION (1 << 6) 44 | #define I8042_CONFIG_ZERO_BIT_3 (1 << 3) 45 | #define I8042_CONFIG_ZERO_BIT_7 (1 << 7) 46 | 47 | #define I8042_IRQ_KBD (0x1) 48 | #define I8042_IRQ_MOU (0xC) 49 | 50 | // kbd.c 51 | void KbdInitialize(int Vector, KIPL Ipl); 52 | 53 | // i8042.c 54 | void SendByte(uint16_t Port, uint8_t Value); 55 | uint8_t GetByte(uint16_t Port); 56 | uint8_t ReadConfig(); 57 | void WriteConfig(uint8_t Config); 58 | 59 | // main.c 60 | int AllocateVector(PKIPL Ipl, KIPL Default); 61 | -------------------------------------------------------------------------------- /drivers/i8042prt/source/kbd.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | main.c 7 | 8 | Abstract: 9 | This header file defines extern functions and variables 10 | related to the i8042 keyboard driver. 11 | 12 | Author: 13 | iProgramInCpp - 30 June 2024 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include "i8042.h" 20 | 21 | extern IO_DISPATCH_TABLE KbdDispatchTable; 22 | 23 | extern BSTATUS KbdCreateDeviceObject(); 24 | 25 | -------------------------------------------------------------------------------- /drivers/stornvme/Makefile: -------------------------------------------------------------------------------- 1 | # The Boron Operating System 2 | # Common makefile for all driver targets 3 | 4 | DRIVER_NAME = stornvme 5 | # DRIVER_ENTRY = DriverEntry 6 | # DEBUG = yes 7 | # DEBUG2 = no 8 | 9 | include ../CommonMakefile 10 | -------------------------------------------------------------------------------- /drivers/stornvme/linker.ld: -------------------------------------------------------------------------------- 1 | /* Tell the linker that we want an x86_64 ELF64 output file */ 2 | OUTPUT_FORMAT(elf64-x86-64) 3 | OUTPUT_ARCH(i386:x86-64) 4 | 5 | /* We want the symbol DriverEntry to be our entry point */ 6 | ENTRY(DriverEntry) 7 | 8 | /* Define the program headers we want so the bootloader gives us the right */ 9 | /* MMU permissions */ 10 | PHDRS 11 | { 12 | text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ 13 | rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ 14 | data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ 15 | } 16 | 17 | SECTIONS 18 | { 19 | /* We want to be placed in the topmost 2GiB of the address space, for optimizations, and because that is what the Limine spec mandates. */ 20 | /* Any address in this region will do, but often 0xffffffff80000000 is chosen as that is the beginning of the region. */ 21 | . = 0xffffffff80000000; 22 | 23 | .text : { 24 | *(.text .text.*) 25 | } :text 26 | 27 | /* Move to the next memory page for .rodata */ 28 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 29 | 30 | .rodata : { 31 | *(.rodata .rodata.*) 32 | } :rodata 33 | 34 | /* Move to the next memory page for .data */ 35 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 36 | 37 | /* Global constructor array. */ 38 | .init_array : { 39 | g_init_array_start = .; 40 | *(.init_array) 41 | g_init_array_end = .; 42 | } 43 | 44 | /* Global destructor array. */ 45 | .fini_array : { 46 | g_fini_array_start = .; 47 | *(.fini_array) 48 | g_fini_array_end = .; 49 | } 50 | 51 | .data : { 52 | *(.data .data.*) 53 | } :data 54 | 55 | .bss : { 56 | *(COMMON) 57 | *(.bss .bss.*) 58 | } :data 59 | 60 | /* Discard .note.* and .eh_frame since they may cause issues on some hosts. */ 61 | /DISCARD/ : { 62 | *(.eh_frame) 63 | *(.note .note.*) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /drivers/stornvme/source/main.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | main.c 7 | 8 | Abstract: 9 | This module implements the main function for the 10 | NVMe device driver. 11 | 12 | Author: 13 | iProgramInCpp - 7 July 2024 14 | ***/ 15 | #include "nvme.h" 16 | #include 17 | 18 | PDRIVER_OBJECT NvmeDriverObject; 19 | 20 | bool NvmeSeekable(UNUSED PFCB Fcb) 21 | { 22 | return true; 23 | } 24 | 25 | IO_DISPATCH_TABLE NvmeDispatchTable = { 26 | .Read = NvmeRead, 27 | .Write = NvmeWrite, 28 | .Seekable = NvmeSeekable, 29 | .GetAlignmentInfo = NvmeGetAlignmentInfo 30 | }; 31 | 32 | int AllocateVector(PKIPL Ipl, KIPL Default) 33 | { 34 | int Vector = -1; 35 | 36 | *Ipl = Default; 37 | while ((Vector = KeAllocateInterruptVector(*Ipl)) < 0 && *Ipl < IPL_CLOCK) 38 | (*Ipl)++; 39 | 40 | return Vector; 41 | } 42 | 43 | /* 44 | void NvmeInitializeDispatchTable() 45 | { 46 | NvmeDispatchTable.Read = NvmeRead; 47 | NvmeDispatchTable.Write = NvmeWrite; 48 | NvmeDispatchTable.Seekable = NvmeSeekable; 49 | NvmeDispatchTable.GetAlignmentInfo = NvmeGetAlignmentInfo; 50 | } 51 | */ 52 | BSTATUS DriverEntry(PDRIVER_OBJECT DriverObject) 53 | { 54 | NvmeDriverObject = DriverObject; 55 | 56 | //NvmeInitializeDispatchTable(); 57 | 58 | BSTATUS Status = HalPciEnumerate( 59 | false, 60 | 0, 61 | NULL, 62 | PCI_CLASS_MASS_STORAGE, 63 | PCI_SUBCLASS_NVM, 64 | NvmePciDeviceEnumerated, 65 | NULL 66 | ); 67 | 68 | if (Status == STATUS_NO_SUCH_DEVICES) 69 | Status = STATUS_UNLOAD; 70 | 71 | return Status; 72 | } 73 | -------------------------------------------------------------------------------- /drivers/test/Makefile: -------------------------------------------------------------------------------- 1 | # The Boron Operating System 2 | # Common makefile for all driver targets 3 | 4 | DRIVER_NAME = test 5 | # DRIVER_ENTRY = DriverEntry 6 | # DEBUG = yes 7 | # DEBUG2 = no 8 | 9 | include ../CommonMakefile 10 | -------------------------------------------------------------------------------- /drivers/test/linker.ld: -------------------------------------------------------------------------------- 1 | /* Tell the linker that we want an x86_64 ELF64 output file */ 2 | OUTPUT_FORMAT(elf64-x86-64) 3 | OUTPUT_ARCH(i386:x86-64) 4 | 5 | /* We want the symbol DriverEntry to be our entry point */ 6 | ENTRY(DriverEntry) 7 | 8 | /* Define the program headers we want so the bootloader gives us the right */ 9 | /* MMU permissions */ 10 | PHDRS 11 | { 12 | text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ 13 | rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ 14 | data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ 15 | } 16 | 17 | SECTIONS 18 | { 19 | /* We want to be placed in the topmost 2GiB of the address space, for optimizations, and because that is what the Limine spec mandates. */ 20 | /* Any address in this region will do, but often 0xffffffff80000000 is chosen as that is the beginning of the region. */ 21 | . = 0xffffffff80000000; 22 | 23 | .text : { 24 | *(.text .text.*) 25 | } :text 26 | 27 | /* Move to the next memory page for .rodata */ 28 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 29 | 30 | .rodata : { 31 | *(.rodata .rodata.*) 32 | } :rodata 33 | 34 | /* Move to the next memory page for .data */ 35 | . = ALIGN(CONSTANT(MAXPAGESIZE)); 36 | 37 | /* Global constructor array. */ 38 | .init_array : { 39 | g_init_array_start = .; 40 | *(.init_array) 41 | g_init_array_end = .; 42 | } 43 | 44 | /* Global destructor array. */ 45 | .fini_array : { 46 | g_fini_array_start = .; 47 | *(.fini_array) 48 | g_fini_array_end = .; 49 | } 50 | 51 | .data : { 52 | *(.data .data.*) 53 | } :data 54 | 55 | .bss : { 56 | *(COMMON) 57 | *(.bss .bss.*) 58 | } :data 59 | 60 | /* Discard .note.* and .eh_frame since they may cause issues on some hosts. */ 61 | /DISCARD/ : { 62 | *(.eh_frame) 63 | *(.note .note.*) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /drivers/test/source/apctst.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | apctst.c 7 | 8 | Abstract: 9 | This module implements the APC test for the test driver. 10 | 11 | Author: 12 | iProgramInCpp - 24 February 2024 13 | ***/ 14 | #include "utils.h" 15 | #include 16 | 17 | static KEVENT Event; 18 | 19 | static void ApcSpecialRoutine(UNUSED PKAPC Apc, UNUSED PKAPC_NORMAL_ROUTINE* R, UNUSED void** A, UNUSED void** B, UNUSED void** C) 20 | { 21 | LogMsg("Hello from ApcSpecialRoutine! I'm coming from %p", KeGetCurrentThread()); 22 | } 23 | 24 | static void ApcNormalRoutine(UNUSED void* Context, UNUSED void* SystemArgument1, UNUSED void* SystemArgument2) 25 | { 26 | LogMsg("Hello from ApcNormalRoutine! I'm coming from %p", KeGetCurrentThread()); 27 | 28 | KeSetEvent(&Event, 1); 29 | } 30 | 31 | static NO_RETURN void ApcTestRoutine() 32 | { 33 | LogMsg("Hello from ApcTestRoutine! My thread ptr is %p", KeGetCurrentThread()); 34 | 35 | KeInitializeEvent(&Event, EVENT_SYNCHRONIZATION, false); 36 | 37 | KeWaitForSingleObject(&Event, false, TIMEOUT_INFINITE, MODE_KERNEL); 38 | 39 | LogMsg("Exiting"); 40 | 41 | KeTerminateThread(1); 42 | 43 | /* 44 | while (true) { 45 | ASM("hlt"); 46 | }*/ 47 | } 48 | 49 | void PerformApcTest() 50 | { 51 | KTHREAD Thread; 52 | KeInitializeThread(&Thread, NULL, ApcTestRoutine, NULL, KeGetCurrentProcess()); 53 | KeReadyThread(&Thread); 54 | 55 | // wait a bit. 56 | PerformDelay(1000, NULL); 57 | 58 | KAPC Apc; 59 | LogMsg("Initializing APC..."); 60 | KeInitializeApc(&Apc, &Thread, ApcSpecialRoutine, ApcNormalRoutine, NULL, MODE_KERNEL); 61 | LogMsg("Enqueuing APC..."); 62 | KeInsertQueueApc(&Apc, NULL, NULL, 0); 63 | 64 | LogMsg("Done, should execute now. Waiting for the thread to exit..."); 65 | 66 | KeWaitForSingleObject(&Thread, false, TIMEOUT_INFINITE, MODE_KERNEL); 67 | } 68 | -------------------------------------------------------------------------------- /drivers/test/source/ccbtst.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | ccbtst.c 7 | 8 | Abstract: 9 | This module implements the CCB test for the test driver. 10 | It tests the functionality of the CCB (cache control block). 11 | 12 | Author: 13 | iProgramInCpp - 26 August 2024 14 | ***/ 15 | #include 16 | #include 17 | #include "utils.h" 18 | 19 | void PerformCcbTest() 20 | { 21 | LogMsg("Delaying half a second"); 22 | PerformDelay(500, NULL); 23 | 24 | CCB Ccb; 25 | MmInitializeCcb(&Ccb); 26 | 27 | const int Off = 5; 28 | 29 | MmLockCcb(&Ccb); 30 | 31 | PCCB_ENTRY Entry1 = MmGetEntryPointerCcb(&Ccb, Off + 0, true); 32 | PCCB_ENTRY Entry2 = MmGetEntryPointerCcb(&Ccb, Off + 12, true); 33 | PCCB_ENTRY Entry3 = MmGetEntryPointerCcb(&Ccb, Off + 1024LL + 12, true); 34 | PCCB_ENTRY Entry4 = MmGetEntryPointerCcb(&Ccb, Off + 1024LL * 1024 + 1024 + 12, true); 35 | // L4: PCCB_ENTRY Entry5 = MmGetEntryPointerCcb(&Ccb, Off + 1024LL * 1024 * 1024 + 1024 * 1024 + 1024 + 12, true); 36 | // L5: PCCB_ENTRY Entry6 = MmGetEntryPointerCcb(&Ccb, Off + 1024LL * 1024 * 1024 * 1024 + 1024 * 1024 * 1024 + 1024 * 1024 + 1024 + 12, true); 37 | 38 | LogMsg("Ccb: %p", &Ccb); 39 | LogMsg("Entry1: %p", Entry1); 40 | LogMsg("Entry2: %p", Entry2); 41 | LogMsg("Entry3: %p", Entry3); 42 | LogMsg("Entry4: %p", Entry4); 43 | // L4: LogMsg("Entry5: %p", Entry5); 44 | // L5: LogMsg("Entry6: %p", Entry6); 45 | 46 | MmUnlockCcb(&Ccb); 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /drivers/test/source/inttst.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2024 iProgramInCpp 4 | 5 | Module name: 6 | inttst.c 7 | 8 | Abstract: 9 | This module implements the interrupt dispatch test for 10 | the test driver. 11 | 12 | Author: 13 | iProgramInCpp - 1 April 2024 14 | ***/ 15 | #include "utils.h" 16 | #include 17 | 18 | static KSPIN_LOCK Int1SyncLock; 19 | static KSPIN_LOCK Int2SyncLock; 20 | static KINTERRUPT Int1; 21 | static KINTERRUPT Int2; 22 | static bool Int1Fired, Int2Fired; 23 | 24 | void Int1Routine(PKINTERRUPT Int, void* Ctx) 25 | { 26 | DbgPrint("Int1Routine (%p, %p)!", Int, Ctx); 27 | Int1Fired = true; 28 | } 29 | 30 | void Int2Routine(PKINTERRUPT Int, void* Ctx) 31 | { 32 | DbgPrint("Int2Routine (%p, %p)!", Int, Ctx); 33 | Int2Fired = true; 34 | } 35 | 36 | void PerformIntTest() 37 | { 38 | // Test 1. 39 | Int1Fired = Int2Fired = false; 40 | 41 | KeInitializeInterrupt(&Int1, Int1Routine, NULL, &Int1SyncLock, 0x80, 0x8, true); 42 | KeInitializeInterrupt(&Int2, Int2Routine, NULL, &Int2SyncLock, 0x80, 0x8, true); 43 | 44 | if (!KeConnectInterrupt(&Int1)) KeCrash("Test fail: cannot connect Int1 (first test)"); 45 | if (!KeConnectInterrupt(&Int2)) KeCrash("Test fail: cannot connect Int2 (first test)"); 46 | 47 | ASM("int $0x80":::"memory"); 48 | 49 | if (!Int1Fired) KeCrash("Test fail: int1 not fired (first test)"); 50 | if (!Int2Fired) KeCrash("Test fail: int2 not fired (first test)"); 51 | 52 | KeDisconnectInterrupt(&Int1); 53 | KeDisconnectInterrupt(&Int2); 54 | 55 | // Test 2. 56 | Int1Fired = Int2Fired = false; 57 | 58 | KeInitializeInterrupt(&Int1, Int1Routine, NULL, &Int1SyncLock, 0x80, 0x8, false); 59 | KeInitializeInterrupt(&Int2, Int2Routine, NULL, &Int2SyncLock, 0x80, 0x8, false); 60 | 61 | if (!KeConnectInterrupt(&Int1)) KeCrash("Test fail: cannot connect int1 (second test)"); 62 | if ( KeConnectInterrupt(&Int2)) KeCrash("Test fail: can connect int2 (second test)"); 63 | 64 | ASM("int $0x80":::"memory"); 65 | 66 | if (!Int1Fired) KeCrash("Test fail: int1 not fired (second test)"); 67 | if ( Int2Fired) KeCrash("Test fail: int2 fired (second test)"); 68 | 69 | KeDisconnectInterrupt(&Int1); 70 | } 71 | -------------------------------------------------------------------------------- /drivers/test/source/iotst.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2025 iProgramInCpp 4 | 5 | Module name: 6 | iotst.c 7 | 8 | Abstract: 9 | This module implements the I/O test. 10 | 11 | This tests the CreateFile, OpenFile, ReadFile, and WriteFile 12 | APIs. Later it will also test CreateSectionFromFile, 13 | MapViewOfSection, UnmapViewOfSection, MapViewOfFile, and 14 | UnmapViewOfFile. Except that these APIs may or may not 15 | exist, who knows. 16 | 17 | Author: 18 | iProgramInCpp - 14 March 2025 19 | ***/ 20 | #include 21 | 22 | void PerformIoTest() 23 | { 24 | 25 | } 26 | -------------------------------------------------------------------------------- /drivers/test/source/mutextst.c: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | mutextst.c 7 | 8 | Abstract: 9 | This module implements the mutex test for the test driver. 10 | 11 | Author: 12 | iProgramInCpp - 19 November 2023 13 | ***/ 14 | #include "utils.h" 15 | 16 | // Convert an integer to a void* to pass in to the start routine. 17 | // Won't be used as an actual pointer. 18 | #define P(n) ((void*) (uintptr_t) (n)) 19 | 20 | // Global mutex used in the test. 21 | static KMUTEX TestMutex; 22 | static KMUTEX TestMutex2; 23 | 24 | #define DELAY (100) 25 | 26 | NO_RETURN static void MutexTestThread(UNUSED void* Parameter) 27 | { 28 | int ThreadNum = (int)(uintptr_t)Parameter; 29 | 30 | DbgPrint("Hello from MutexTestThread #%d", ThreadNum); 31 | 32 | for (int i = 0; i < 10; i++) 33 | { 34 | LogMsg("Thread %d Acquiring Mutexes...", ThreadNum); 35 | 36 | // Acquire the mutexes. 37 | void* Objects[] = { &TestMutex, &TestMutex2 }; 38 | KeWaitForMultipleObjects(2, Objects, WAIT_TYPE_ALL, false, TIMEOUT_INFINITE, NULL, MODE_KERNEL); 39 | 40 | LogMsg("Thread %d Waiting %d ms...", ThreadNum, DELAY); 41 | // Wait a second. 42 | KTIMER Timer; 43 | KeInitializeTimer(&Timer); 44 | KeSetTimer(&Timer, DELAY, NULL); 45 | KeWaitForSingleObject(&Timer, false, TIMEOUT_INFINITE, MODE_KERNEL); 46 | 47 | // Finally, release the mutexes. 48 | LogMsg("Thread %d Releasing Mutexes...", ThreadNum); 49 | KeReleaseMutex(&TestMutex); 50 | KeReleaseMutex(&TestMutex2); 51 | } 52 | 53 | KeTerminateThread(0); 54 | } 55 | 56 | void PerformMutexTest() 57 | { 58 | KeInitializeMutex(&TestMutex, 1); 59 | KeInitializeMutex(&TestMutex2, 1); 60 | 61 | PKTHREAD Thrd1 = CreateThread(MutexTestThread, P(1)); 62 | PKTHREAD Thrd2 = CreateThread(MutexTestThread, P(2)); 63 | 64 | void* Objects[] = 65 | { 66 | Thrd1, 67 | Thrd2 68 | }; 69 | 70 | // Wait for all threads to exit. 71 | KeWaitForMultipleObjects(2, Objects, WAIT_TYPE_ALL, false, TIMEOUT_INFINITE, NULL, MODE_KERNEL); 72 | 73 | // Get rid of the threads. 74 | ObDereferenceObject(Thrd1); 75 | ObDereferenceObject(Thrd2); 76 | 77 | LogMsg("*** All threads have exited."); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /drivers/test/source/tests.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | tests.h 7 | 8 | Abstract: 9 | This header file provides forward declarations for testing 10 | functions in the test driver module. 11 | 12 | Author: 13 | iProgramInCpp - 19 November 2023 14 | ***/ 15 | #pragma once 16 | 17 | void PerformMutexTest(void); 18 | void PerformBallTest(void); 19 | void PerformProcessTest(void); 20 | void PerformFireworksTest(void); 21 | void PerformHandleTest(void); 22 | void PerformRwlockTest(void); 23 | void PerformObjectTest(void); 24 | void PerformMdlTest(void); 25 | void PerformApcTest(void); 26 | void PerformIntTest(void); 27 | void PerformKeyboardTest(void); 28 | void PerformStorageTest(void); 29 | void PerformExObTest(void); 30 | void PerformCcbTest(void); 31 | void PerformMm1Test(void); 32 | void PerformMm2Test(void); 33 | void PerformMm3Test(void); 34 | void PerformMm4Test(void); 35 | -------------------------------------------------------------------------------- /drivers/test/source/utils.h: -------------------------------------------------------------------------------- 1 | /*** 2 | The Boron Operating System 3 | Copyright (C) 2023 iProgramInCpp 4 | 5 | Module name: 6 | utils.h 7 | 8 | Abstract: 9 | This header file provides forward declarations for utilitary 10 | functions in the test driver module. 11 | 12 | Author: 13 | iProgramInCpp - 19 November 2023 14 | ***/ 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | // Create a simple thread. 21 | // 22 | // Use ObDereferenceObject on the thread pointer to detach and/or free! 23 | PKTHREAD CreateThread(PKTHREAD_START StartRoutine, void* Parameter); 24 | 25 | // Performs a small delay. 26 | void PerformDelay(int Ms, PKDPC Dpc); 27 | 28 | // Performs a hex dump of some memory. 29 | void DumpHex(void* DataV, size_t DataSize, bool LogScreen); 30 | -------------------------------------------------------------------------------- /images/2023-10-15 12-03-52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramMC/Boron/fefe24e1d08a1e2b7f02a5abe724f8b8aed624a5/images/2023-10-15 12-03-52.png -------------------------------------------------------------------------------- /images/2023-10-15 12-05-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramMC/Boron/fefe24e1d08a1e2b7f02a5abe724f8b8aed624a5/images/2023-10-15 12-05-14.png -------------------------------------------------------------------------------- /images/2023-10-24 22-40-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramMC/Boron/fefe24e1d08a1e2b7f02a5abe724f8b8aed624a5/images/2023-10-24 22-40-20.png -------------------------------------------------------------------------------- /images/2023-10-25 21-15-25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramMC/Boron/fefe24e1d08a1e2b7f02a5abe724f8b8aed624a5/images/2023-10-25 21-15-25.png -------------------------------------------------------------------------------- /images/2023-10-28 19-41-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramMC/Boron/fefe24e1d08a1e2b7f02a5abe724f8b8aed624a5/images/2023-10-28 19-41-04.png -------------------------------------------------------------------------------- /images/2024-06-23 12-06-27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramMC/Boron/fefe24e1d08a1e2b7f02a5abe724f8b8aed624a5/images/2024-06-23 12-06-27.png -------------------------------------------------------------------------------- /images/2024-06-23 12-07-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramMC/Boron/fefe24e1d08a1e2b7f02a5abe724f8b8aed624a5/images/2024-06-23 12-07-01.png -------------------------------------------------------------------------------- /limine.cfg: -------------------------------------------------------------------------------- 1 | TIMEOUT=3 2 | VERBOSE=yes 3 | 4 | :The Boron Operating System 5 | PROTOCOL=limine 6 | KERNEL_PATH=boot:///kernel.elf 7 | MODULE_PATH=boot:///libboron.so 8 | MODULE_PATH=boot:///halx86.sys 9 | MODULE_PATH=boot:///i8042prt.sys 10 | MODULE_PATH=boot:///stornvme.sys 11 | #MODULE_PATH=boot:///ext2fs.sys 12 | MODULE_PATH=boot:///test.sys 13 | -------------------------------------------------------------------------------- /run-unix.sh: -------------------------------------------------------------------------------- 1 | qemu-system-x86_64 \ 2 | -no-reboot \ 3 | -no-shutdown \ 4 | -M q35 \ 5 | -m 256M \ 6 | -smp 4 \ 7 | -boot d \ 8 | -cdrom build/image.iso \ 9 | -debugcon stdio 10 | -------------------------------------------------------------------------------- /run.bat: -------------------------------------------------------------------------------- 1 | @rem Run script 2 | 3 | @echo off 4 | 5 | set backupPath=%path% 6 | set NSPath=%CD% 7 | cd /d c:\Program Files\qemu 8 | set path=%path%;%NSPath% 9 | 10 | if exist %nspath%\vdiske2.vdi ( 11 | set DriveOptions=-cdrom %nspath%\build\image.iso -drive id=nvm,file=%nspath%\vdiske2.vdi,if=none -device nvme,serial=deadbeef,drive=nvm 12 | ) else ( 13 | set DriveOptions=-cdrom %nspath%\build\image.iso 14 | ) 15 | 16 | qemu-system-x86_64.exe -no-reboot -no-shutdown -d int -M smm=off ^ 17 | -M q35 ^ 18 | -m 256M ^ 19 | -smp 6 ^ 20 | -boot d ^ 21 | -display sdl ^ 22 | -accel tcg ^ 23 | -monitor telnet:127.0.0.1:56789,server,nowait ^ 24 | -debugcon stdio ^ 25 | -trace *nvme* -trace *msi* -D %nspath%\keep\nvmelog.txt ^ 26 | -s ^ 27 | %DriveOptions% 28 | 29 | :-debugcon stdio ^ 30 | :-d cpu_reset ^ 31 | : -s -S -- for debugging with GDB 32 | : -serial COM7 -- to output the serial port to somewhere real 33 | : -kernel %nspath%/kernel.bin 34 | : -debugcon stdio 35 | : -monitor telnet:127.0.0.1:55555,server,nowait -- to use the QEMU console 36 | : 37 | :-d int ^ 38 | :-D %nspath%\keep/things.txt ^ 39 | :qemu-system-i386 -m 16M -drive file=\\.\PHYSICALDRIVE1,format=raw 40 | rem -s -S 41 | 42 | :-drive id=disk,file=%nspath%\vdisk.vdi,if=none ^ 43 | :-device ahci,id=ahci ^ 44 | :-device ide-hd,drive=disk,bus=ahci.0 ^ 45 | 46 | rem go back 47 | cd /d %NSPath% 48 | 49 | set path=%backupPath% 50 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | # works only in wsl :) 2 | 3 | cmd.exe /k "run.bat && exit" 4 | --------------------------------------------------------------------------------