├── .gitignore
├── .gitmodules
├── .vscode
└── launch.json
├── CMakeLists.txt
├── LICENSE
├── README.md
├── documentation
├── Doxyfile
├── Doxyfile_Syscalls
├── driver_communication.md
└── signals.md
├── isodir
├── EFI
│ └── BOOT
│ │ ├── BOOTAA64.EFI
│ │ └── BOOTIA32.EFI
├── limine.cfg
├── limine
│ ├── limine-bios-cd.bin
│ ├── limine-bios-pxe.bin
│ ├── limine-bios.sys
│ └── limine-uefi-cd.bin
├── obos
│ ├── font.bin
│ ├── initrd.tar
│ ├── initrd
│ │ ├── boot.cfg
│ │ ├── fatDriver
│ │ ├── gptDriver
│ │ ├── mbrDriver
│ │ ├── obos
│ │ │ └── init
│ │ ├── ps2KeyboardDriver
│ │ └── sataDriver
│ ├── initrdDriver
│ └── oboskrnl
└── testProgram
├── out
├── acpiDriver
├── fatDriver
├── gptDriver
├── init
├── initrdDriver
├── mbrDriver
├── obos.iso
├── oboskrnl
├── ps2KeyboardDriver
├── sataDriver
└── test_program
├── ovmf
├── OVMF_CODE_4M.fd
└── OVMF_VARS_4M.fd
├── screenshots
├── 1511_2023-11-11.png
├── 2023-11-13_20-59.png
├── 2023-12-02_1126.png
├── 2023-12-03_0937.png
├── 20230112_2053.png
├── 20231128_1838.png
├── 20231213_2020.png
├── 20231224_1909.png
├── 20231225_1914.png
├── 20231228_1202.png
├── 20231228_1951.png
├── 20231229_0831.png
├── 2023_12_10-1143.png
├── 2023_12_10-1149.png
├── 2023_12_10-1204.png
├── 20240103_1012.png
├── 20240103_1025.png
├── 20240103_1134.png
├── 20240104_0905.png
├── 20240116_1903.png
├── 20240116_1921.png
├── 20240117_1630.png
├── 20240117_1950.png
├── 20240117_1954.png
├── 20240120_2042.png
├── 20240121_0726.png
├── 20240121_1932.png
├── 20240126_0826.png
├── 20240126_0932.png
├── 20240126_0938.png
├── 20240126_0943.png
├── 20240126_1028.png
├── 2024012_1028.png
├── 20240201_2005.png
├── 20240201_2014.png
├── initrd_driver-reading.png
├── initrd_driver-working.png
├── kpanic_2023-10-12_0437PM.png
├── kpanic_2023-10-29.png
├── multitasking_1.png
├── new_kpanic-2023_10_28.png
├── smp_try1.png
├── vfs_test-2023-11-04.png
└── vfs_test-2023-11-04_2.png
├── scripts
├── .gdbinit
├── find_addr.sh
├── launch_qemu.bat
├── launch_qemu.sh
├── make_initrd.bat
└── make_initrd.sh
└── src
├── drivers
├── generic
│ ├── acpi
│ │ ├── CMakeLists.txt
│ │ ├── impl.cpp
│ │ ├── main.cpp
│ │ ├── makeshift_include
│ │ │ ├── inttypes.h
│ │ │ ├── stdio.h
│ │ │ ├── stdlib.h
│ │ │ ├── string.h
│ │ │ └── uacpi_arch_helpers.h
│ │ └── stdlib_impl.cpp
│ ├── common
│ │ └── new.cpp
│ ├── fat
│ │ ├── CMakeLists.txt
│ │ ├── cache.cpp
│ │ ├── cache.h
│ │ ├── fat32_structs.h
│ │ ├── fat_structs.h
│ │ ├── interface.cpp
│ │ └── main.cpp
│ ├── gpt
│ │ ├── CMakeLists.txt
│ │ └── main.cpp
│ └── initrd
│ │ ├── CMakeLists.txt
│ │ ├── interface.cpp
│ │ ├── interface.h
│ │ ├── main.cpp
│ │ ├── parse.cpp
│ │ └── parse.h
└── x86_64
│ ├── mbr
│ ├── CMakeLists.txt
│ └── main.cpp
│ ├── ps2Keyboard
│ ├── CMakeLists.txt
│ ├── dmain.cpp
│ ├── scancodes.cpp
│ └── scancodes.h
│ └── sata
│ ├── CMakeLists.txt
│ ├── command.cpp
│ ├── command.h
│ ├── interface.cpp
│ ├── main.cpp
│ └── structs.h
├── oboskrnl
├── CMakeLists.txt
├── allocators
│ ├── liballoc.cpp
│ ├── liballoc.h
│ ├── slab.cpp
│ ├── slab.h
│ └── vmm
│ │ ├── arch.h
│ │ ├── vmm.cpp
│ │ └── vmm.h
├── arch
│ ├── interrupt.h
│ └── x86_64
│ │ ├── exception_handlers.cpp
│ │ ├── fpu.asm
│ │ ├── gdbstub
│ │ ├── communicate.cpp
│ │ ├── communicate.h
│ │ ├── stub.cpp
│ │ └── stub.h
│ │ ├── gdt.asm
│ │ ├── gdt.cpp
│ │ ├── idt.asm
│ │ ├── idt.cpp
│ │ ├── int_handlers.asm
│ │ ├── interrupt.h
│ │ ├── irq
│ │ ├── acpi.h
│ │ ├── irq.cpp
│ │ ├── irq.h
│ │ ├── timer.cpp
│ │ └── timer.h
│ │ ├── memory_manager
│ │ ├── physical
│ │ │ ├── allocate.h
│ │ │ ├── allocatePhys.cpp
│ │ │ └── allocate_old.cpp
│ │ └── virtual
│ │ │ ├── allocate.cpp
│ │ │ ├── initialize.cpp
│ │ │ ├── initialize.h
│ │ │ ├── internal.cpp
│ │ │ ├── internal.h
│ │ │ └── mapFile.cpp
│ │ ├── signals.cpp
│ │ ├── smp_start.cpp
│ │ ├── smp_trampoline.asm
│ │ ├── sse.asm
│ │ ├── stack_canary.cpp
│ │ ├── syscall
│ │ ├── console.h
│ │ ├── handle.cpp
│ │ ├── handle.h
│ │ ├── power_management.cpp
│ │ ├── power_management.h
│ │ ├── register.cpp
│ │ ├── register.h
│ │ ├── sconsole.cpp
│ │ ├── signals.h
│ │ ├── sys_signals.cpp
│ │ ├── syscall_vmm.cpp
│ │ ├── thread.cpp
│ │ ├── thread.h
│ │ ├── verify_pars.cpp
│ │ ├── verify_pars.h
│ │ ├── vfs
│ │ │ ├── dir.cpp
│ │ │ ├── dir.h
│ │ │ ├── disk.cpp
│ │ │ ├── disk.h
│ │ │ ├── file.cpp
│ │ │ └── file.h
│ │ └── vmm.h
│ │ └── trace.cpp
├── atomic.h
├── boot
│ ├── cfg.cpp
│ ├── cfg.h
│ ├── kmain.cpp
│ └── x86_64
│ │ └── kmain_arch.cpp
├── console.cpp
├── console.h
├── driverInterface
│ ├── input_device.h
│ ├── load.h
│ ├── register.cpp
│ ├── register.h
│ ├── struct.h
│ └── x86_64
│ │ ├── enumerate_pci.cpp
│ │ ├── enumerate_pci.h
│ │ ├── load.cpp
│ │ └── scan.cpp
├── error.cpp
├── error.h
├── export.h
├── int.h
├── klog.cpp
├── klog.h
├── memory_manipulation.h
├── multitasking
│ ├── arch.h
│ ├── cpu_local.h
│ ├── locks
│ │ ├── mutex.cpp
│ │ └── mutex.h
│ ├── process
│ │ ├── arch.h
│ │ ├── process.cpp
│ │ ├── process.h
│ │ ├── signals.h
│ │ └── x86_64
│ │ │ ├── loader
│ │ │ ├── elf.cpp
│ │ │ ├── elf.h
│ │ │ └── elfStructures.h
│ │ │ ├── procInfo.cpp
│ │ │ └── procInfo.h
│ ├── scheduler.cpp
│ ├── scheduler.h
│ ├── thread.h
│ ├── threadAPI
│ │ ├── thrHandle.cpp
│ │ └── thrHandle.h
│ └── x86_64
│ │ ├── arch_structs.h
│ │ ├── calibrate_timer.asm
│ │ ├── calibrate_timer_old.asm
│ │ ├── scheduler_bootstrapper.cpp
│ │ ├── setupFrameInfo.cpp
│ │ └── taskSwitchImpl.asm
├── new
├── utils
│ ├── hashmap.h
│ ├── pair.h
│ ├── stack.h
│ ├── stb_sprintf.h
│ ├── string.cpp
│ ├── string.h
│ └── vector.h
├── vfs
│ ├── devManip
│ │ ├── driveHandle.cpp
│ │ ├── driveHandle.h
│ │ ├── driveIterator.cpp
│ │ ├── driveIterator.h
│ │ ├── memcpy.h
│ │ └── sectorStore.h
│ ├── fileManip
│ │ ├── directoryIterator.cpp
│ │ ├── directoryIterator.h
│ │ ├── fileHandle.cpp
│ │ └── fileHandle.h
│ ├── mount
│ │ ├── mount.cpp
│ │ └── mount.h
│ ├── off_t.h
│ └── vfsNode.h
└── x86_64-utils
│ ├── asm.asm
│ ├── asm.h
│ └── memory_manipulation.asm
├── programs
└── x86-64
│ ├── common
│ └── syscall.asm
│ ├── init
│ ├── CMakeLists.txt
│ ├── liballoc.cpp
│ ├── liballoc.h
│ ├── logger.cpp
│ ├── logger.h
│ ├── main.cpp
│ ├── new
│ ├── stb_sprintf.h
│ └── syscall.h
│ └── testProgram
│ ├── CMakeLists.txt
│ └── main.cpp
└── scripts-toolchains
└── x86_64
├── linker.ld
└── toolchain.cmake
/.gitignore:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio.
3 | ################################################################################
4 |
5 | /.vs
6 | /out/build
7 | /CMakePresets.json
8 | /oldCMakeSettings.json
9 | /out/Ubuntu
10 | /limine
11 | /qemu_log.txt
12 | /documentation/html
13 | /qemu_log.txt
14 | /.vscode
15 | /.VSCodeCounter
16 | /build
17 | /scripts/copy_files_to_disk.bat
18 | /bck
19 | /disk.img
20 | /scripts/mount_disk_image.sh
21 | /scripts/umount_disk_image.sh
22 | /documentation/doxygen
23 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "src/drivers/generic/acpi/uACPI"]
2 | path = src/drivers/generic/acpi/uACPI
3 | url = https://github.com/UltraOS/uACPI.git
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "oboskrnl-qemu",
9 | "type": "cppdbg",
10 | "request": "launch",
11 | "cwd": ".",
12 | "program": "./out/oboskrnl",
13 | "MIMode": "gdb",
14 | "miDebuggerPath": "gdb",
15 | "targetArchitecture": "x64",
16 | "miDebuggerServerAddress": ":1234",
17 | "logging": {},
18 | "customLaunchSetupCommands": [
19 | {
20 | "description": "Set Disassembly Flavor to Intel",
21 | "text": "-gdb-set disassembly-flavor intel",
22 | "ignoreFailures": true
23 | },
24 | {
25 | "description": "Set architecture",
26 | "text": "-gdb-set architecture i386:x86_64",
27 | "ignoreFailures": true
28 | },
29 | {
30 | "description": "Connect to qemu",
31 | "text": "-target-select extended-remote localhost:1234"
32 | },
33 | {
34 | "description": "Load the kernel binary.",
35 | "text": "-file-exec-and-symbols /Code/obos/out/oboskrnl",
36 | "ignoreFailures": true
37 | },
38 | {
39 | "description": "Load the init program binary.",
40 | "text": "-file-exec-and-symbols /Code/obos/out/init",
41 | "ignoreFailures": false
42 | }
43 | ],
44 | },
45 | ]
46 | }
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # CMakeLists.txt
2 |
3 | # Copyright (c) 2023-2024 Omar Berrow
4 |
5 | cmake_minimum_required(VERSION 3.5)
6 |
7 | project(obos C CXX ASM_NASM)
8 |
9 | if (NOT DEFINED OUTPUT_DIR)
10 | set(OUTPUT_DIR "${CMAKE_SOURCE_DIR}/out")
11 | endif()
12 | if (NOT DEFINED GENERATE_BUILD_FILES_FOR_UNIX)
13 | set(GENERATE_BUILD_FILES_FOR_UNIX 1)
14 | endif()
15 | if (NOT DEFINED E9_HACK)
16 | if(CMAKE_BUILD_TYPE STREQUAL "Debug")
17 | set(E9_HACK "1")
18 | else()
19 | set(E9_HACK "0")
20 | endif()
21 | endif()
22 |
23 | if(CMAKE_BUILD_TYPE STREQUAL "Debug")
24 | set(DEBUG_SYMBOLS_OPT -g)
25 | else()
26 | set(DEBUG_SYMBOLS_OPT)
27 | endif()
28 |
29 | set (CXX_STANDARD 20)
30 |
31 | add_subdirectory("src/oboskrnl")
32 | add_subdirectory("src/drivers/generic/initrd")
33 | add_subdirectory("src/drivers/generic/gpt")
34 | add_subdirectory("src/drivers/generic/fat")
35 | add_subdirectory("src/drivers/generic/acpi")
36 | if (OBOS_ARCHITECTURE STREQUAL "x86_64")
37 | add_subdirectory("src/drivers/x86_64/sata")
38 | add_subdirectory("src/drivers/x86_64/mbr")
39 | add_subdirectory("src/drivers/x86_64/ps2Keyboard")
40 | add_subdirectory("src/programs/x86-64/init")
41 | endif()
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023-2024 Omar Berrow
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OBOS
2 | ## Goals
3 | - [x] A module loader/interface
4 | - [x] An initrd driver
5 | - [x] A VFS
6 | - [x] PS2 Keyboard driver
7 | - [x] AHCI Driver
8 | - [ ] NVME Driver.
9 | - [x] A FAT driver.
10 | - [ ] Ext2/3/4 Driver.
11 | - [ ] POSIX Compatibility Layer
12 | - [ ] Porting mlibc.
13 | - [ ] A terminal.
14 | - [ ] Support for USB.
15 | - [x] Support for ACPI power management.
16 | - [x] Making a GCC/Binutils target for the os.
17 | - [ ] Porting binutils and GCC to the os.
18 | - [ ] Porting CMake and Make.
19 | - [ ] Porting tar.
20 | - [ ] A network stack.
21 | - [ ] An audio stack.
22 | - [ ] A GUI.
23 | - [ ] Porting python.
24 | - [ ] Porting 7zip.
25 | - [ ] Porting a browser and curl.
26 | - [ ] Porting qemu.
27 | ## Building
28 | ### Prerequisites
29 | - CMake
30 | - Ninja
31 | - Make
32 | - xorriso
33 | - An x86_64-elf-gcc cross compiler if you are building for x86_64.
34 | - WSL2 if you are on windows.
35 | ### Build Instructions (x86_64)
36 | 1. Open a terminal (or WSL if on windows), and clone the GitHub repository with these commands:
37 | ```bash
38 | git clone https://github.com/oberrow/obos.git
39 | cd obos
40 | git clone https://github.com/limine-bootloader/limine.git --branch=v5.2023-20241006.0-binary --depth=1
41 | ```
42 | You can ignore any warnings.
43 | 2. Configure cmake with this command:
44 | ```bash
45 | cmake --toolchain src/scripts-toolchains/x86_64/toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -G Ninja .
46 | ```
47 | 3. Finally, build the kernel with these commands:
48 | ```bash
49 | make -C limine
50 | ninja -j 0
51 | ```
52 |
53 | The iso image will be stored in out/obos.iso
54 | If you have qemu installed, you can run a virtual machine with the os by running scripts/launch-qemu.sh
55 |
--------------------------------------------------------------------------------
/documentation/signals.md:
--------------------------------------------------------------------------------
1 | # OBOS Signals
2 | ## Definition
3 | A callback (much like an interrupt) called by the kernel on a certain condition (ex: page fault).
4 | ## Signal values.
5 | | Signal | Value | Reason for signal | Default action |
6 | |---------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|
7 | | SIGPF | 0x0000 | A page fault occurred that the kernel couldn't resolve (not related to demand paging or any VMM feature). | Kill the process. |
8 | | SIGPM | 0x0001 | Permission error. This occurs when the program tries to modify something other than memory that it is not allowed to modify. | Kill the process. |
9 | | SIGOF | 0x0002 | An integer overflow occurred | Kill the process. |
10 | | SIGME | 0x0003 | A math error occurred. This can occur on division by zero or any operation that involves math (like anything to do with floating point). This should not occur on integer overflow (see SIGOF). | Kill the process. |
11 | | SIGDG | 0x0004 | A debug exception occurred. This is architecture-specific. | Kill the process. |
12 | | SIGTIME | 0x0005 | A timer set by the thread finished. | Ignore |
13 | | SIGTERM | 0x0006 | A program made a request to terminate the program. This is provided so that the program can properly free any resources opened. | Kill the process. |
14 | | SIGINT | 0x0007 | A request to interrupt the process was made. | Kill the process. |
15 | | SIGUDOC | 0x0008 | An undefined opcode exception occurred. | Kill the process. |
16 | | SIGUEXC | 0x0009 | An exception with no signal happened. | Kill the process. |
--------------------------------------------------------------------------------
/isodir/EFI/BOOT/BOOTAA64.EFI:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/EFI/BOOT/BOOTAA64.EFI
--------------------------------------------------------------------------------
/isodir/EFI/BOOT/BOOTIA32.EFI:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/EFI/BOOT/BOOTIA32.EFI
--------------------------------------------------------------------------------
/isodir/limine.cfg:
--------------------------------------------------------------------------------
1 | # Timeout in seconds that Limine will use before automatically booting.
2 | TIMEOUT=1
3 | QUIET=yes
4 | DEFAULT_ENTRY=1
5 | RANDOMIZE_MEMORY=no
6 |
7 | :OBOS
8 | PROTOCOL=limine
9 |
10 | KASLR=no
11 |
12 | MODULE_PATH=boot:///obos/font.bin
13 | MODULE_PATH=boot:///obos/initrdDriver
14 | MODULE_PATH=boot:///obos/initrd.tar
15 | KERNEL_PATH=boot:///obos/oboskrnl
16 | :Next Bootable Disk
17 | PROTOCOL=chainload_next
--------------------------------------------------------------------------------
/isodir/limine/limine-bios-cd.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/limine/limine-bios-cd.bin
--------------------------------------------------------------------------------
/isodir/limine/limine-bios-pxe.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/limine/limine-bios-pxe.bin
--------------------------------------------------------------------------------
/isodir/limine/limine-bios.sys:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/limine/limine-bios.sys
--------------------------------------------------------------------------------
/isodir/limine/limine-uefi-cd.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/limine/limine-uefi-cd.bin
--------------------------------------------------------------------------------
/isodir/obos/font.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/obos/font.bin
--------------------------------------------------------------------------------
/isodir/obos/initrd.tar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/obos/initrd.tar
--------------------------------------------------------------------------------
/isodir/obos/initrd/boot.cfg:
--------------------------------------------------------------------------------
1 | # oboskrnl boot configuration file.
2 |
3 | # The filesystem drivers to load at boot, these must be in the initrd image.
4 | FS_DRIVERS=[ 0:/fatDriver ]
5 | # Whether to load only trusted drivers at boot.
6 | # TODO: Implement.
7 | TRUSTED_DRIVERS_ONLY=false
8 | # The init program to start before finishing early-kernel boot.
9 | # This can specify any valid mount point, not just the initrd like FS_DRIVERS.
10 | # Although, to know the valid mount points, you need to run the kernel and see the various mount points printed.
11 | INIT_PROGRAM=0:/obos/init
--------------------------------------------------------------------------------
/isodir/obos/initrd/fatDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/obos/initrd/fatDriver
--------------------------------------------------------------------------------
/isodir/obos/initrd/gptDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/obos/initrd/gptDriver
--------------------------------------------------------------------------------
/isodir/obos/initrd/mbrDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/obos/initrd/mbrDriver
--------------------------------------------------------------------------------
/isodir/obos/initrd/obos/init:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/obos/initrd/obos/init
--------------------------------------------------------------------------------
/isodir/obos/initrd/ps2KeyboardDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/obos/initrd/ps2KeyboardDriver
--------------------------------------------------------------------------------
/isodir/obos/initrd/sataDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/obos/initrd/sataDriver
--------------------------------------------------------------------------------
/isodir/obos/initrdDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/obos/initrdDriver
--------------------------------------------------------------------------------
/isodir/obos/oboskrnl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/obos/oboskrnl
--------------------------------------------------------------------------------
/isodir/testProgram:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/isodir/testProgram
--------------------------------------------------------------------------------
/out/acpiDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/out/acpiDriver
--------------------------------------------------------------------------------
/out/fatDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/out/fatDriver
--------------------------------------------------------------------------------
/out/gptDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/out/gptDriver
--------------------------------------------------------------------------------
/out/init:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/out/init
--------------------------------------------------------------------------------
/out/initrdDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/out/initrdDriver
--------------------------------------------------------------------------------
/out/mbrDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/out/mbrDriver
--------------------------------------------------------------------------------
/out/obos.iso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/out/obos.iso
--------------------------------------------------------------------------------
/out/oboskrnl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/out/oboskrnl
--------------------------------------------------------------------------------
/out/ps2KeyboardDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/out/ps2KeyboardDriver
--------------------------------------------------------------------------------
/out/sataDriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/out/sataDriver
--------------------------------------------------------------------------------
/out/test_program:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/out/test_program
--------------------------------------------------------------------------------
/ovmf/OVMF_CODE_4M.fd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/ovmf/OVMF_CODE_4M.fd
--------------------------------------------------------------------------------
/ovmf/OVMF_VARS_4M.fd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/ovmf/OVMF_VARS_4M.fd
--------------------------------------------------------------------------------
/screenshots/1511_2023-11-11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/1511_2023-11-11.png
--------------------------------------------------------------------------------
/screenshots/2023-11-13_20-59.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/2023-11-13_20-59.png
--------------------------------------------------------------------------------
/screenshots/2023-12-02_1126.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/2023-12-02_1126.png
--------------------------------------------------------------------------------
/screenshots/2023-12-03_0937.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/2023-12-03_0937.png
--------------------------------------------------------------------------------
/screenshots/20230112_2053.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20230112_2053.png
--------------------------------------------------------------------------------
/screenshots/20231128_1838.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20231128_1838.png
--------------------------------------------------------------------------------
/screenshots/20231213_2020.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20231213_2020.png
--------------------------------------------------------------------------------
/screenshots/20231224_1909.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20231224_1909.png
--------------------------------------------------------------------------------
/screenshots/20231225_1914.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20231225_1914.png
--------------------------------------------------------------------------------
/screenshots/20231228_1202.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20231228_1202.png
--------------------------------------------------------------------------------
/screenshots/20231228_1951.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20231228_1951.png
--------------------------------------------------------------------------------
/screenshots/20231229_0831.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20231229_0831.png
--------------------------------------------------------------------------------
/screenshots/2023_12_10-1143.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/2023_12_10-1143.png
--------------------------------------------------------------------------------
/screenshots/2023_12_10-1149.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/2023_12_10-1149.png
--------------------------------------------------------------------------------
/screenshots/2023_12_10-1204.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/2023_12_10-1204.png
--------------------------------------------------------------------------------
/screenshots/20240103_1012.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240103_1012.png
--------------------------------------------------------------------------------
/screenshots/20240103_1025.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240103_1025.png
--------------------------------------------------------------------------------
/screenshots/20240103_1134.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240103_1134.png
--------------------------------------------------------------------------------
/screenshots/20240104_0905.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240104_0905.png
--------------------------------------------------------------------------------
/screenshots/20240116_1903.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240116_1903.png
--------------------------------------------------------------------------------
/screenshots/20240116_1921.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240116_1921.png
--------------------------------------------------------------------------------
/screenshots/20240117_1630.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240117_1630.png
--------------------------------------------------------------------------------
/screenshots/20240117_1950.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240117_1950.png
--------------------------------------------------------------------------------
/screenshots/20240117_1954.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240117_1954.png
--------------------------------------------------------------------------------
/screenshots/20240120_2042.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240120_2042.png
--------------------------------------------------------------------------------
/screenshots/20240121_0726.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240121_0726.png
--------------------------------------------------------------------------------
/screenshots/20240121_1932.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240121_1932.png
--------------------------------------------------------------------------------
/screenshots/20240126_0826.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240126_0826.png
--------------------------------------------------------------------------------
/screenshots/20240126_0932.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240126_0932.png
--------------------------------------------------------------------------------
/screenshots/20240126_0938.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240126_0938.png
--------------------------------------------------------------------------------
/screenshots/20240126_0943.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240126_0943.png
--------------------------------------------------------------------------------
/screenshots/20240126_1028.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240126_1028.png
--------------------------------------------------------------------------------
/screenshots/2024012_1028.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/2024012_1028.png
--------------------------------------------------------------------------------
/screenshots/20240201_2005.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240201_2005.png
--------------------------------------------------------------------------------
/screenshots/20240201_2014.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/20240201_2014.png
--------------------------------------------------------------------------------
/screenshots/initrd_driver-reading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/initrd_driver-reading.png
--------------------------------------------------------------------------------
/screenshots/initrd_driver-working.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/initrd_driver-working.png
--------------------------------------------------------------------------------
/screenshots/kpanic_2023-10-12_0437PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/kpanic_2023-10-12_0437PM.png
--------------------------------------------------------------------------------
/screenshots/kpanic_2023-10-29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/kpanic_2023-10-29.png
--------------------------------------------------------------------------------
/screenshots/multitasking_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/multitasking_1.png
--------------------------------------------------------------------------------
/screenshots/new_kpanic-2023_10_28.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/new_kpanic-2023_10_28.png
--------------------------------------------------------------------------------
/screenshots/smp_try1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/smp_try1.png
--------------------------------------------------------------------------------
/screenshots/vfs_test-2023-11-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/vfs_test-2023-11-04.png
--------------------------------------------------------------------------------
/screenshots/vfs_test-2023-11-04_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos-old/d82cd2bd3e488f48e7c174040611a5dedb3ff93a/screenshots/vfs_test-2023-11-04_2.png
--------------------------------------------------------------------------------
/scripts/.gdbinit:
--------------------------------------------------------------------------------
1 | set architecture i386:x86-64
2 | target remote :1234
3 | b *0x80
4 | c
5 | file ../out/oboskrnl
--------------------------------------------------------------------------------
/scripts/find_addr.sh:
--------------------------------------------------------------------------------
1 | clear
2 |
3 | cd ..
4 | export address=$1
5 | export exe=$2
6 | if [ -z "$exe" ]
7 | then
8 | export exe=out/oboskrnl
9 | fi
10 | addr2line -e $exe -Cfpira 0x$address
11 | objdump -d $exe -C -M intel | grep --color -C 10 -n $address
12 | cd scripts
13 |
--------------------------------------------------------------------------------
/scripts/launch_qemu.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | cd ../
4 |
5 | del qemu_log.txt
6 |
7 | qemu-system-x86_64 ^
8 | -device ahci,id=ahci1 ^
9 | -drive id=disk1,file=out/obos.iso,if=none,format=raw -device ide-hd,drive=disk1,bus=ahci1.0 ^
10 | -drive id=disk2,file=disk.img,if=none,format=raw -device ide-hd,drive=disk2,bus=ahci1.1 ^
11 | -gdb tcp:0.0.0.0:1234 -S ^
12 | -m 1G ^
13 | -cpu qemu64,+nx,+pdpe1gb,+syscall,-fsgsbase,+smep,+smap,+sse,+sse2,+sse4.1,+sse4.2 ^
14 | -monitor stdio ^
15 | -debugcon file:CON ^
16 | -serial tcp:0.0.0.0:1534,server,nowait ^
17 | -smp cores=8,threads=1,sockets=1 ^
18 | -d int ^
19 | -D qemu_log.txt
20 | rem -drive if=pflash,format=raw,unit=1,file=ovmf/OVMF_VARS_4M.fd
21 | rem -drive if=pflash,format=raw,unit=0,file=ovmf/OVMF_CODE_4M.fd,readonly=on
22 | rem -M smm=off ^
23 | rem -no-reboot
24 | rem -no-shutdown
25 |
26 | cd scripts
--------------------------------------------------------------------------------
/scripts/launch_qemu.sh:
--------------------------------------------------------------------------------
1 | cd ../
2 |
3 | qemu-system-x86_64 \
4 | -drive id=disk1,file=out/obos.iso,if=none,format=raw -device ahci,id=ahci1 -device ide-hd,drive=disk1,bus=ahci1.0 \
5 | -drive id=disk2,file=disk.img,if=none,format=raw -device ide-hd,drive=disk2,bus=ahci1.1 \
6 | -gdb tcp:0.0.0.0:1234 -S \
7 | -m 1G \
8 | -cpu qemu64,+nx,+pdpe1gb,+syscall,+fsgsbase,+rdrand,+rdseed,+rdtscp,+smep,+smap \
9 | -monitor stdio \
10 | -debugcon file:/dev/stdout \
11 | -serial tcp:0.0.0.0:1534,server,nowait \
12 | -smp cores=4,threads=1,sockets=1 \
13 | -M smm=off \
14 | -d trace:*ahci*,int \
15 | -D qemu_log.txt
16 | # \
17 | # -no-reboot
18 | # -no-shutdown
19 | # -drive if=pflash,format=raw,unit=0,file=ovmf/OVMF_CODE_4M.fd,readonly=on \
20 | # -drive if=pflash,format=raw,unit=1,file=ovmf/OVMF_VARS_4M.fd \
21 |
22 | cd scripts
--------------------------------------------------------------------------------
/scripts/make_initrd.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | cd ../isodir/obos/initrd
3 | tar --format ustar -cf ..\initrd.tar *
4 | cd ../../../scripts
--------------------------------------------------------------------------------
/scripts/make_initrd.sh:
--------------------------------------------------------------------------------
1 | clear
2 | cd ../isodir/obos/initrd
3 | tar -H ustar -cf ../initrd.tar $(ls)
4 | cd ../../../scripts
--------------------------------------------------------------------------------
/src/drivers/generic/acpi/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/generic/acpi/CMakeLists.txt
2 |
3 | # Copyright (c) 2023-2024 Omar Berrow
4 |
5 | include("uACPI/uacpi.cmake")
6 |
7 | uacpi_add_sources()
8 |
9 | add_library(acpiDriver STATIC "main.cpp" "../common/new.cpp" ${UACPI_SOURCES} "impl.cpp" "stdlib_impl.cpp")
10 |
11 | target_compile_options(acpiDriver
12 | PRIVATE $<$:-fno-stack-protector -fno-stack-check -fno-lto>
13 | PRIVATE $<$:-fno-use-cxa-atexit>
14 | PRIVATE $<$:-fno-rtti>
15 | PRIVATE $<$:-nostdlib>
16 | PRIVATE $<$:-fno-exceptions>
17 | PRIVATE $<$:-ffreestanding>
18 | PRIVATE $<$:-Wall>
19 | PRIVATE $<$:-Wextra>
20 | PRIVATE $<$:${TARGET_COMPILE_OPTIONS_C}>
21 | PRIVATE $<$:${TARGET_COMPILE_OPTIONS_CPP}>
22 | PRIVATE "${DEBUG_SYMBOLS_OPT}"
23 | )
24 | set_property (TARGET acpiDriver PROPERTY CXX_STANDARD 20)
25 |
26 | set_target_properties(acpiDriver PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}")
27 |
28 | target_compile_definitions(acpiDriver PRIVATE OBOS_DRIVER=1 PRIVATE UACPI_OVERRIDE_ARCH_HELPERS=1)
29 |
30 | target_include_directories(acpiDriver PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl")
31 | target_include_directories(acpiDriver PRIVATE "${CMAKE_SOURCE_DIR}/limine")
32 | target_include_directories(acpiDriver PUBLIC "${CMAKE_SOURCE_DIR}/src/drivers/generic/acpi/makeshift_include")
33 | target_include_directories(acpiDriver PUBLIC ${UACPI_INCLUDES})
34 |
35 | target_link_options(acpiDriver
36 | PRIVATE "-ffreestanding"
37 | PRIVATE "-nostdlib"
38 | )
--------------------------------------------------------------------------------
/src/drivers/generic/acpi/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/generic/acpi/main.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #ifdef __x86_64__
15 | #include
16 | #endif
17 |
18 | extern "C"
19 | {
20 | #include
21 |
22 | #include
23 |
24 | #include
25 | #include
26 | }
27 |
28 | using namespace obos;
29 |
30 | #ifdef __GNUC__
31 | #define DEFINE_IN_SECTION __attribute__((section(OBOS_DRIVER_HEADER_SECTION_NAME)))
32 | #else
33 | #define DEFINE_IN_SECTION
34 | #endif
35 |
36 | namespace obos
37 | {
38 | extern OBOS_EXPORT volatile limine_rsdp_request rsdp_request;
39 | extern OBOS_EXPORT volatile limine_hhdm_request hhdm_offset;
40 | }
41 |
42 | #define verify_status(st) \
43 | if (st != UACPI_STATUS_OK)\
44 | obos::logger::panic(nullptr, "uACPI Failed! Status code: %d, error message: %s\n", st, uacpi_status_to_string(st));
45 |
46 | namespace obos
47 | {
48 | void InitializeUACPI()
49 | {
50 | uacpi_init_params params = {
51 | (uintptr_t)rsdp_request.response->address - hhdm_offset.response->offset,
52 | { UACPI_LOG_INFO, 0 }
53 | };
54 | uacpi_status st = uacpi_initialize(¶ms);
55 | verify_status(st);
56 |
57 | st = uacpi_namespace_load();
58 | verify_status(st);
59 |
60 | st = uacpi_namespace_initialize();
61 | verify_status(st);
62 | }
63 | bool EnterSleepState(int sleepState)
64 | {
65 | if (sleepState < 0 || sleepState > 5)
66 | return false;
67 | uacpi_status ret;
68 |
69 | ret = uacpi_prepare_for_sleep_state((uacpi_sleep_state)sleepState);
70 | if (uacpi_unlikely_error(ret))
71 | return false;
72 |
73 | #ifdef __x86_64__
74 | cli();
75 | #endif
76 | ret = uacpi_enter_sleep_state((uacpi_sleep_state)sleepState);
77 | #ifdef __x86_64__
78 | sti();
79 | #endif
80 | return ret == UACPI_STATUS_OK;
81 | // Keep this code as a souvenir of when uACPI didn't have sleep helpers when I (Omar Berrow) had implemented it.
82 | /*char objectName[5] = {};
83 | logger::sprintf(objectName, "_S%d_", sleepState);
84 | uacpi_object* ret = nullptr;
85 | uacpi_status st = uacpi_eval(nullptr, objectName, nullptr, &ret);
86 | if (st != UACPI_STATUS_OK)
87 | return false;
88 |
89 | auto* obj = uacpi_create_object(UACPI_OBJECT_INTEGER);
90 | obj->integer = sleepState;
91 | uacpi_args args{ &obj, 1 };
92 | st = uacpi_eval(nullptr, "_PTS", &args, nullptr);
93 | if (st != UACPI_STATUS_OK && st != UACPI_STATUS_NOT_FOUND)
94 | {
95 | uacpi_object_unref(obj);
96 | return false;
97 | }
98 |
99 | uacpi_table* t = nullptr;
100 | st = uacpi_table_find_by_type(UACPI_TABLE_TYPE_FADT, &t);
101 | if (st != UACPI_STATUS_OK)
102 | {
103 | uacpi_object_unref(obj);
104 | return false;
105 | }
106 | acpi_fadt* fadt = (acpi_fadt*)t->hdr;
107 | uacpi_handle pm1a_cnt_blk_hnd{}, pm1b_cnt_blk_hnd{};
108 | if (uacpi_kernel_io_map(fadt->pm1a_cnt_blk, 2, &pm1a_cnt_blk_hnd) != UACPI_STATUS_OK)
109 | return false;
110 | if (fadt->pm1b_cnt_blk)
111 | {
112 | if (uacpi_kernel_io_map(fadt->pm1b_cnt_blk, 2, &pm1b_cnt_blk_hnd) != UACPI_STATUS_OK)
113 | {
114 | uacpi_kernel_io_unmap(pm1b_cnt_blk_hnd);
115 | return false;
116 | }
117 | }
118 | uacpi_kernel_io_write(pm1a_cnt_blk_hnd, 0, 2, (ret->package->objects[0]->integer << 10) | ((uint64_t)1 << 13));
119 | if (fadt->pm1b_cnt_blk)
120 | uacpi_kernel_io_write(pm1b_cnt_blk_hnd, 0, 2, (ret->package->objects[1]->integer << 10) | ((uint64_t)1 << 13));
121 | uacpi_object_unref(obj);
122 | uacpi_kernel_io_unmap(pm1a_cnt_blk_hnd);
123 | if (fadt->pm1b_cnt_blk)
124 | uacpi_kernel_io_unmap(pm1b_cnt_blk_hnd);
125 | return true;*/
126 | }
127 |
128 | }
--------------------------------------------------------------------------------
/src/drivers/generic/acpi/makeshift_include/inttypes.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define PRIx64 "x"
4 | #define PRIX64 "X"
5 | #define PRIu64 "u"
--------------------------------------------------------------------------------
/src/drivers/generic/acpi/makeshift_include/stdio.h:
--------------------------------------------------------------------------------
1 | // Does nothing
--------------------------------------------------------------------------------
/src/drivers/generic/acpi/makeshift_include/stdlib.h:
--------------------------------------------------------------------------------
1 | // Does nothing
--------------------------------------------------------------------------------
/src/drivers/generic/acpi/makeshift_include/string.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #ifdef __cplusplus
6 | #define OBOS_EXTERN_C extern "C"
7 | #else
8 | #define OBOS_EXTERN_C
9 | #endif
10 |
11 | OBOS_EXTERN_C void* memcpy(void* src, const void* dest, size_t size);
12 | OBOS_EXTERN_C void* memset(void* dest, int val, size_t size);
13 | OBOS_EXTERN_C int memcmp(const void* p1, const void* p2, size_t cnt);
14 | OBOS_EXTERN_C int strncmp(const char* p1, const char* p2, size_t maxCnt);
15 | OBOS_EXTERN_C int strcmp(const char* p1, const char* p2);
16 | OBOS_EXTERN_C void* memmove(void* dest, const void* src, size_t size);
17 | OBOS_EXTERN_C size_t strnlen(const char* str, size_t maxCnt);
18 | OBOS_EXTERN_C size_t strlen(const char* str);
19 | OBOS_EXTERN_C uint64_t strtoull(const char* str, char** endptr, int base);
20 | OBOS_EXTERN_C int snprintf(char* dest, size_t maxLen, const char* format, ...);
--------------------------------------------------------------------------------
/src/drivers/generic/acpi/makeshift_include/uacpi_arch_helpers.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define UACPI_ARCH_FLUSH_CPU_CACHE() asm volatile("wbinvd")
--------------------------------------------------------------------------------
/src/drivers/generic/common/new.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/x86_64/common/new.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 |
9 | #include
10 |
11 | [[nodiscard]] void* operator new(size_t count) noexcept
12 | {
13 | return kmalloc(count);
14 | }
15 | [[nodiscard]] void* operator new[](size_t count) noexcept
16 | {
17 | return operator new(count);
18 | }
19 | void operator delete(void* block) noexcept
20 | {
21 | kfree(block);
22 | }
23 | void operator delete[](void* block) noexcept
24 | {
25 | kfree(block);
26 | }
27 | void operator delete(void* block, size_t)
28 | {
29 | kfree(block);
30 | }
31 | void operator delete[](void* block, size_t)
32 | {
33 | kfree(block);
34 | }
35 |
36 | [[nodiscard]] void* operator new(size_t, void* ptr) noexcept
37 | {
38 | return ptr;
39 | }
40 | [[nodiscard]] void* operator new[](size_t, void* ptr) noexcept
41 | {
42 | return ptr;
43 | }
44 | void operator delete(void*, void*) noexcept
45 | {}
46 | void operator delete[](void*, void*) noexcept
47 | {}
--------------------------------------------------------------------------------
/src/drivers/generic/fat/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/generic/fat/CMakeLists.txt
2 |
3 | # Copyright (c) 2023-2024 Omar Berrow
4 |
5 | add_executable(fatDriver "main.cpp" "../common/new.cpp" "cache.cpp" "interface.cpp")
6 |
7 | target_compile_options(fatDriver
8 | PRIVATE $<$:-fno-stack-protector -fno-stack-check -fno-lto>
9 | PRIVATE $<$:-fno-use-cxa-atexit>
10 | PRIVATE $<$:-fno-rtti>
11 | PRIVATE $<$:-nostdlib>
12 | PRIVATE $<$:-fno-exceptions>
13 | PRIVATE $<$:-ffreestanding>
14 | PRIVATE $<$:-Wall>
15 | PRIVATE $<$:-Wextra>
16 | PRIVATE $<$:-fPIE>
17 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_CPP}>
18 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
19 | PRIVATE "${DEBUG_SYMBOLS_OPT}"
20 | )
21 | set_property (TARGET fatDriver PROPERTY CXX_STANDARD 20)
22 |
23 | set_target_properties(fatDriver PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}")
24 |
25 | target_compile_definitions(fatDriver PRIVATE OBOS_DRIVER=1)
26 |
27 | target_include_directories(fatDriver PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl")
28 |
29 | target_link_options(fatDriver
30 | PRIVATE "-ffreestanding"
31 | PRIVATE "-nostdlib"
32 | PRIVATE "-pie"
33 | )
34 |
35 | add_dependencies(fatDriver oboskrnl)
--------------------------------------------------------------------------------
/src/drivers/generic/fat/cache.h:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/generic/fat/cache.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #define fat32FirstSectorOfCluster(cluster, bpb, first_data_sector) (uint32_t)((((cluster) - 2) * (bpb).sectorsPerCluster) + (first_data_sector))
15 |
16 | namespace fatDriver
17 | {
18 | struct cacheEntry
19 | {
20 | char* path = nullptr;
21 | uint8_t fileAttributes = 0; // See obos::driverInterface::fileAttributes
22 | size_t filesize = 0; // Shouldn't ever pass 0xffffffff because well, FAT32.
23 | obos::utils::Vector clusters; // Must be in growing order.
24 | struct partition* owner = nullptr;
25 | cacheEntry *next, *prev;
26 | };
27 | enum class fatType
28 | {
29 | INVALID,
30 | FAT12 = 12,
31 | FAT16 = 16,
32 | FAT32 = 32,
33 | };
34 | struct partition
35 | {
36 | uint32_t driveId = 0;
37 | uint32_t partitionId = 0;
38 | fatType fat_type = fatType::INVALID;
39 | cacheEntry *head = nullptr,
40 | *tail = nullptr;
41 | ::size_t nCacheEntries = 0;
42 | uint32_t FatSz = 0;
43 | uint32_t RootDirSectors = 0;
44 | uint32_t TotSec = 0;
45 | uint32_t DataSec = 0;
46 | uint32_t FirstDataSec = 0;
47 | uint32_t ClusterCount = 0;
48 | struct generic_bpb* bpb;
49 | };
50 | bool operator==(const partition& first, const partition& second);
51 | extern obos::utils::Vector g_partitions;
52 | typedef obos::utils::pair partitionIdPair;
53 | extern obos::utils::Hashmap g_partitionToIndex;
54 |
55 | void ProbeDrives();
56 | }
--------------------------------------------------------------------------------
/src/drivers/generic/fat/fat32_structs.h:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/generic/fat/fat32_structs.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | namespace fatDriver
12 | {
13 | struct ebpb_fat32
14 | {
15 | uint32_t sectorsPerFAT;
16 | uint16_t flags;
17 | uint8_t version[2]; // version[0]: Minor Version, version[1]: Major Version
18 | uint32_t rootDirectoryCluster;
19 | uint16_t fsInfoSector;
20 | uint16_t backupBootSector;
21 | byte resv1[12];
22 | uint8_t driveNumber;
23 | uint8_t resv2_or_ntFlags;
24 | uint8_t signature; // 0x28 or 0x29
25 | uint32_t volumeIDSerialNumber;
26 | char volumeLabel[11];
27 | char sysIdentifierString[8];
28 | uint8_t bootcode[420];
29 | uint16_t mbrSignature;
30 | } __attribute__((packed));
31 | }
--------------------------------------------------------------------------------
/src/drivers/generic/fat/fat_structs.h:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/generic/fat/fat_structs.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include "fat32_structs.h"
12 |
13 | namespace fatDriver
14 | {
15 | struct generic_bpb
16 | {
17 | uint8_t jmp[3];
18 | char oem_identifer[8];
19 | uint16_t bytesPerSector;
20 | uint8_t sectorsPerCluster;
21 | uint16_t nResvSectors;
22 | uint8_t nFats;
23 | uint16_t nRootDirectoryEntries;
24 | uint16_t totalSectorCountOnVolume16; // If zero, use totalSectorCountOnVolume32
25 | uint8_t mediaDescriptorType;
26 | uint16_t sectorsPerFAT;
27 | uint16_t sectorsPerTrack;
28 | uint16_t nHeadsSidesInMedia;
29 | uint32_t nHiddenSectors;
30 | uint32_t totalSectorCountOnVolume32;
31 | union
32 | {
33 | ebpb_fat32 fat32_ebpb;
34 | } ebpb;
35 | } __attribute__((packed));
36 | struct fat_timestamp
37 | {
38 | byte second : 5; // Multiply value by two for the actual value.
39 | byte minute : 6;
40 | byte hour : 5;
41 | } __attribute__((packed));
42 | struct fat_date
43 | {
44 | byte day : 5;
45 | byte month : 4;
46 | byte year1980 : 7;
47 | } __attribute__((packed));
48 | static_assert(sizeof(fat_date) == 2, "sizeof(fat_date) isn't 2 bytes.");
49 | static_assert(sizeof(fat_timestamp) == 2, "sizeof(fat_timestamp) isn't 2 bytes.");
50 | struct fat_dirEntry
51 | {
52 | enum fat_dirEntryType
53 | {
54 | READ_ONLY = 0x01,
55 | HIDDEN = 0x02,
56 | SYSTEM = 0x04,
57 | VOLUME_ID = 0x08,
58 | DIRECTORY = 0x10,
59 | ARCHIVE = 0x20,
60 | LFN = READ_ONLY|HIDDEN|SYSTEM|VOLUME_ID,
61 | };
62 | char fname[11];
63 | byte fAttribs;
64 | byte ntResv;
65 | byte creationTimeHunderthsSec;
66 | fat_timestamp creationTime;
67 | fat_date creationDate;
68 | fat_date accessDate;
69 | uint16_t cluster16_31;
70 | fat_timestamp modifyTime;
71 | fat_date modifyDate;
72 | uint16_t cluster0_15;
73 | uint32_t filesize;
74 | } __attribute__((packed));
75 | struct fat_lfn
76 | {
77 | uint8_t order; // To get the order, bitwise "and" with ~0x40. If (order & 0x40), the current LFN is the last.
78 | char16_t name1_5[5];
79 | uint8_t attribs; // Must be fat_dirEntry::LFN
80 | uint8_t type;
81 | uint8_t checksum;
82 | char16_t name6_11[6];
83 | uint16_t ignored;
84 | char16_t name12_13[2];
85 | } __attribute__((packed));
86 | static_assert(sizeof(generic_bpb) == 512, "sizeof(generic_bpb) isn't 512 bytes.");
87 | static_assert(sizeof(fat_dirEntry) == 32, "sizeof(fat_dirEntry) isn't 32 bytes.");
88 | static_assert(sizeof(fat_lfn) == 32, "sizeof(fat_dirEntry) isn't 32 bytes.");
89 | }
--------------------------------------------------------------------------------
/src/drivers/generic/fat/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/generic/fat/main.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 |
10 | #include
11 |
12 | #include
13 |
14 | #include
15 |
16 | #include "cache.h"
17 |
18 | using namespace obos;
19 |
20 | #ifdef __GNUC__
21 | #define DEFINE_IN_SECTION __attribute__((section(OBOS_DRIVER_HEADER_SECTION_NAME)))
22 | #else
23 | #define DEFINE_IN_SECTION
24 | #endif
25 |
26 | namespace fatDriver
27 | {
28 | bool QueryFileProperties(
29 | const char* path,
30 | uint32_t driveId, uint32_t partitionIdOnDrive,
31 | size_t* oFsizeBytes,
32 | driverInterface::fileAttributes* oFAttribs);
33 | bool FileIteratorCreate(
34 | uint32_t driveId, uint32_t partitionIdOnDrive,
35 | uintptr_t* oIter);
36 | bool FileIteratorNext(
37 | uintptr_t iter,
38 | const char** oFilepath,
39 | void(**freeFunction)(void* buf),
40 | size_t* oFsizeBytes,
41 | driverInterface::fileAttributes* oFAttribs);
42 | bool FileIteratorClose(uintptr_t iter);
43 | bool ReadFile(
44 | uint32_t driveId, uint32_t partitionIdOnDrive,
45 | const char* path,
46 | size_t nToSkip,
47 | size_t nToRead,
48 | char* buff);
49 | }
50 |
51 | driverInterface::driverHeader DEFINE_IN_SECTION g_driverHeader = {
52 | .magicNumber = obos::driverInterface::OBOS_DRIVER_HEADER_MAGIC,
53 | .driverId = 4,
54 | .driverType = obos::driverInterface::OBOS_SERVICE_TYPE_FILESYSTEM,
55 | .requests = driverInterface::driverHeader::REQUEST_SET_STACK_SIZE,
56 | .stackSize = 0x10000,
57 | .functionTable = {
58 | .GetServiceType = []()->driverInterface::serviceType { return driverInterface::serviceType::OBOS_SERVICE_TYPE_FILESYSTEM; },
59 | .serviceSpecific = {
60 | .filesystem = {
61 | .QueryFileProperties = fatDriver::QueryFileProperties,
62 | .FileIteratorCreate = fatDriver::FileIteratorCreate,
63 | .FileIteratorNext = fatDriver::FileIteratorNext,
64 | .FileIteratorClose = fatDriver::FileIteratorClose,
65 | .ReadFile = fatDriver::ReadFile,
66 | .unused = { nullptr,nullptr,nullptr,nullptr }
67 | }
68 | }
69 | }
70 | };
71 |
72 | extern "C" void _start()
73 | {
74 | logger::log("FAT Driver: Probing drives for FAT partitions.\n");
75 | fatDriver::ProbeDrives();
76 | g_driverHeader.driver_initialized = true;
77 | while (!g_driverHeader.driver_finished_loading);
78 | thread::ExitThread(0);
79 | }
80 |
--------------------------------------------------------------------------------
/src/drivers/generic/gpt/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/generic/gpt/CMakeLists.txt
2 |
3 | # Copyright (c) 2023-2024 Omar Berrow
4 |
5 | add_executable(gptDriver "main.cpp" "../common/new.cpp")
6 |
7 | target_compile_options(gptDriver
8 | PRIVATE $<$:-fno-stack-protector -fno-stack-check -fno-lto>
9 | PRIVATE $<$:-fno-use-cxa-atexit>
10 | PRIVATE $<$:-fno-rtti>
11 | PRIVATE $<$:-nostdlib>
12 | PRIVATE $<$:-fno-exceptions>
13 | PRIVATE $<$:-ffreestanding>
14 | PRIVATE $<$:-Wall>
15 | PRIVATE $<$:-Wextra>
16 | PRIVATE $<$:-fPIE>
17 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_CPP}>
18 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
19 | PRIVATE "${DEBUG_SYMBOLS_OPT}"
20 | )
21 | set_property (TARGET gptDriver PROPERTY CXX_STANDARD 20)
22 |
23 | set_target_properties(gptDriver PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}")
24 |
25 | target_compile_definitions(gptDriver PRIVATE OBOS_DRIVER=1)
26 |
27 | target_include_directories(gptDriver PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl")
28 |
29 | target_link_options(gptDriver
30 | PRIVATE "-ffreestanding"
31 | PRIVATE "-nostdlib"
32 | PRIVATE "-pie"
33 | )
34 |
35 | add_dependencies(gptDriver oboskrnl)
--------------------------------------------------------------------------------
/src/drivers/generic/initrd/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/generic/test/CMakeLists.txt
2 |
3 | # Copyright (c) 2023-2024 Omar Berrow
4 |
5 | add_executable(initrdDriver "main.cpp" "parse.cpp" "interface.cpp")
6 |
7 | target_compile_options(initrdDriver
8 | PRIVATE "-ffreestanding"
9 | PRIVATE "-nostdlib"
10 | PRIVATE "-fPIE"
11 | PRIVATE "-Wall"
12 | PRIVATE "-Wextra"
13 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_CPP}>
14 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
15 | PRIVATE "${DEBUG_SYMBOLS_OPT}"
16 | )
17 | set_property (TARGET initrdDriver PROPERTY CXX_STANDARD 20)
18 |
19 | set_target_properties(initrdDriver PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}")
20 |
21 | target_compile_definitions(initrdDriver PRIVATE OBOS_DRIVER=1)
22 |
23 | target_include_directories(initrdDriver PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl")
24 |
25 | target_link_options(initrdDriver
26 | PRIVATE "-ffreestanding"
27 | PRIVATE "-nostdlib"
28 | PRIVATE "-pie"
29 | )
30 |
31 | add_dependencies(initrdDriver oboskrnl)
--------------------------------------------------------------------------------
/src/drivers/generic/initrd/interface.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/generic/initrd/interface.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 |
10 | #include
11 |
12 | #include "interface.h"
13 | #include "parse.h"
14 |
15 | #include
16 |
17 | struct
18 | {
19 | fileIterator* head, * tail;
20 | size_t size;
21 | } g_iterators;
22 |
23 | namespace initrdInterface
24 | {
25 | bool QueryFileProperties(
26 | const char* path,
27 | uint32_t, uint32_t,
28 | size_t* oFsizeBytes,
29 | obos::driverInterface::fileAttributes* oFAttribs)
30 | {
31 | uint32_t fAttribs = 0;
32 | if (!::GetFileAttribute(path, oFsizeBytes, &fAttribs))
33 | {
34 | if (oFAttribs)
35 | *oFAttribs = obos::driverInterface::FILE_DOESNT_EXIST;
36 | if (oFsizeBytes)
37 | *oFsizeBytes = 0;
38 | return false;
39 | }
40 | if (oFAttribs)
41 | *oFAttribs = (obos::driverInterface::fileAttributes)fAttribs;
42 | return true;
43 |
44 | }
45 | bool IterCreate(
46 | uint32_t, uint32_t,
47 | uintptr_t* oIter)
48 | {
49 | fileIterator* iter = (fileIterator*)kcalloc(1, sizeof(fileIterator));
50 | if (!iter)
51 | return false;
52 | iter->currentNode = g_filesystemCache.head;
53 | if (g_iterators.tail)
54 | g_iterators.tail->next = iter;
55 | if (!g_iterators.head)
56 | g_iterators.head = iter;
57 | iter->prev = g_iterators.tail;
58 | g_iterators.tail = iter;
59 | g_iterators.size++;
60 | *oIter = (uintptr_t)iter;
61 | return true;
62 | }
63 | bool IterNext(
64 | uintptr_t _iter,
65 | const char** oFilepath,
66 | void(**freeFunction)(void* buf),
67 | size_t* oFsizeBytes,
68 | obos::driverInterface::fileAttributes* oFAttribs)
69 | {
70 | fileIterator* iter = (fileIterator*)_iter;
71 | fileIterator* _node = g_iterators.head;
72 | while (_node)
73 | {
74 | if (_node == iter)
75 | break;
76 |
77 | _node = _node->next;
78 | }
79 | if (_node != iter)
80 | return false;
81 | if (!iter->currentNode)
82 | {
83 | if (oFAttribs)
84 | *oFAttribs = obos::driverInterface::FILE_DOESNT_EXIST;
85 | if (oFsizeBytes)
86 | *oFsizeBytes = 0;
87 | return true;
88 | }
89 | bool ret = QueryFileProperties(iter->currentNode->cache->entry->path, 0,0, oFsizeBytes, oFAttribs);
90 | if (!ret)
91 | return false;
92 | size_t szFilepath = obos::utils::strlen(iter->currentNode->cache->entry->path);
93 | if (oFilepath)
94 | *oFilepath = (const char*)obos::utils::memcpy(kcalloc(szFilepath + 1, 1), iter->currentNode->cache->entry->path, szFilepath);
95 | if (freeFunction)
96 | *freeFunction = kfree;
97 | iter->currentNode = iter->currentNode->next;
98 | return true;
99 | }
100 | bool IterClose(uintptr_t _iter)
101 | {
102 | fileIterator* iter = (fileIterator*)_iter;
103 | fileIterator* _node = g_iterators.head;
104 | while (_node)
105 | {
106 | if (_node == iter)
107 | break;
108 | _node = _node->next;
109 | }
110 | if (_node != iter)
111 | return false;
112 | if (iter->next)
113 | iter->next->prev = iter->prev;
114 | if (iter->prev)
115 | iter->prev->next = iter->next;
116 | if (g_iterators.head == iter)
117 | g_iterators.head = iter->next;
118 | if (g_iterators.tail == iter)
119 | g_iterators.tail = iter->prev;
120 | g_iterators.size--;
121 | kfree(iter);
122 | return true;
123 | }
124 | bool ReadFile(
125 | uint32_t, uint32_t,
126 | const char* path,
127 | size_t nToSkip,
128 | size_t nToRead,
129 | char* buff)
130 | {
131 | auto cache = GetCacheForPath(path);
132 | if (!cache)
133 | return false;
134 | if (nToSkip >= cache->entryFilesize)
135 | return false;
136 | if ((nToSkip + nToRead) > cache->entryFilesize)
137 | return false;
138 | if (buff)
139 | obos::utils::memcpy(buff, cache->dataStart + nToSkip, nToRead);
140 | return true;
141 | }
142 | }
--------------------------------------------------------------------------------
/src/drivers/generic/initrd/interface.h:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/generic/initrd/interface.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | namespace initrdInterface
14 | {
15 | bool QueryFileProperties (
16 | const char* path,
17 | uint32_t driveId, uint32_t partitionIdOnDrive,
18 | size_t* oFsizeBytes,
19 | obos::driverInterface::fileAttributes* oFAttribs);
20 | bool IterCreate(
21 | uint32_t driveId, uint32_t partitionIdOnDrive,
22 | uintptr_t* oIter);
23 | bool IterNext(
24 | uintptr_t iter,
25 | const char** oFilepath,
26 | void(**freeFunction)(void* buf),
27 | size_t* oFsizeBytes,
28 | obos::driverInterface::fileAttributes* oFAttribs);
29 | bool IterClose(uintptr_t iter);
30 | bool ReadFile(
31 | uint32_t driveId, uint32_t partitionIdOnDrive,
32 | const char* path,
33 | size_t nToSkip,
34 | size_t nToRead,
35 | char* buff);
36 | }
--------------------------------------------------------------------------------
/src/drivers/generic/initrd/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/generic/initrd/main.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 |
10 | #include
11 |
12 | #include
13 |
14 | #include
15 |
16 | #include
17 |
18 | #include "parse.h"
19 | #include "interface.h"
20 |
21 | using namespace obos;
22 |
23 | #ifdef __GNUC__
24 | #define DEFINE_IN_SECTION __attribute__((section(OBOS_DRIVER_HEADER_SECTION_NAME)))
25 | #else
26 | #define DEFINE_IN_SECTION
27 | #endif
28 |
29 | driverInterface::driverHeader DEFINE_IN_SECTION g_driverHeader = {
30 | .magicNumber = obos::driverInterface::OBOS_DRIVER_HEADER_MAGIC,
31 | .driverId = 0,
32 | .driverType = obos::driverInterface::OBOS_SERVICE_TYPE_INITRD_FILESYSTEM,
33 | .requests = driverInterface::driverHeader::REQUEST_INITRD_LOCATION,
34 | .functionTable = {
35 | .GetServiceType = []()->driverInterface::serviceType { return driverInterface::serviceType::OBOS_SERVICE_TYPE_INITRD_FILESYSTEM; },
36 | .serviceSpecific = {
37 | .filesystem = {
38 | .QueryFileProperties = initrdInterface::QueryFileProperties,
39 | .FileIteratorCreate = initrdInterface::IterCreate,
40 | .FileIteratorNext = initrdInterface::IterNext,
41 | .FileIteratorClose = initrdInterface::IterClose,
42 | .ReadFile = initrdInterface::ReadFile,
43 | .unused = { nullptr,nullptr,nullptr,nullptr }
44 | }
45 | }
46 | }
47 | };
48 |
49 | extern void ConnectionHandler(uintptr_t);
50 |
51 | #ifdef __GNUC__
52 | #define WEAK __attribute__((weak))
53 | #else
54 | #define WEAK
55 | #endif
56 |
57 | extern "C" void _start()
58 | {
59 | if (!g_driverHeader.initrdLocationResponse.addr)
60 | logger::panic(nullptr, "InitRD Driver: No initrd image received from the kernel.\n");
61 | logger::log("InitRD Driver: Initializing filesystem cache.\n");
62 | InitializeFilesystemCache();
63 | g_driverHeader.driver_initialized = true;
64 | while (!g_driverHeader.driver_finished_loading);
65 | thread::ExitThread(0);
66 | }
67 |
--------------------------------------------------------------------------------
/src/drivers/generic/initrd/parse.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/generic/initrd/parse.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #include "parse.h"
12 |
13 | #include
14 |
15 | #include
16 |
17 |
18 | using namespace obos;
19 |
20 |
21 |
22 | extern driverInterface::driverHeader g_driverHeader;
23 |
24 | int oct2bin(char* str, int size)
25 | {
26 | int n = 0;
27 | char* c = str;
28 | while (size-- > 0) {
29 | n *= 8;
30 | n += *c - '0';
31 | c++;
32 | }
33 | return n;
34 | }
35 |
36 | [[noreturn]] extern void kpanic(const char* format, ...);
37 |
38 | filesystemCache g_filesystemCache = {};
39 |
40 | void InitializeFilesystemCache()
41 | {
42 | ustarEntry* entry = (ustarEntry*)g_driverHeader.initrdLocationResponse.addr;
43 | if (!obos::utils::memcmp(&entry->indication, "ustar", 6))
44 | obos::logger::panic(nullptr, "DRIVER 0, %s: Invalid or empty initrd image!\n", __func__);
45 | while (obos::utils::memcmp(&entry->indication, "ustar", 6))
46 | {
47 | size_t filesize = oct2bin(entry->filesizeOctal, 11);
48 | ustarEntryCacheNode* node = (ustarEntryCacheNode*)kcalloc(1, sizeof(ustarEntryCacheNode));
49 | ustarEntryCache* cache = node->cache = (ustarEntryCache*)kcalloc(1, sizeof(ustarEntryCache));
50 | obos::utils::memzero(node, sizeof(*node));
51 | cache->entry = entry;
52 | cache->entryFilesize = filesize;
53 | cache->dataStart = (uint8_t*)(entry + 1);
54 | if (filesize)
55 | cache->dataEnd = cache->dataStart + ((filesize / 512 + (filesize % 512 != 0)) * 512);
56 | else
57 | cache->dataEnd = cache->dataStart;
58 | node->cache = cache;
59 | switch (entry->type)
60 | {
61 | case ustarEntry::NORMAL_FILE:
62 | cache->entryAttributes = driverInterface::FILE_ATTRIBUTES_FILE | driverInterface::FILE_ATTRIBUTES_READ_ONLY;
63 | // TODO: Find out what the point of this was?
64 | //cache->entryFilesize++; // Add one to the filesize.
65 | break;
66 | case ustarEntry::DIRECTORY:
67 | cache->entryAttributes = driverInterface::FILE_ATTRIBUTES_DIRECTORY;
68 | break;
69 | case ustarEntry::HARD_LINK:
70 | cache->entryAttributes = driverInterface::FILE_ATTRIBUTES_HARDLINK;
71 | break;
72 | default:
73 | break;
74 | }
75 | if (g_filesystemCache.tail)
76 | g_filesystemCache.tail->next = node;
77 | if (!g_filesystemCache.head)
78 | g_filesystemCache.head = node;
79 | node->prev = g_filesystemCache.tail;
80 | g_filesystemCache.tail = node;
81 | g_filesystemCache.size++;
82 | entry = (ustarEntry*)cache->dataEnd;
83 | }
84 | }
85 |
86 | bool GetFileAttribute(const char* filepath, size_t* size, uint32_t* _attrib)
87 | {
88 | ustarEntryCache* entry = GetCacheForPath(filepath);
89 | if (!entry)
90 | {
91 | if (_attrib)
92 | *_attrib = driverInterface::fileAttributes::FILE_DOESNT_EXIST;
93 | if (size)
94 | *size = 0;
95 | return false;
96 | }
97 | if (_attrib)
98 | *_attrib = entry->entryAttributes;
99 | if (size)
100 | *size = entry->entryFilesize;
101 | return true;
102 | }
103 | bool FileExists(const char* filepath)
104 | {
105 | return GetCacheForPath(filepath) != nullptr;
106 | }
107 |
108 | ustarEntryCache* GetCacheForPath(const char* path)
109 | {
110 | ustarEntryCacheNode* entry = g_filesystemCache.head;
111 | while (entry)
112 | {
113 | if (obos::utils::strcmp(path, entry->cache->entry->path))
114 | break;
115 |
116 | entry = entry->next;
117 | }
118 |
119 | return entry->cache;
120 | }
121 |
--------------------------------------------------------------------------------
/src/drivers/generic/initrd/parse.h:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/generic/initrd/parse.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | struct ustarEntry
14 | {
15 | char path[100];
16 | byte unused1[24];
17 | char filesizeOctal[12];
18 | byte unused2[12];
19 | uint64_t unused3;
20 | enum __type
21 | {
22 | NORMAL_FILE = '0',
23 | HARD_LINK = '1',
24 | SYM_LINK = '2',
25 | CHAR_DEVICE = '3',
26 | BLOCK_DEVICE = '4',
27 | DIRECTORY = '5',
28 | NAMED_PIPE = '6',
29 | } __attribute__((packed));
30 | __type type;
31 | char linkedFile[100];
32 | char indication[6]; // should be "ustar\0"
33 | char version[2];
34 | char unused4[80];
35 | char filenamePrefix[155];
36 | char padding[12];
37 | } __attribute__((packed));
38 |
39 | struct ustarEntryCache
40 | {
41 | ustarEntry* entry;
42 | size_t entryFilesize;
43 | uint32_t entryAttributes;
44 | byte* dataStart;
45 | byte* dataEnd;
46 | };
47 | struct ustarEntryCacheNode
48 | {
49 | ustarEntryCacheNode *next, *prev;
50 | ustarEntryCache* cache;
51 | };
52 | struct fileIterator
53 | {
54 | ustarEntryCacheNode* currentNode;
55 | fileIterator *next, *prev; // The next file iterator in the file iterator list.
56 | };
57 | struct filesystemCache
58 | {
59 | ustarEntryCacheNode *head, *tail;
60 | size_t size;
61 | } extern g_filesystemCache;
62 |
63 | void InitializeFilesystemCache();
64 |
65 | bool GetFileAttribute(const char* filepath, size_t* size, uint32_t* attrib); // OBOS_SERVICE_QUERY_FILE_DATA
66 | bool FileExists(const char* path);
67 | ustarEntryCache* GetCacheForPath(const char* path);
--------------------------------------------------------------------------------
/src/drivers/x86_64/mbr/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/x86_64/mbr/CMakeLists.txt
2 |
3 | # Copyright (c) 2023-2024 Omar Berrow
4 |
5 | add_executable(mbrDriver "main.cpp" "../../generic/common/new.cpp")
6 |
7 | target_compile_options(mbrDriver
8 | PRIVATE $<$:-fno-stack-protector -fno-stack-check -fno-lto>
9 | PRIVATE $<$:-fno-use-cxa-atexit>
10 | PRIVATE $<$:-fno-rtti>
11 | PRIVATE $<$:-nostdlib>
12 | PRIVATE $<$:-fno-exceptions>
13 | PRIVATE $<$:-ffreestanding>
14 | PRIVATE $<$:-Wall>
15 | PRIVATE $<$:-Wextra>
16 | PRIVATE $<$:-fPIE>
17 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_CPP}>
18 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
19 | PRIVATE "${DEBUG_SYMBOLS_OPT}"
20 | )
21 | set_property (TARGET mbrDriver PROPERTY CXX_STANDARD 20)
22 |
23 | set_target_properties(mbrDriver PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}")
24 |
25 | target_compile_definitions(mbrDriver PRIVATE OBOS_DRIVER=1)
26 |
27 | target_include_directories(mbrDriver PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl")
28 |
29 | target_link_options(mbrDriver
30 | PRIVATE "-ffreestanding"
31 | PRIVATE "-nostdlib"
32 | PRIVATE "-pie"
33 | )
34 |
35 | add_dependencies(mbrDriver oboskrnl)
--------------------------------------------------------------------------------
/src/drivers/x86_64/mbr/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/x86_64/mbr/main.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 |
10 | #include
11 |
12 | #include
13 |
14 | #include
15 |
16 | using namespace obos;
17 |
18 | #ifdef __GNUC__
19 | #define DEFINE_IN_SECTION __attribute__((section(OBOS_DRIVER_HEADER_SECTION_NAME)))
20 | #else
21 | #define DEFINE_IN_SECTION
22 | #endif
23 |
24 | bool RegisterMBRPartitionsOnDrive(uint32_t driveId, size_t* oNPartitions, driverInterface::partitionInfo** oPartInfo);
25 |
26 | driverInterface::driverHeader DEFINE_IN_SECTION g_driverHeader = {
27 | .magicNumber = driverInterface::OBOS_DRIVER_HEADER_MAGIC,
28 | .driverId = 2, // The kernel __depends__ on this being two, do not change.
29 | .driverType = driverInterface::OBOS_SERVICE_TYPE_PARTITION_MANAGER,
30 | .requests = driverInterface::driverHeader::REQUEST_NO_MAIN_THREAD,
31 | .functionTable = {
32 | .GetServiceType = []()->driverInterface::serviceType { return driverInterface::serviceType::OBOS_SERVICE_TYPE_STORAGE_DEVICE; },
33 | .serviceSpecific = {
34 | .partitionManager = {
35 | .RegisterPartitionsOnDrive = RegisterMBRPartitionsOnDrive,
36 | .unused = {nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,}
37 | }
38 | }
39 | }
40 | };
41 |
42 | struct mbr_part
43 | {
44 | // Bit 7: Active partition.
45 | // Any other bits should be zero.
46 | uint8_t attribs;
47 | uint8_t startHead;
48 | uint8_t startSector;
49 | uint8_t startTrack;
50 | uint8_t osIndicator;
51 | uint8_t endHead;
52 | uint8_t endSector;
53 | uint8_t endTrack;
54 | uint32_t startingLBA;
55 | uint32_t endLBA;
56 | } __attribute__((packed));
57 | struct mbr
58 | {
59 | uint8_t bootCode[440];
60 | uint32_t uniqueMBRSignature;
61 | uint8_t unknown[2];
62 | mbr_part partitions[4];
63 | uint16_t signature; // If != 0x55AA, invalid MBR.
64 | } __attribute__((packed));
65 | static_assert(sizeof(mbr) == 512, "struct mbr is not 512 bytes in length.");
66 |
67 | bool RegisterMBRPartitionsOnDrive(uint32_t driveId, size_t* oNPartitions, driverInterface::partitionInfo** oPartInfo)
68 | {
69 | char* path = new char[logger::sprintf(nullptr, "D%d:/", driveId) + 1];
70 | logger::sprintf(path, "D%d:/", driveId);
71 | vfs::DriveHandle drive;
72 | drive.OpenDrive(path, vfs::DriveHandle::OpenOptions::OPTIONS_READ_ONLY);
73 | delete[] path;
74 | size_t sizeofSector;
75 | drive.QueryInfo(nullptr, &sizeofSector, nullptr);
76 | byte* firstSector = new byte[sizeofSector];
77 | if (!drive.ReadSectors(firstSector, nullptr, 0, 1))
78 | {
79 | delete[] firstSector;
80 | drive.Close();
81 | return false;
82 | }
83 | mbr* driveMbr = (mbr*)firstSector;
84 | if (driveMbr->signature != 0xAA55)
85 | return false;
86 | size_t nPartitions = 0;
87 | driverInterface::partitionInfo* partitionInfo = nullptr;
88 | for (size_t part = 0; part < 4; part++)
89 | {
90 | // Active partition.
91 | if (driveMbr->partitions[part].attribs & 0x80)
92 | {
93 | partitionInfo = (driverInterface::partitionInfo*)krealloc(partitionInfo, ++nPartitions);
94 | partitionInfo[nPartitions - 1].id = nPartitions - 1;
95 | partitionInfo[nPartitions - 1].lbaOffset = driveMbr->partitions[part].startingLBA;
96 | partitionInfo[nPartitions - 1].sizeSectors = driveMbr->partitions[part].endLBA - driveMbr->partitions[part].startingLBA;
97 | }
98 | }
99 | if (oNPartitions)
100 | *oNPartitions = nPartitions;
101 | if (oPartInfo)
102 | *oPartInfo = partitionInfo;
103 | else
104 | delete[] oPartInfo;
105 | return true;
106 | }
107 |
108 | extern "C" void _start()
109 | {}
--------------------------------------------------------------------------------
/src/drivers/x86_64/ps2Keyboard/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/x86_64/ps2KeyboardDriver/CMakeLists.txt
2 |
3 | # Copyright (c) 2023-2024 Omar Berrow
4 |
5 | add_executable (ps2KeyboardDriver "dmain.cpp" "scancodes.cpp" "../../generic/common/new.cpp")
6 |
7 | target_compile_options(ps2KeyboardDriver
8 | PRIVATE $<$:-fno-stack-protector -fno-stack-check -fno-lto>
9 | PRIVATE $<$:-fno-use-cxa-atexit>
10 | PRIVATE $<$:-fno-rtti>
11 | PRIVATE $<$:-nostdlib>
12 | PRIVATE $<$:-fno-exceptions>
13 | PRIVATE $<$:-ffreestanding>
14 | PRIVATE $<$:-Wall>
15 | PRIVATE $<$:-Wextra>
16 | PRIVATE $<$:-fPIE>
17 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_CPP}>
18 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
19 | PRIVATE "${DEBUG_SYMBOLS_OPT}"
20 | )
21 | set_property (TARGET ps2KeyboardDriver PROPERTY CXX_STANDARD 20)
22 |
23 | set_target_properties(ps2KeyboardDriver PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}")
24 |
25 | target_compile_definitions(ps2KeyboardDriver PRIVATE OBOS_DRIVER=1)
26 |
27 | target_include_directories(ps2KeyboardDriver PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl")
28 |
29 | target_link_options(ps2KeyboardDriver
30 | PRIVATE "-ffreestanding"
31 | PRIVATE "-nostdlib"
32 | PRIVATE "-pie"
33 | )
34 |
35 | add_dependencies(ps2KeyboardDriver oboskrnl)
--------------------------------------------------------------------------------
/src/drivers/x86_64/ps2Keyboard/scancodes.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/x86_64/ps2Keyboard/scancodes.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include "scancodes.h"
8 |
9 | #include
10 |
11 | using namespace obos::driverInterface;
12 |
13 | #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
14 |
15 | key g_keys[] = {
16 | { 0x00, 0,0, '\x00' },
17 | { 0x01, 0,0, '\x1b' },
18 | { 0x02, 0,0, '1', '!' },
19 | { 0x03, 0,0, '2', '@' },
20 | { 0x04, 0,0, '3', '#' },
21 | { 0x05, 0,0, '4', '$' },
22 | { 0x06, 0,0, '5', '%' },
23 | { 0x07, 0,0, '6', '^' },
24 | { 0x08, 0,0, '7', '&' },
25 | { 0x09, 0,0, '8', '*' },
26 | { 0x0A, 0,0, '9', '(' },
27 | { 0x0B, 0,0, '0', ')' },
28 | { 0x0C, 0,0, '-', '_'},
29 | { 0x0D, 0,0, '=', '+' },
30 | { 0x0E, 0,0, '\b' },
31 | { 0x0F, 0,0, '\t' },
32 | { 0x10, 0,0, 'Q' },
33 | { 0x11, 0,0, 'W' },
34 | { 0x12, 0,0, 'E' },
35 | { 0x13, 0,0, 'R' },
36 | { 0x14, 0,0, 'T' },
37 | { 0x15, 0,0, 'Y' },
38 | { 0x16, 0,0, 'U' },
39 | { 0x17, 0,0, 'I' },
40 | { 0x18, 0,0, 'O' },
41 | { 0x19, 0,0, 'P' },
42 | { 0x1A, 0,0, '[', '{' },
43 | { 0x1B, 0,0, ']', '}' },
44 | { 0x1C, 0,0, '\n', '\0', true, },
45 | { 0x1D, 0,0, (uint16_t)SpecialKeys::LEFT_CONTROL, '\0', false, (uint16_t)SpecialKeys::RIGHT_CONTROL, },
46 | { 0x1E, 0,0, 'A' },
47 | { 0x1F, 0,0, 'S' },
48 | { 0x20, 0,0, 'D' },
49 | { 0x21, 0,0, 'F' },
50 | { 0x22, 0,0, 'G' },
51 | { 0x23, 0,0, 'H' },
52 | { 0x24, 0,0, 'J' },
53 | { 0x25, 0,0, 'K' },
54 | { 0x26, 0,0, 'L' },
55 | { 0x27, 0,0, ';', ':' },
56 | { 0x28, 0,0, '\'', '\"' },
57 | { 0x29, 0,0, '`', '~' },
58 | { 0x2A, 0,0, (uint16_t)SpecialKeys::LEFT_ALT, '\0', true, },
59 | { 0x2B, 0,0, '\\', '|'},
60 | { 0x2C, 0,0, 'Z' },
61 | { 0x2D, 0,0, 'X' },
62 | { 0x2E, 0,0, 'C' },
63 | { 0x2F, 0,0, 'V' },
64 | { 0x30, 0,0, 'B' },
65 | { 0x31, 0,0, 'N' },
66 | { 0x32, 0,0, 'M' },
67 | { 0x33, 0,0, ',', '<' },
68 | { 0x34, 0,0, '.', '>' },
69 | { 0x35, 0,0, '/', '?', true },
70 | { 0x36, 0,0, '\0' },
71 | { 0x37, 0,0, '*' },
72 | { 0x38, 0,0, '\0', '\0', false, (uint16_t)SpecialKeys::RIGHT_ALT },
73 | { 0x39, 0,0, ' ' },
74 | { 0x3A, 0,0, '\0' },
75 | { 0x3B, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F1 },
76 | { 0x3C, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F2 },
77 | { 0x3D, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F3 },
78 | { 0x3E, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F4 },
79 | { 0x3F, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F5 },
80 | { 0x40, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F6 },
81 | { 0x41, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F7 },
82 | { 0x42, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F8 },
83 | { 0x43, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F9 },
84 | { 0x44, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F10 },
85 | { 0x45, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::NUMLOCK },
86 | { 0x46, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::SCROLL_LOCK },
87 | { 0x47, 0,0, '7', '\0', false, (uint16_t)SpecialKeys::HOME, },
88 | { 0x48, 0,0, '8', '\0', false, (uint16_t)SpecialKeys::UP_ARROW, },
89 | { 0x49, 0,0, '9', '\0', false, (uint16_t)SpecialKeys::PAGE_UP, },
90 | { 0x4A, 0,0, '-' },
91 | { 0x4B, 0,0, '4', '\0', false, (uint16_t)SpecialKeys::LEFT_ARROW, },
92 | { 0x4C, 0,0, '5' },
93 | { 0x4D, 0,0, '6', '\0', false, (uint16_t)SpecialKeys::RIGHT_ARROW, },
94 | { 0x4E, 0,0, '+' },
95 | { 0x4F, 0,0, '1', '\0', false, (uint16_t)SpecialKeys::END, },
96 | { 0x50, 0,0, '2', '\0', false, (uint16_t)SpecialKeys::DOWN_ARROW, },
97 | { 0x51, 0,0, '3', '\0', false, (uint16_t)SpecialKeys::PAGE_DOWN, },
98 | { 0x52, 0,0, '0', '\0', false, (uint16_t)SpecialKeys::INSERT, },
99 | { 0x53, 0,0, '.', '\0', false, (uint16_t)SpecialKeys::DELETE, },
100 | { 0x54, 0,0, '\0' },
101 | { 0x55, 0,0, '\0' },
102 | { 0x56, 0,0, '\0' },
103 | { 0x57, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F11 },
104 | { 0x58, 0,0, '\0', '\0', true, (uint16_t)SpecialKeys::F12 },
105 | };
--------------------------------------------------------------------------------
/src/drivers/x86_64/ps2Keyboard/scancodes.h:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/x86_64/ps2Keyboard/scancodes.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | typedef struct _key
14 | {
15 | uint32_t scanCode;
16 | size_t nPressed;
17 | bool isPressed;
18 | uint16_t ch;
19 | char shiftAlias;
20 | bool skipExtended = false;
21 | uint16_t extendedCh;
22 | } key;
23 |
24 | extern key g_keys[89];
--------------------------------------------------------------------------------
/src/drivers/x86_64/sata/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/x86_64/sata/CMakeLists.txt
2 |
3 | # Copyright (c) 2023-2024 Omar Berrow
4 |
5 | add_executable(sataDriver "main.cpp" "../../generic/common/new.cpp" "command.cpp" "interface.cpp")
6 |
7 | target_compile_options(sataDriver
8 | PRIVATE $<$:-fno-stack-protector -fno-stack-check -fno-lto>
9 | PRIVATE $<$:-fno-use-cxa-atexit>
10 | PRIVATE $<$:-fno-rtti>
11 | PRIVATE $<$:-nostdlib>
12 | PRIVATE $<$:-fno-exceptions>
13 | PRIVATE $<$:-ffreestanding>
14 | PRIVATE $<$:-Wall>
15 | PRIVATE $<$:-Wextra>
16 | PRIVATE $<$:-fPIE>
17 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_CPP}>
18 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
19 | PRIVATE "${DEBUG_SYMBOLS_OPT}"
20 | )
21 | set_property (TARGET sataDriver PROPERTY CXX_STANDARD 20)
22 |
23 | set_target_properties(sataDriver PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}")
24 |
25 | target_compile_definitions(sataDriver PRIVATE OBOS_DRIVER=1)
26 |
27 | target_include_directories(sataDriver PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl")
28 |
29 | target_link_options(sataDriver
30 | PRIVATE "-ffreestanding"
31 | PRIVATE "-nostdlib"
32 | PRIVATE "-pie"
33 | )
34 |
35 | add_dependencies(sataDriver oboskrnl)
--------------------------------------------------------------------------------
/src/drivers/x86_64/sata/command.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/x86_64/sata/command.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 |
10 | #include "command.h"
11 | #include "structs.h"
12 |
13 | extern volatile HBA_MEM* g_generalHostControl;
14 |
15 | asm(
16 | ".global _Z17StopCommandEnginePV8HBA_PORT;"
17 | ".global _Z18StartCommandEnginePV8HBA_PORT;"
18 | ".global _Z11FindCMDSlotPV8HBA_PORT;"
19 | ".intel_syntax noprefix;"
20 | "_Z11FindCMDSlotPV8HBA_PORT:;"
21 | " mov eax, dword ptr [rdi+0x34];"
22 | " or eax, [rdi+0x38];"
23 | " mov esi, eax;"
24 | " not esi;"
25 | " bsf eax, esi;"
26 | " ret;"
27 | "_Z17StopCommandEnginePV8HBA_PORT:;"
28 | " push rbp;"
29 | " mov rbp, rsp;"
30 | " and dword ptr [rdi+0x18], ~(1<<0);" // Clear ST (bit 0)
31 | " and dword ptr [rdi+0x18], ~(1<<4);" // Clear FRE (bit 4)
32 | // Wait until FR (bit 14), CR (bit 15) are cleared
33 | "_Z17StopCommandEnginePV8HBA_PORT.loop:;"
34 | " test dword ptr [rdi+0x18], (1<<14);"
35 | " jnz _Z17StopCommandEnginePV8HBA_PORT.loop;"
36 | " test dword ptr [rdi+0x18], (1<<15);"
37 | " jnz _Z17StopCommandEnginePV8HBA_PORT.loop;"
38 | "_Z17StopCommandEnginePV8HBA_PORT.end:;"
39 | " leave;"
40 | " ret;"
41 | ".intel_syntax noprefix;"
42 | "_Z18StartCommandEnginePV8HBA_PORT:;"
43 | " push rbp;"
44 | " mov rbp, rsp;"
45 | "_Z18StartCommandEnginePV8HBA_PORT.loop:;"
46 | " test dword ptr [rdi+0x18], (1<<15);"
47 | " jnz _Z18StartCommandEnginePV8HBA_PORT.loop;"
48 | "_Z18StartCommandEnginePV8HBA_PORT.end:;"
49 | " or dword ptr [rdi+0x18], (1<<4);"
50 | " or dword ptr [rdi+0x18], (1<<0);"
51 | " leave;"
52 | " ret;"
53 | ".att_syntax prefix;"
54 | );
--------------------------------------------------------------------------------
/src/drivers/x86_64/sata/command.h:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/x86_64/sata/command.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | uint32_t FindCMDSlot(volatile struct HBA_PORT* pPort);
12 | void StopCommandEngine(volatile struct HBA_PORT* pPort);
13 | void StartCommandEngine(volatile struct HBA_PORT* pPort);
--------------------------------------------------------------------------------
/src/oboskrnl/allocators/liballoc.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/allocators/liballoc.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #ifdef __cplusplus
13 | extern "C"
14 | {
15 | #endif
16 |
17 | OBOS_EXPORT void* kmalloc(size_t amount);
18 | OBOS_EXPORT void* kcalloc(size_t nobj, size_t szObj);
19 | OBOS_EXPORT void* krealloc(void* ptr, size_t newSize);
20 | OBOS_EXPORT void kfree(void* ptr);
21 |
22 | #ifdef __cplusplus
23 | }
24 | namespace obos
25 | {
26 | bool CanAllocateMemory();
27 | }
28 | #endif
29 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/interrupt.h:
--------------------------------------------------------------------------------
1 | #if defined(__x86_64__) || defined(_WIN64)
2 | #include
3 | #endif
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/fpu.asm:
--------------------------------------------------------------------------------
1 | [BITS 64]
2 |
3 | global fpuInit
4 | fpuInit:
5 | fninit
6 | ret
7 | global _fxsave
8 | _fxsave:
9 | fxsave [rdi]
10 | ret
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdbstub/communicate.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/gdbstub/communicate.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | namespace obos
12 | {
13 | namespace gdbstub
14 | {
15 | struct Packet
16 | {
17 | char* data;
18 | size_t len;
19 | };
20 | void DefaultLockConnection();
21 | void DefaultUnlockConnection();
22 | void DefaultSendByteOnRawConnection(byte);
23 | byte DefaultRecvByteOnRawConnection();
24 | bool DefaultByteInConnBuffer();
25 | void InitDefaultConnection();
26 | byte mod256(const char* data, size_t len);
27 | class Connection
28 | {
29 | public:
30 | Connection()
31 | : m_sendByteOnRawConnection{ DefaultSendByteOnRawConnection },
32 | m_recvByteOnRawConnection{ DefaultRecvByteOnRawConnection },
33 | m_lockConnection{ DefaultLockConnection },
34 | m_unlockConnection{ DefaultUnlockConnection },
35 | m_isByteInConnBuffer{ DefaultByteInConnBuffer }
36 | {}
37 | Connection(void(*sendByteOnRawConnection)(byte), byte(*recvByteOnRawConnection)(), void(*lockConnection)(), void(*unlockConnection)(), bool(*isByteInConnBuffer)())
38 | : m_sendByteOnRawConnection{ sendByteOnRawConnection },
39 | m_recvByteOnRawConnection{ recvByteOnRawConnection },
40 | m_lockConnection{ lockConnection },
41 | m_unlockConnection{ unlockConnection },
42 | m_isByteInConnBuffer { isByteInConnBuffer }
43 | {}
44 |
45 | bool SendRawPacket(const Packet& packet);
46 | bool RecvRawPacket(Packet& packet);
47 |
48 | void SetSendingACK(bool val) { m_sendingACK = val; };
49 | bool IsSendingACK() const { return m_sendingACK; };
50 |
51 | bool CanReadByte() { return m_isByteInConnBuffer(); }
52 | private:
53 | void(*m_sendByteOnRawConnection)(byte);
54 | byte(*m_recvByteOnRawConnection)();
55 | void(*m_lockConnection)();
56 | void(*m_unlockConnection)();
57 | bool(*m_isByteInConnBuffer)();
58 | bool m_sendingACK = true;
59 | };
60 | }
61 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdbstub/stub.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/gdbstub/stub.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | namespace obos
14 | {
15 | namespace gdbstub
16 | {
17 | extern bool g_stubInitialized;
18 | void InititalizeGDBStub(Connection* conn);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdt.asm:
--------------------------------------------------------------------------------
1 | [BITS 64]
2 |
3 | segment .data
4 |
5 | align 16
6 | GDT:
7 | ; Null entry.
8 | dq 0
9 | ; Code segment.
10 | dq 0x00209A0000000000
11 | ; Data segment.
12 | dq 0x0000920000000000
13 | ; User mode data segment
14 | dq 0x00aff3000000ffff
15 | ; User mode code segment
16 | dq 0x00affb000000ffff
17 | align 1
18 | TSS:
19 | dq 0,0
20 |
21 | align 1
22 |
23 | GDT_Ptr:
24 | dw $- GDT - 1
25 | dq 0
26 |
27 | [GLOBAL TSS]
28 | [GLOBAL GDT]
29 | [GLOBAL GDT_Ptr]
30 |
31 | segment .text
32 |
33 | [GLOBAL _ZN4obos16InitializeGDTASMEv]
34 |
35 | _ZN4obos16InitializeGDTASMEv:
36 | push rbp
37 | mov rbp, rsp
38 |
39 | lea rax, [GDT]
40 | mov [GDT_Ptr+2], rax
41 |
42 | lgdt [GDT_Ptr]
43 |
44 | mov ax, 0x10
45 | mov ds, ax
46 | mov es, ax
47 | mov fs, ax
48 | mov gs, ax
49 | mov ss, ax
50 |
51 | push 0x8
52 | push .flush_tss
53 | retfq
54 | .flush_tss:
55 | mov ax, 0x28
56 | ltr ax
57 |
58 | leave
59 | ret
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdt.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | arch/x86_64/gdt.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 |
9 | #include
10 |
11 | #include
12 | #include
13 |
14 | namespace obos
15 | {
16 | struct gdtEntry
17 | {
18 | uint16_t limitLow;
19 | uint16_t baseLow;
20 | uint8_t baseMiddle1;
21 | uint8_t access;
22 | uint8_t granularity;
23 | uint8_t baseMiddle2;
24 | uint64_t baseHigh;
25 | } __attribute__((packed));
26 |
27 | struct tssEntry
28 | {
29 | uint32_t resv1;
30 | uint64_t rsp0;
31 | uint64_t rsp1;
32 | uint64_t rsp2;
33 | uint64_t resv2;
34 | uint64_t ist0;
35 | uint8_t unused1[0x3a];
36 | uint16_t iopb;
37 | } __attribute__((packed));
38 |
39 | extern "C" gdtEntry TSS[sizeof(gdtEntry)];
40 |
41 | tssEntry s_tssEntry alignas(8);
42 |
43 | static_assert(sizeof(tssEntry) == 104, "sizeof(tssEntry) != 104");
44 |
45 | extern void InitializeGDTASM();
46 |
47 | void InitializeGdt()
48 | {
49 | utils::memzero(&s_tssEntry, sizeof(tssEntry));
50 |
51 | gdtEntry* tss = (gdtEntry*)&TSS;
52 |
53 | uintptr_t base = reinterpret_cast(&s_tssEntry);
54 | tss->access = 0x89;
55 | tss->granularity = 0x40;
56 | tss->limitLow = sizeof(tssEntry) - 1;
57 | tss->baseLow = base & 0xFFFF;
58 | tss->baseMiddle1 = (base >> 16) & 0xFF;
59 | tss->baseMiddle2 = (base >> 24) & 0xFF;
60 | tss->baseHigh = base >> 32;
61 | s_tssEntry.iopb = 103;
62 | static char ist0_tstack[0x1800];
63 | s_tssEntry.ist0 = (uint64_t)(ist0_tstack + 0x1800);
64 |
65 | InitializeGDTASM();
66 | }
67 | void SetTSSStack(void* rsp)
68 | {
69 | if (thread::GetCurrentCpuLocalPtr())
70 | thread::GetCurrentCpuLocalPtr()->arch_specific.tss.rsp0 = (uintptr_t)rsp;
71 | else
72 | s_tssEntry.rsp0 = (uintptr_t)rsp;
73 | }
74 | void SetIST(void* rsp)
75 | {
76 | if(thread::GetCurrentCpuLocalPtr())
77 | thread::GetCurrentCpuLocalPtr()->arch_specific.tss.ist0 = (uint64_t)rsp;
78 | else
79 | s_tssEntry.ist0 = (uintptr_t)rsp;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/idt.asm:
--------------------------------------------------------------------------------
1 | ; oboskrnl/arch/x86_64/idt.asm
2 |
3 | ; Copyright (c) 2023-2024 Omar Berrow
4 |
5 | [BITS 64]
6 |
7 | section .bss
8 | align 1
9 | bad_idt:
10 | dq 0
11 | dw 0
12 | section .text
13 |
14 | global idtFlush
15 | global reset_idt
16 |
17 | idtFlush:
18 | lidt [rdi]
19 | ret
20 | reset_idt:
21 | lidt [bad_idt]
22 | ret
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/interrupt.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/interrupt_frame.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #define BITFIELD_FROM_BIT(n) (1<
10 |
11 | namespace obos
12 | {
13 | namespace acpi
14 | {
15 | struct ACPIRSDPHeader {
16 | char Signature[8];
17 | uint8_t Checksum;
18 | char OEMID[6];
19 | uint8_t Revision;
20 | uint32_t RsdtAddress; // Deprecated
21 |
22 | // Fields only valid if Revision != 0
23 | uint32_t Length;
24 | uint64_t XsdtAddress;
25 | uint8_t ExtendedChecksum;
26 | uint8_t reserved[3];
27 | } __attribute__((packed));
28 | struct ACPISDTHeader {
29 | char Signature[4];
30 | uint32_t Length;
31 | uint8_t Revision;
32 | uint8_t Checksum;
33 | char OEMID[6];
34 | char OEMTableID[8];
35 | uint32_t OEMRevision;
36 | uint32_t CreatorID;
37 | uint32_t CreatorRevision;
38 | } __attribute__((packed));
39 | struct MADTTable
40 | {
41 | ACPISDTHeader sdtHeader;
42 | uint32_t lapicAddress;
43 | uint32_t unwanted;
44 | // There are more entries.
45 | } __attribute__((packed));
46 | struct MADT_EntryHeader
47 | {
48 | uint8_t type;
49 | uint8_t length;
50 | } __attribute__((packed));
51 | struct MADT_EntryType0
52 | {
53 | MADT_EntryHeader entryHeader;
54 | uint8_t processorID;
55 | uint8_t apicID;
56 | uint32_t flags;
57 | } __attribute__((packed));
58 | struct MADT_EntryType1
59 | {
60 | MADT_EntryHeader entryHeader;
61 | uint8_t ioApicID;
62 | uint8_t resv1;
63 | uint32_t ioapicAddress;
64 | uint32_t globalSystemInterruptBase;
65 | } __attribute__((packed));
66 | struct MADT_EntryType2
67 | {
68 | MADT_EntryHeader entryHeader;
69 | uint8_t busSource;
70 | uint8_t irqSource;
71 | uint32_t globalSystemInterrupt;
72 | uint16_t flags;
73 | } __attribute__((packed));
74 | struct MADT_EntryType3
75 | {
76 | MADT_EntryHeader entryHeader;
77 | uint8_t nmiSource;
78 | uint8_t resv;
79 | uint16_t flags;
80 | uint32_t globalSystemInterrupt;
81 | } __attribute__((packed));
82 | struct MADT_EntryType4
83 | {
84 | MADT_EntryHeader entryHeader;
85 | uint8_t processorID;
86 | uint16_t flags;
87 | uint8_t lINT;
88 | } __attribute__((packed));
89 | struct MADT_EntryType5
90 | {
91 | MADT_EntryHeader entryHeader;
92 | uint8_t resv1[2];
93 | uintptr_t lapic_address;
94 | } __attribute__((packed));
95 | struct MADT_EntryType9
96 | {
97 | MADT_EntryHeader entryHeader;
98 | uint8_t resv1[2];
99 | uint32_t x2APIC_ID;
100 | uint32_t flags;
101 | uint32_t acpiID;
102 | } __attribute__((packed));
103 |
104 | struct HPET_Addr
105 | {
106 | uint8_t addressSpaceId;
107 | uint8_t registerBitWidth;
108 | uint8_t registerBitOffset;
109 | uint8_t resv;
110 | uintptr_t address;
111 | } __attribute__((packed));
112 | struct HPET_Table
113 | {
114 | ACPISDTHeader sdtHeader;
115 | uint32_t eventTimerBlockID;
116 | HPET_Addr baseAddress;
117 | uint8_t hpetNumber;
118 | uint16_t mainCounterMinimum/*ClockTickPeriodicMode*/;
119 | uint8_t pageProtectionAndOEMAttrib;
120 | } __attribute__((packed));
121 | }
122 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/irq/timer.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/irq/timer.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 |
9 | #include
10 |
11 | #include
12 | #include
13 |
14 | #include
15 |
16 | namespace obos
17 | {
18 | void(*g_currentTimerHandler)(interrupt_frame*);
19 | static void IntermediateTimerIntHandler(interrupt_frame* frame)
20 | {
21 | if(g_currentTimerHandler)
22 | g_currentTimerHandler(frame);
23 | SendEOI();
24 | }
25 | void ConfigureAPICTimer(void(*handler)(interrupt_frame* frame), byte isr, uint32_t initialCount, TimerConfig timerConfig, TimerDivisor divisor, bool mask)
26 | {
27 | uintptr_t savedFlags = saveFlagsAndCLI();
28 | RegisterInterruptHandler(isr, IntermediateTimerIntHandler);
29 | g_currentTimerHandler = handler;
30 | divisor = (TimerDivisor)((int)divisor & 0b1101);
31 | if (timerConfig != 0 && timerConfig != TIMER_CONFIG_PERIODIC)
32 | timerConfig = TIMER_CONFIG_PERIODIC;
33 | g_localAPICAddr->divideConfig = divisor;
34 | g_localAPICAddr->lvtTimer = isr | timerConfig;
35 | MaskTimer(mask);
36 | g_localAPICAddr->initialCount = initialCount;
37 | restorePreviousInterruptStatus(savedFlags);
38 | }
39 | void MaskTimer(bool mask)
40 | {
41 | if(!mask)
42 | g_localAPICAddr->lvtTimer |= (1 << 16);
43 | else
44 | g_localAPICAddr->lvtTimer &= ~(1 << 16);
45 | }
46 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/irq/timer.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/irq/timer.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 |
9 | #include
10 |
11 | namespace obos
12 | {
13 | enum TimerConfig
14 | {
15 | TIMER_CONFIG_ONE_SHOT,
16 | TIMER_CONFIG_PERIODIC = 0x20000,
17 | };
18 | enum TimerDivisor
19 | {
20 | TIMER_DIVISOR_TWO = 0b0000,
21 | TIMER_DIVISOR_FOUR = 0b0001,
22 | TIMER_DIVISOR_EIGHT = 0b0010,
23 | TIMER_DIVISOR_SIXTEEN = 0b0011,
24 | TIMER_DIVISOR_THIRTY_TWO = 0b1000,
25 | TIMER_DIVISOR_SIXTY_FOUR = 0b1001,
26 | TIMER_DIVISOR_ONE_HUNDERED_TWENTY_EIGHT = 0b1010,
27 | TIMER_DIVISOR_ONE = 0b1011,
28 | };
29 | void ConfigureAPICTimer(void(*handler)(interrupt_frame* frame), byte isr, uint32_t initialCount, TimerConfig timerConfig, TimerDivisor divisor, bool maskIrq = true);
30 | void MaskTimer(bool mask); // Masks the timer interrupt. If !mask, the timer interrupt is disabled.
31 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/memory_manager/physical/allocate.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/memory_manager/allocate.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | namespace obos
13 | {
14 | namespace memory
15 | {
16 | void InitializePhysicalMemoryManager();
17 |
18 | ///
19 | /// Allocates a physical page.
20 | ///
21 | /// The address of the page. Make sure to map this page before using it.
22 | OBOS_EXPORT uintptr_t allocatePhysicalPage(size_t nPages = 1);
23 | ///
24 | /// Marks a physical page as freed.
25 | ///
26 | /// The address of the page to free
27 | /// true on success, otherwise false.
28 | OBOS_EXPORT bool freePhysicalPage(uintptr_t addr, size_t nPages = 1);
29 | ///
30 | /// Queries whether a page is in the HHDM or not.
31 | ///
32 | /// The address of the page to check.
33 | /// true if the page is in the HHDM, otherwise false.
34 | OBOS_EXPORT bool PageInHHDM(uintptr_t addr);
35 | }
36 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/memory_manager/virtual/initialize.h:
--------------------------------------------------------------------------------
1 | /*
2 | arch/x86_64/memory_manager/virtual/initialize.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | namespace obos
13 | {
14 | namespace memory
15 | {
16 | OBOS_EXPORT uintptr_t* mapPageTable(uintptr_t* phys);
17 |
18 | class PageMap
19 | {
20 | public:
21 | PageMap() = delete;
22 |
23 | // L4 -> Page Map
24 | // L3 -> Page Directory Pointer
25 | // L2 -> Page Directory
26 | // L1 -> Page Table
27 | // L0 -> Page Table Entry
28 |
29 | OBOS_EXPORT uintptr_t* getPageMap() { return (uintptr_t*)this; }
30 | OBOS_EXPORT uintptr_t* getL4PageMapEntryAt(uintptr_t at); // pageMap[addressToIndex(at, 3)];
31 | OBOS_EXPORT uintptr_t* getL3PageMapEntryAt(uintptr_t at); // getL4PageMapEntryAt()[addressToIndex(at,2)];
32 | OBOS_EXPORT uintptr_t* getL2PageMapEntryAt(uintptr_t at); // getL3PageMapEntryAt()[addressToIndex(at,1)];
33 | OBOS_EXPORT uintptr_t* getL1PageMapEntryAt(uintptr_t at); // getL2PageMapEntryAt()[addressToIndex(at,0)];
34 |
35 | OBOS_EXPORT void switchToThis();
36 |
37 | OBOS_EXPORT static size_t addressToIndex(uintptr_t address, uint8_t level) { return (address >> (9 * level + 12)) & 0x1FF; }
38 | };
39 |
40 | OBOS_EXPORT PageMap* getCurrentPageMap();
41 |
42 | OBOS_EXPORT size_t GetPhysicalAddressBits();
43 | OBOS_EXPORT size_t GetVirtualAddressBits();
44 |
45 | void InitializeVirtualMemoryManager();
46 |
47 | OBOS_EXPORT bool CPUSupportsExecuteDisable();
48 |
49 | // We don't export this because by the time a driver gets loaded it will be true.
50 |
51 | extern bool g_initialized;
52 |
53 | extern OBOS_EXPORT uintptr_t g_physAddrMask;
54 | }
55 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/memory_manager/virtual/internal.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/memory_manager/virtual/internal.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | #include
14 |
15 | namespace obos
16 | {
17 | namespace memory
18 | {
19 | struct pageMapTuple { PageMap* pageMap; bool isUserMode; };
20 | pageMapTuple GetPageMapFromProcess(process::Process* proc);
21 | bool CanAllocatePages(void* _base, size_t nPages, PageMap* pageMap);
22 | bool PagesAllocated(const void* _base, size_t nPages, PageMap* pageMap);
23 | uintptr_t DecodeProtectionFlags(uintptr_t _flags);
24 |
25 | uintptr_t* allocatePagingStructures(uintptr_t address, PageMap* pageMap, uintptr_t flags);
26 | void freePagingStructures(uintptr_t* _pageMap, uintptr_t _pageMapPhys, obos::memory::PageMap* pageMap, uintptr_t addr);
27 |
28 | // This includes non-committed pages (ie. pages that have bit 10 of the pte set, but not bit 0).
29 | void IteratePages(
30 | uintptr_t* headPM,
31 | uintptr_t* currentPM,
32 | uint8_t level,
33 | uintptr_t start,
34 | uintptr_t end,
35 | bool(*callback)(uintptr_t userdata, uintptr_t* pm, uintptr_t virt, uintptr_t entry),
36 | uintptr_t userdata,
37 | uintptr_t* indices // must be an array of at least 4 entries (anything over is ignored).
38 | );
39 |
40 | void* MapPhysicalAddress(PageMap* pageMap, uintptr_t phys, void* to, uintptr_t cpuFlags);
41 | void* MapEntry(PageMap* pageMap, uintptr_t entry, void* to);
42 | void UnmapAddress(PageMap* pageMap, void* _addr);
43 | }
44 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/signals.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/signals.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #include
12 | #include
13 |
14 | #include
15 | #include
16 |
17 | #include
18 |
19 | #include
20 |
21 | namespace obos
22 | {
23 | namespace process
24 | {
25 | template
26 | static bool testbit(i bitfield, uint8_t bit)
27 | {
28 | return (bitfield >> bit) & 1;
29 | }
30 | void __ImplCallSignal(thread::Thread* on, void(*handler)())
31 | {
32 | on->flags |= thread::THREAD_FLAGS_IN_SIGNAL;
33 | bool isRunning = on->status & thread::THREAD_STATUS_RUNNING;
34 | __uint128_t affinity = on->affinity;
35 | on->status = thread::THREAD_STATUS_CAN_RUN | thread::THREAD_STATUS_PAUSED;
36 | if (isRunning)
37 | {
38 | // Find the cpu the thread is running on.
39 | uint32_t cpuId = bsf(affinity);
40 | // Call the scheduler on the cpu.
41 | SendIPI(DestinationShorthand::None, DeliveryMode::Fixed, 0x30, cpuId);
42 | }
43 | uintptr_t previousRip = on->context.frame.rip;
44 | on->context.frame.rip = (uintptr_t)handler;
45 | uintptr_t* returnAddress = (uintptr_t*)(on->context.frame.rsp -= 8);
46 | setAC();
47 | *returnAddress = previousRip;
48 | clearAC();
49 | on->status = thread::THREAD_STATUS_CAN_RUN;
50 | }
51 |
52 | bool CallSignal(thread::Thread* on, signals sig)
53 | {
54 | if (sig > SIGMAX)
55 | {
56 | SetLastError(OBOS_ERROR_INVALID_PARAMETER);
57 | return false;
58 | }
59 | logger::debug("Calling signal %d on thread %d, process id %d. Action on fail: Abort.\n", sig, on->tid, ((process::Process*)on->owner)->pid);
60 | auto process = (Process*)on->owner;
61 | auto handler = process->signal_table[sig];
62 | if (!handler)
63 | {
64 | SetLastError(OBOS_ERROR_NULL_HANDLER);
65 | return false;
66 | }
67 | __ImplCallSignal(on, handler);
68 | return true;
69 | }
70 | bool CallSignalOrTerminate(thread::Thread* on, signals sig)
71 | {
72 | if (sig > SIGMAX)
73 | {
74 | SetLastError(OBOS_ERROR_INVALID_PARAMETER);
75 | return false;
76 | }
77 | logger::debug("Calling signal %d on thread %d, process id %d. Action on fail: Terminate thread's process.\n", sig, on->tid, ((process::Process*)on->owner)->pid);
78 | auto process = (Process*)on->owner;
79 | auto handler = process->signal_table[sig];
80 | if (handler)
81 | __ImplCallSignal(on, handler);
82 | else
83 | TerminateProcess(process);
84 | return true;
85 | }
86 | }
87 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/smp_trampoline.asm:
--------------------------------------------------------------------------------
1 | ; arch/x86_64/smp_trampoline.asm
2 | ;
3 | ; Copyright (c) 2023-2024 Omar Berrow
4 |
5 | [BITS 16]
6 |
7 | segment .data
8 |
9 | global _strampoline
10 | global _etrampoline
11 | global loadGDT
12 |
13 | extern GDT_Ptr
14 |
15 | ; The start of the trampoline.
16 | _strampoline:
17 | db 0xEB, 0x38
18 |
19 | align 8
20 | gdt:
21 | dq 0
22 | ; 64-bit Code segment.
23 | dq 0x00209A0000000000
24 | ; 64-bit Data segment.
25 | dq 0x0000920000000000
26 | ; 32-bit Code segment.
27 | dd 0x0000FFFF
28 | dd 0x00CF9A00
29 | ; 32-bit Data segment.
30 | dd 0x0000FFFF
31 | dd 0x00CF9200
32 | gdt_end:
33 | gdt_ptr:
34 | %define gdt_ptr_addr 0x30
35 | align 1
36 | dw gdt_end-gdt-1
37 | dq 0x8
38 |
39 | ; The real-mode trampoline.
40 | ; We will always be loaded at nullptr, so we can assume some values.
41 | trampoline:
42 |
43 | .real_mode:
44 | cli
45 |
46 | ; Enter protected-mode
47 | mov eax, cr0
48 | or ax, 1 ; Enable protected mode.
49 | mov cr0, eax
50 |
51 | lgdt [gdt_ptr_addr]
52 |
53 | mov sp, 0xFD0
54 |
55 | mov ax, 0x20
56 | mov ds, ax
57 | mov es, ax
58 | mov ss, ax
59 | mov fs, ax
60 | mov gs, ax
61 |
62 | db 0xE8, 0x00, 0x00 ; call REL16
63 | pop ax
64 | add ax, 10
65 | mov byte [0x01], al
66 |
67 | db 0x9A, 0x00, 0x00, 0x18, 0x00 ; call 0x18:.protected_mode
68 | align 1
69 | .protected_mode:
70 | [BITS 32]
71 |
72 | ; Enter 64-bit long mode.
73 |
74 | ; Enable PAE
75 | mov eax, cr4
76 | or eax, (1<<5)
77 | mov cr4, eax
78 |
79 | ; Load the page map
80 | mov eax, [0xff8]
81 | mov cr3, eax
82 |
83 | ; Enter long mode.
84 | mov eax, 0x80000001
85 | xor ecx,ecx
86 | cpuid
87 | xor eax, eax
88 | test edx, (1<<20)
89 | mov esi, (1<<11)
90 | cmovnz eax, esi ; If bit 20 is set
91 | mov ecx, 0xC0000080
92 | or eax, (1 << 8)|(1<<10)
93 | xor edx,edx
94 | wrmsr
95 |
96 | ; Enable paging.
97 | mov eax, 0x80010001
98 | mov cr0, eax
99 |
100 | mov esp, 0xFC8
101 | call .jmp
102 | .jmp:
103 | pop edi ; The address of .set_cs needs to be in a register that won't be modified by a) cpuid b) the rest of the code.
104 | add edi, 8
105 | db 0x6A, 0x08, 0x57, 0xCB ; push 0x08; push edi; retfd
106 |
107 | .set_cs:
108 | mov ax, 0x10
109 | mov ds, ax
110 | mov es, ax
111 | mov ss, ax
112 | mov fs, ax
113 | mov gs, ax
114 |
115 | .done:
116 | [BITS 64]
117 | mov al, [0xFB0]
118 | test al,al
119 | jnz .call_procInit
120 |
121 | lgdt [GDT_Ptr]
122 |
123 | ; Set "trampoline_has_gdt" to true
124 | mov qword [0xFB0], 1
125 |
126 | push 0x8
127 | push rdi
128 | retfq
129 |
130 | .call_procInit:
131 | ; Set "trampoline_has_gdt" to false for the next AP.
132 | mov qword [0xFB0], 0
133 |
134 | mov rdi, [0xFD8]
135 | mov rsp, [rdi]
136 | add rsp, 0x2000
137 | jmp [0xFA8]
138 |
139 | .abort:
140 | cli
141 | hlt
142 | jmp .abort
143 |
144 | align 4096
145 | .end:
146 |
147 | _etrampoline:
148 | align 1
149 | segment .text
150 | loadGDT:
151 | lgdt [rdi]
152 |
153 | mov ax, 0x10
154 | mov ds, ax
155 | mov es, ax
156 | mov fs, ax
157 | mov gs, ax
158 | mov ss, ax
159 |
160 | mov ax, 0x28
161 | ltr ax
162 | xor ax,ax
163 | lldt ax
164 |
165 | pop rax
166 | push 0x8
167 | push rax
168 | retfq
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/sse.asm:
--------------------------------------------------------------------------------
1 | ; arch/x86_64/sse.asm
2 | ;
3 | ; Copyright (c) 2023-2024 Omar Berrow
4 |
5 | [BITS 64]
6 |
7 | global _ZN4obos7initSSEEv
8 |
9 | _ZN4obos7initSSEEv:
10 | mov rax, cr4
11 | or rax, (1<<9)|(1<<10)
12 | mov cr4, rax
13 | mov rax, cr0
14 | and eax, ~(1<<2)
15 | or eax, (1<<1)
16 | mov cr0, rax
17 | ret
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/stack_canary.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/stack_canary.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 | #ifdef OBOS_DEBUG
7 | #include
8 | #include
9 |
10 | #include
11 |
12 | #include
13 |
14 | uintptr_t __stack_chk_guard = 0x15E4F6DABD6F8A;
15 |
16 | struct frame
17 | {
18 | frame* next;
19 | void *rip;
20 | };
21 | extern "C" [[noreturn]] void __stack_chk_fail(void)
22 | {
23 | frame* current = (frame*)obos::getRBP();
24 | void* where = nullptr;
25 | // Why did I go through all this JUST to get the return address
26 | {
27 | if (!current)
28 | goto skip;
29 | uint64_t attrib = 0;
30 | size_t nPages = 0;
31 | uintptr_t _current = (uintptr_t)current;
32 | nPages = 1llu + (((_current + sizeof(*current)) & ~0xfff) > (_current & ~0xfff));
33 | obos::memory::VirtualAllocator vallocator{ nullptr };
34 | if (!vallocator.VirtualGetProtection(current, nPages, &attrib))
35 | goto skip;
36 | if (!(attrib & obos::memory::PROT_IS_PRESENT))
37 | goto skip;
38 | where = current->rip;
39 | }
40 | skip:
41 | obos::logger::panic(nullptr, "Stack corruption detected at 0x%p.\n", where);
42 | }
43 | #endif
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/syscall/handle.h:
--------------------------------------------------------------------------------
1 | /*
2 | arch/x86_64/syscall/handle.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | namespace obos
13 | {
14 | namespace syscalls
15 | {
16 | enum class ProcessHandleType
17 | {
18 | INVALID = (-1),
19 | FILE_HANDLE,
20 | DRIVE_HANDLE,
21 | THREAD_HANDLE,
22 | VALLOCATOR_HANDLE,
23 | DIRECTORY_ITERATOR_HANDLE,
24 | };
25 | using user_handle = uint64_t;
26 | using handle = utils::pair;
27 | constexpr user_handle USER_HANDLE_MAX = UINT64_MAX;
28 | ///
29 | /// Registers a handle for a process at a certain address with a certain type.
30 | ///
31 | /// The owner of the handle. This should be a process::Process*
32 | /// The address of the object.
33 | /// The type of the object.
34 | /// The newly made handle, or UINT64_MAX on failure.
35 | user_handle ProcessRegisterHandle(void* proc, void* objectAddress, ProcessHandleType type);
36 | ///
37 | /// Frees a handle for a process.
38 | ///
39 | /// The owner of the handle. This should be a process::Process*
40 | /// The handle to release.
41 | /// The object the handle represented, or nullptr on failure.
42 | void* ProcessReleaseHandle(void* proc, user_handle handle);
43 | ///
44 | /// Checks if a handle exists or not.
45 | ///
46 | /// The owner of the handle. This should be a process::Process*
47 | /// The handle value to check.
48 | /// The type of the handle. This can be ProcessHandleType::INVALID to specify any handle type.
49 | /// true if the handle exists, and the type matches, otherwise false.
50 | bool ProcessVerifyHandle(void* proc, user_handle handle, ProcessHandleType type = ProcessHandleType::INVALID);
51 | ///
52 | /// Gets the object represented by a handle.
53 | ///
54 | /// The owner of the handle. This should be a process::Process*
55 | /// The handle value to retrieve.
56 | /// The object represented by the handle on success, or nullptr on failure.
57 | void* ProcessGetHandleObject(void* proc, user_handle handle);
58 | ///
59 | /// Gets the type of a handle.
60 | ///
61 | /// The owner of the handle. This should be a process::Process*
62 | /// The handle value to retrieve.
63 | /// The type of thehandle on success, or ProcessHandleType::INVALID on failure.
64 | ProcessHandleType ProcessGetHandleType(void* proc, user_handle handle);
65 |
66 | ///
67 | /// Syscall Number: 24
68 | /// Frees a handle. After this function is called on a handle, the handle can no longer be used for any purpose.
69 | /// You should call this function after calling Syscall*CloseHandle.
70 | ///
71 | /// uint64_t thrHandle = SyscallMakeThreadHandle();
72 | /// SyscallCreateThread(thrHandle, 0,0,ThreadEntry,0, nullptr, false);
73 | /// // Do stuff with the handle.
74 | /// SyscallThreadCloseHandle(thrHandle);
75 | /// SyscallInvalidateHandle(thrHandle);
76 | ///
77 | /// Only here because of the syscall abi on OBOS x86-64
78 | /// The handle to free. This is a pointer because of the syscall abi on OBOS x86-64, when 'syscall'ing, you just pass a user_handle.
79 | /// Whether the handle was freed properly (true) or false on failure.
80 | bool SyscallInvalidateHandle(uint64_t syscall, user_handle* handle);
81 | }
82 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/syscall/power_management.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/syscall/power_management.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | namespace obos
12 | {
13 | namespace syscalls
14 | {
15 | uintptr_t PMSyscallHandler(uint64_t syscall, void* args);
16 |
17 | ///
18 | /// System number: 59
19 | /// Shuts down the system, doing necessary cleanup.
20 | /// If for some reason this fails, all CPUs are stopped and the system idles.
21 | /// This syscall does not return.
22 | ///
23 | void SyscallShutdown();
24 | ///
25 | /// System number: 60
26 | /// Reboots the system, doing necessary cleanup.
27 | /// If for some reason this fails, all CPUs are stopped and the system idles.
28 | /// This syscall does not return.
29 | ///
30 | void SyscallReboot();
31 | } // namespace syscall
32 |
33 | } // namespace obos
34 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/syscall/register.h:
--------------------------------------------------------------------------------
1 | /*
2 | arch/x86_64/syscall/register.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | namespace obos
12 | {
13 | namespace syscalls
14 | {
15 | // Zero-based.
16 | constexpr size_t g_syscallTableLimit = 0x1fff;
17 | extern uintptr_t g_syscallTable[g_syscallTableLimit + 1];
18 | void RegisterSyscalls();
19 | void RegisterSyscall(uint16_t n, uintptr_t func);
20 |
21 | // These next five functions are never actually defined except for the actual syscall
22 | // They're just defined for documentation purposes
23 |
24 | ///
25 | /// Syscall number: 55
26 | /// Gets the last error for the current thread.
27 | ///
28 | /// The last error
29 | uint32_t SyscallGetLastError();
30 | ///
31 | /// Syscall number: 56
32 | /// Sets the last error for the current thread.
33 | ///
34 | /// The new error code.
35 | void SyscallSetLastError(uint32_t newError);
36 |
37 | ///
38 | /// Syscall number: 57
39 | /// Loads a kernel module.
40 | ///
41 | /// The beginning of the file.
42 | /// The size of the file.
43 | /// Whether the function succeeded (true) or not (false).
44 | bool SyscallLoadModule(const byte* data, size_t size);
45 |
46 | ///
47 | /// Syscall number: 69
48 | /// Prefer the wrgsbase/wrfsbase instructions over this when possible.
49 | /// Writes to gs/fs base.
50 | ///
51 | /// The value to write.
52 | /// Whether to write to GSBase (true) or FSBase (false)>.
53 | void wrfsgsbase(uintptr_t val, bool isGSBase);
54 | ///
55 | /// Syscall number: 70
56 | /// Prefer the rdgsbase/rdfsbase instructions over this when possible.
57 | /// Reads from gs/fs base.
58 | ///
59 | /// Whether to write to GSBase (true) or FSBase (false)>.
60 | /// The value of gs/fs base.
61 | uintptr_t rdfsgsbase(bool isGSBase);
62 | }
63 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/syscall/signals.h:
--------------------------------------------------------------------------------
1 | /*
2 | arch/x86_64/syscall/signals.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | #include
14 |
15 | namespace obos
16 | {
17 | namespace syscalls
18 | {
19 | uintptr_t SignalsSyscallHandler(uint64_t syscall, void* args);
20 |
21 | ///
22 | /// Syscall Number: 57
23 | /// Registers a signal handler for the current process.
24 | ///
25 | /// The signal to register.
26 | /// The handler, or nullptr to clear the handler.
27 | /// Whether the signal was successfully registered (true) or not (false).
28 | bool SyscallRegisterSignal(process::signals signal, uintptr_t uhandler);
29 | ///
30 | /// Syscall Number: 58
31 | /// Calls a signal on a thread.
32 | ///
33 | /// A thread handle representing the thread to call the signal on.
34 | /// The signal to send.
35 | /// Whether the signal was successfully send (true) or not (false).
36 | bool SyscallCallSignal(user_handle on, process::signals sig);
37 | }
38 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/syscall/sys_signals.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | arch/x86_64/syscall/signals.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 |
10 | #include
11 | #include
12 |
13 | #include
14 | #include
15 |
16 | #include
17 |
18 | #include
19 |
20 | namespace obos
21 | {
22 | namespace syscalls
23 | {
24 | uintptr_t SignalsSyscallHandler(uint64_t syscall, void* args)
25 | {
26 | switch (syscall)
27 | {
28 | case 57:
29 | {
30 | struct _par
31 | {
32 | alignas(0x10) process::signals signal;
33 | alignas(0x10) uintptr_t uhandler;
34 | } *par = (_par*)args;
35 | if (!canAccessUserMemory(par, sizeof(*par), false))
36 | {
37 | SetLastError(OBOS_ERROR_INVALID_PARAMETER);
38 | return false;
39 | }
40 | return SyscallRegisterSignal(par->signal, par->uhandler);
41 | }
42 | case 58:
43 | {
44 | struct _par
45 | {
46 | alignas(0x10) user_handle on;
47 | alignas(0x10) process::signals sig;
48 | } *par = (_par*)args;
49 | if (!canAccessUserMemory(par, sizeof(*par), false))
50 | {
51 | SetLastError(OBOS_ERROR_INVALID_PARAMETER);
52 | return false;
53 | }
54 | return SyscallCallSignal(par->on, par->sig);
55 | }
56 | default:
57 | break;
58 | }
59 | return 0;
60 | }
61 |
62 | bool SyscallRegisterSignal(process::signals signal, uintptr_t uhandler)
63 | {
64 | if ((uint32_t)signal > (uint32_t)process::signals::INVALID_SIGNAL)
65 | {
66 | SetLastError(OBOS_ERROR_INVALID_PARAMETER);
67 | return false;
68 | }
69 | process::Process* currentProc = (process::Process*)thread::GetCurrentCpuLocalPtr()->currentThread->owner;
70 | currentProc->signal_table[signal] = (void(*)())uhandler;
71 | return true;
72 | }
73 | bool SyscallCallSignal(user_handle on, process::signals sig)
74 | {
75 | if (!ProcessVerifyHandle(nullptr, on, ProcessHandleType::THREAD_HANDLE))
76 | {
77 | SetLastError(OBOS_ERROR_INVALID_PARAMETER);
78 | return false;
79 | }
80 | return process::CallSignal((thread::Thread*)ProcessGetHandleObject(nullptr, on), sig);
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/syscall/verify_pars.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | arch/x86_64/syscall/verify_pars.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include
16 |
17 | #define getCPULocal() ((thread::cpu_local*)thread::getCurrentCpuLocalPtr())
18 |
19 | namespace obos
20 | {
21 | namespace syscalls
22 | {
23 | bool canAccessUserMemory(const void* addr, size_t size, bool hasToWrite)
24 | {
25 | if (!addr)
26 | return false;
27 | memory::VirtualAllocator vallocator = ((process::Process*)getCPULocal()->currentThread->owner);
28 | bool checkUsermode = ((process::Process*)getCPULocal()->currentThread->owner)->isUsermode;
29 | if (checkUsermode && (uintptr_t)addr > 0xffff'8000'0000'0000)
30 | return false;
31 | size_t nPagesToCheck = ((size + 0xfff) & ~0xfff) / 4096;
32 | uintptr_t* pageFlags = (uintptr_t*)kmalloc(nPagesToCheck * sizeof(uintptr_t));
33 | uintptr_t requiredFlags = memory::PROT_IS_PRESENT | ((uintptr_t)checkUsermode * memory::PROT_USER_MODE_ACCESS);
34 | if(!vallocator.VirtualGetProtection((void*)((uintptr_t)addr & ~0xfff), nPagesToCheck * 4096, pageFlags))
35 | {
36 | kfree(pageFlags);
37 | return false;
38 | }
39 | for (size_t i = 0; i < nPagesToCheck; i++)
40 | {
41 | if (((pageFlags[i] & requiredFlags) != requiredFlags) || ((pageFlags[0] & memory::PROT_READ_ONLY) && hasToWrite))
42 | {
43 | kfree(pageFlags);
44 | return false;
45 | }
46 | }
47 | kfree(pageFlags);
48 | return true;
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/syscall/verify_pars.h:
--------------------------------------------------------------------------------
1 | /*
2 | arch/x86_64/syscall/verify_pars.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | namespace obos
12 | {
13 | namespace syscalls
14 | {
15 | bool canAccessUserMemory(const void* addr, size_t size, bool hasToWrite);
16 | }
17 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/syscall/vfs/dir.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/syscall/vfs/dir.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | namespace obos
14 | {
15 | namespace syscalls
16 | {
17 | uintptr_t DirectorySyscallHandler(uint64_t syscall, void* args);
18 |
19 | ///
20 | /// Syscall number: 61
21 | /// Makes a directory iterator.
22 | ///
23 | /// The handle, or USER_HANDLE_MAX on failure.
24 | user_handle SyscallMakeDirectoryIterator();
25 |
26 | ///
27 | /// Syscall number: 66
28 | /// Opens a directory iterator at 'path'.
29 | ///
30 | /// The handle to open.
31 | /// The path of the directory to iterate over.
32 | /// Whether the handle was successfully opened (true) or not (false).
33 | bool SyscallDirectoryIteratorOpen(user_handle hnd, const char* path);
34 |
35 | ///
36 | /// Syscall number: 62
37 | /// Makes the directory iterator's position increase by one.
38 | ///
39 | /// The iterator to modify.
40 | /// Whether the function succeeded (true) or not (false).
41 | bool SyscallDirectoryIteratorNext(user_handle hnd);
42 | ///
43 | /// Syscall number: 63
44 | /// Makes the directory iterator's position decrease by one.
45 | ///
46 | /// The iterator to modify.
47 | /// Whether the function succeeded (true) or not (false).
48 | bool SyscallDirectoryIteratorPrevious(user_handle hnd);
49 | ///
50 | /// Syscall number: 64
51 | /// Gets the current file path of the directory iterator.
52 | ///
53 | /// The handle to query.
54 | /// [out] The buffer to store the path in. This can be nullptr.
55 | /// [in,out] A pointer to the size of the path, and a pointer to the actual size of the path. This must not be nullptr if path is not nullptr.
56 | /// Whether the function succeeded (true) or not (false).
57 | bool SyscallDirectoryIteratorGet(user_handle hnd, char* path, size_t* size);
58 | ///
59 | /// Syscall number: 65
60 | /// Queries whether the directory iterator has any more entries left to iterator, as if you queried EOF on it.
61 | ///
62 | /// The handle to query.
63 | /// [out,opt] Whether the function succeeded (true) or not (false).
64 | /// Whether the directory iterator reached past the last entry (true) or not (false). This returns false if the function fails, always check *status.
65 | bool SyscallDirectoryIteratorEnd(user_handle hnd, bool* status);
66 |
67 | ///
68 | /// Syscall number: 67
69 | /// Closes a directory handle.
70 | ///
71 | /// The handle to close.
72 | /// Whether the handle was successfully closed (true) or not (false).
73 | bool SyscallDirectoryIteratorClose(user_handle hnd);
74 |
75 | ///
76 | /// Syscall number: 68
77 | /// Gets the path of the parent directory of a directory iterator.
78 | /// In case anyone is wondering why I (Omar Berrow) decided to not add a direct syscall to get the parent of a path, it was because I was too lazy to do that.
79 | ///
80 | /// The handle to query.
81 | /// [out] The buffer to store the path in. This can be nullptr.
82 | /// [in,out] A pointer to the size of the path, and a pointer to the actual size of the path. This must not be nullptr if path is not nullptr.
83 | /// Whether the function succeeded (true) or not (false).
84 | bool SyscallDirectoryIteratorGetParent(user_handle hnd, char* path, size_t* size);
85 | }
86 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/syscall/vmm.h:
--------------------------------------------------------------------------------
1 | /*
2 | arch/x86_64/syscall/vmm.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | #include
14 |
15 | namespace obos
16 | {
17 | namespace syscalls
18 | {
19 | uintptr_t VMMSyscallHandler(uint64_t syscall, void* args);
20 |
21 | ///
22 | /// Syscall Number: 39
23 | /// Creates a virtual allocator with 'owner' as the process to allocate as.
24 | ///
25 | /// The process to allocate as.
26 | user_handle SyscallCreateVirtualAllocator(process::Process* owner);
27 |
28 | ///
29 | /// Syscall Number: 40
30 | /// Allocates nPages at base.
31 | ///
32 | /// The base address to allocate at.
33 | /// The amount of bytes (rounded to the nearest page size) to allocate at base.
34 | /// The initial protection flags.
35 | /// "base" if base isn't nullptr. If base is nullptr, the function finds a base address.
36 | void* SyscallVirtualAlloc(user_handle hnd, void* base, size_t size, uintptr_t flags);
37 | ///
38 | /// Syscall Number: 41
39 | /// Free nPages pages at base.
40 | ///
41 | /// The base address to free.
42 | /// The amount of bytes (rounded to the nearest page size) to free.
43 | /// false on failure, otherwise true. If this function fails, use GetLastError for extra error information.
44 | bool SyscallVirtualFree(user_handle hnd, void* base, size_t size);
45 | ///
46 | /// Syscall Number: 42
47 | /// Sets the protection for the pages at base.
48 | ///
49 | /// The base address to set the protection for.
50 | /// The amount of bytes (rounded to the nearest page size) to set the protection for.
51 | /// The new protection flags
52 | /// false on failure, otherwise true. If this function fails, use GetLastError for extra error information.
53 | bool SyscallVirtualProtect(user_handle hnd, void* base, size_t size, uintptr_t flags);
54 | ///
55 | /// Syscall Number: 43
56 | /// Gets the protection for base.
57 | ///
58 | /// The base address to get the protection for.
59 | /// The amount of bytes (rounded to the nearest page size) to get the protection for.
60 | /// A pointer to a buffer of the size "sizeof(PageProtectionFlags) * sizeToPageCount(size)" to store the protection in.
61 | /// false on failure, otherwise true. If this function fails, use GetLastError for extra error information.
62 | bool SyscallVirtualGetProtection(user_handle hnd, void* base, size_t size, uintptr_t* flags);
63 |
64 | ///
65 | /// Syscall Number: 44
66 | /// Copies a buffer from this program to the other process.
67 | ///
68 | /// The remote destination's address.
69 | /// The local source's address.
70 | /// The size of the buffer.
71 | /// remoteDest on success, or nullptr.
72 | void* SyscallVirtualMemcpy(user_handle hnd, void* remoteDest, const void* localSrc, size_t size);
73 | }
74 | }
--------------------------------------------------------------------------------
/src/oboskrnl/atomic.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/atomic.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | namespace obos
12 | {
13 | void atomic_set(bool* val);
14 | void atomic_clear(bool* val);
15 | bool atomic_test(const bool* val);
16 |
17 | void atomic_inc(uint64_t& val);
18 | void atomic_dec(uint64_t& val);
19 | bool atomic_cmpxchg(bool* dest, bool val, bool src);
20 | }
--------------------------------------------------------------------------------
/src/oboskrnl/boot/cfg.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/boot/cfg.h
3 |
4 | Copyright (c) 2023,2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | // Utility to parse the kernel config file.
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | namespace obos
17 | {
18 | struct Element
19 | {
20 | Element() = default;
21 | enum
22 | {
23 | ELEMENT_INVALID,
24 | ELEMENT_STRING,
25 | ELEMENT_ARRAY,
26 | ELEMENT_INTEGER,
27 | ELEMENT_BOOLEAN,
28 | } type = ELEMENT_INVALID;
29 | utils::String string{};
30 | utils::Vector array{};
31 | uintptr_t integer = 0;
32 | bool boolean = false;
33 | Element(const Element& other)
34 | {
35 | type = other.type;
36 | switch (other.type)
37 | {
38 | case ELEMENT_ARRAY:
39 | array = other.array;
40 | break;
41 | case ELEMENT_STRING:
42 | string = other.string;
43 | break;
44 | case ELEMENT_BOOLEAN:
45 | boolean = other.boolean;
46 | break;
47 | case ELEMENT_INTEGER:
48 | integer = other.integer;
49 | break;
50 | default:
51 | break;
52 | }
53 | return;
54 | }
55 | Element& operator=(const Element& other)
56 | {
57 | type = other.type;
58 | switch (other.type)
59 | {
60 | case ELEMENT_ARRAY:
61 | array = other.array;
62 | break;
63 | case ELEMENT_STRING:
64 | string = other.string;
65 | break;
66 | case ELEMENT_BOOLEAN:
67 | boolean = other.boolean;
68 | break;
69 | case ELEMENT_INTEGER:
70 | integer = other.integer;
71 | break;
72 | default:
73 | break;
74 | }
75 | return *this;
76 | }
77 | Element& operator=(Element&&) = delete;
78 | Element(Element&&) = delete;
79 | ~Element(){}
80 | };
81 | class Parser final
82 | {
83 | public:
84 | Parser() = default;
85 |
86 | Parser(const Parser&) = delete;
87 | Parser& operator=(const Parser&) = delete;
88 | Parser(Parser&&) = delete;
89 | Parser& operator=(Parser&&) = delete;
90 |
91 | bool Parse(const char* data, size_t size, utils::Vector& errorMessages);
92 |
93 | const Element* GetElement(const char* key);
94 | const auto& GetMap() { return m_elements; }
95 |
96 | ~Parser() {}
97 | private:
98 | static bool equals(const char* const& key1, const char* const& key2)
99 | { return utils::strcmp(key1, key2); }
100 | static size_t hasher(const char* const& key)
101 | {
102 | const byte* _key = (byte*)key;
103 |
104 | size_t h = 0, g = 0;
105 |
106 | while (*_key)
107 | {
108 | h = (h << 4) + *_key++;
109 | if ((g = h & 0xf0000000))
110 | h ^= g >> 24;
111 | h &= ~g;
112 | }
113 | return h;
114 | }
115 | utils::Hashmap m_elements;
116 | };
117 | }
--------------------------------------------------------------------------------
/src/oboskrnl/driverInterface/input_device.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/driverInterface/register_drive.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include
15 |
16 | #include
17 |
18 | namespace obos
19 | {
20 | namespace driverInterface
21 | {
22 | struct InputDevice
23 | {
24 | driverIdentity* driver = nullptr;
25 | utils::Vector data;
26 | uint32_t id = 0;
27 | vfs::HandleList fileHandlesReferencing;
28 | InputDevice *next = nullptr, *prev = nullptr;
29 |
30 | void* operator new(size_t)
31 | {
32 | return ImplSlabAllocate(ObjectTypes::InputDevice);
33 | }
34 | void operator delete(void* ptr)
35 | {
36 | ImplSlabFree(ObjectTypes::InputDevice, ptr);
37 | }
38 | void* operator new[](size_t sz)
39 | {
40 | return ImplSlabAllocate(ObjectTypes::InputDevice, sz / sizeof(InputDevice));
41 | }
42 | void operator delete[](void* ptr, size_t sz)
43 | {
44 | ImplSlabFree(ObjectTypes::InputDevice, ptr, sz / sizeof(InputDevice));
45 | }
46 | [[nodiscard]] void* operator new(size_t, void* ptr) noexcept { return ptr; }
47 | [[nodiscard]] void* operator new[](size_t, void* ptr) noexcept { return ptr; }
48 | void operator delete(void*, void*) noexcept {}
49 | void operator delete[](void*, void*) noexcept {}
50 | };
51 | struct InputDeviceList
52 | {
53 | InputDevice *head = nullptr, *tail = nullptr;
54 | size_t nNodes = 0;
55 | };
56 | extern InputDeviceList g_inputDevices;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/oboskrnl/driverInterface/load.h:
--------------------------------------------------------------------------------
1 | /*
2 | driverInterface/load.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | #include
14 |
15 | namespace obos
16 | {
17 | namespace driverInterface
18 | {
19 | extern utils::Hashmap g_driverInterfaces;
20 | void ScanAndLoadModules(const char* root);
21 | // Returns the driver header, this header must be in an offset from file to file+size.
22 | struct driverHeader* CheckModule(const byte* file, size_t size);
23 | bool LoadModule(const byte* file, size_t size, thread::ThreadHandle** mainThread);
24 | }
25 | }
--------------------------------------------------------------------------------
/src/oboskrnl/driverInterface/register.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/driverInterface/register_drive.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | namespace obos
13 | {
14 | namespace driverInterface
15 | {
16 | enum class DeviceType
17 | {
18 | Drive,
19 | UserInput
20 | };
21 | ///
22 | /// Registers a device in the kernel.
23 | ///
24 | /// The type of the device.
25 | /// The device id, or 0xffffffff on failure.
26 | OBOS_EXPORT uint32_t RegisterDevice(DeviceType type);
27 | ///
28 | /// Unregisters a device in the kernel.
29 | ///
30 | /// The device to unregister. This must be obtained through RegisterDevice.
31 | /// The device type. This cannot be 0xffffffff.
32 | OBOS_EXPORT void UnregisterDevice(uint32_t id, DeviceType type);
33 | ///
34 | /// Writes a byte to the input device's buffer.
35 | /// This function does not SetLastError on failure.
36 | ///
37 | /// The device's id.
38 | /// The character to write.
39 | /// Whether the function succeeded (true) or not (false).
40 | OBOS_EXPORT bool WriteByteToInputDeviceBuffer(uint32_t id, uint16_t exChar);
41 | void* GetUserInputDevice(uint32_t id);
42 | }
43 | }
--------------------------------------------------------------------------------
/src/oboskrnl/driverInterface/x86_64/enumerate_pci.h:
--------------------------------------------------------------------------------
1 | /*
2 | drivers/x86_64/common/enumerate_pci.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #define PCI_GetRegisterOffset(reg, offset) ((uint8_t)(reg * 4 + offset))
13 |
14 | namespace obos
15 | {
16 | namespace driverInterface
17 | {
18 | OBOS_EXPORT uint8_t pciReadByteRegister(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset);
19 | OBOS_EXPORT uint16_t pciReadWordRegister(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset);
20 | OBOS_EXPORT uint32_t pciReadDwordRegister(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset);
21 | OBOS_EXPORT void pciWriteByteRegister(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset, uint8_t data);
22 | OBOS_EXPORT void pciWriteWordRegister(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset, uint16_t data);
23 | OBOS_EXPORT void pciWriteDwordRegister(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset, uint32_t data);
24 | OBOS_EXPORT void enumerateBus(
25 | uint8_t bus,
26 | bool(*callback)(
27 | void* userData, uint8_t currentSlot, uint8_t currentFunction, uint8_t currentBus, uint8_t classCode,
28 | uint8_t subclass,
29 | uint8_t progIF),
30 | void* callbackUserdata);
31 | OBOS_EXPORT bool enumerateBus(uint8_t bus, uint8_t expectedClassCode, uint8_t expectedSubclass, uint8_t exceptedProgIF, uint8_t* slot, uint8_t* function);
32 | OBOS_EXPORT bool enumeratePci(uint8_t expectedClassCode, uint8_t expectedSubclass, uint8_t exceptedProgIF, uint8_t* slot, uint8_t* function, uint8_t* bus);
33 | }
34 | }
--------------------------------------------------------------------------------
/src/oboskrnl/error.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/error.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include
16 |
17 | #define getCPULocal() ((thread::cpu_local*)thread::getCurrentCpuLocalPtr())
18 |
19 | namespace obos
20 | {
21 | void SetLastError(uint32_t err)
22 | {
23 | if (!getCPULocal())
24 | return;
25 | if (!getCPULocal()->currentThread)
26 | return;
27 | getCPULocal()->currentThread->lastError = err;
28 | }
29 | uint32_t GetLastError()
30 | {
31 | return getCPULocal()->currentThread->lastError;
32 | }
33 | }
--------------------------------------------------------------------------------
/src/oboskrnl/export.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifndef __INTELLISENSE__
4 | # define OBOS_WEAK __attribute__((weak))
5 | #else
6 | # define OBOS_WEAK
7 | #endif
8 | #ifdef OBOS_DRIVER
9 | # ifndef __INTELLISENSE__
10 | # define OBOS_EXPORT __attribute__((weak))
11 | # else
12 | # define OBOS_EXPORT
13 | # endif
14 | #elif defined(OBOS_KERNEL)
15 | # define OBOS_EXPORT
16 | #else
17 | # define OBOS_EXPORT
18 | #endif
--------------------------------------------------------------------------------
/src/oboskrnl/int.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | typedef uint8_t byte;
7 | #ifdef __cplusplus
8 | template
9 | using ptr = T*;
10 | #endif
11 | #ifdef __INTELLISENSE__
12 | // It doesn't matter what the type actually is for intellisense.
13 | // This is only so intellisense gets out of my way.
14 | using __uint128_t = uint64_t;
15 | #endif
--------------------------------------------------------------------------------
/src/oboskrnl/klog.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/klog.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | #ifdef OBOS_DEBUG
14 | #define OBOS_ASSERTP(expr, msg, ...) if (!(expr)) { obos::logger::panic(nullptr, "Function %s, File %s, Line %d: Assertion failed, \"%s\". " msg "\n", __func__, __FILE__, __LINE__, #expr __VA_ARGS__); }
15 | #define OBOS_ASSERT(expr, msg, ...) if (!(expr)) { obos::logger::error("Function %s, File %s, Line %d: Assertion failed, \"%s\". " msg "\n", __func__, __FILE__, __LINE__, #expr __VA_ARGS__); }
16 | #else
17 | #define OBOS_ASSERTP(expr, msg, ...)
18 | #define OBOS_ASSERT(expr, msg, ...)
19 | #endif
20 |
21 | namespace obos
22 | {
23 | namespace logger
24 | {
25 | enum
26 | {
27 | GREY = 0xD3D3D3,
28 | GREEN = 0x03D12B,
29 | BLUE = 0x566F84,
30 | YELLOW = 0xffcc00,
31 | ERROR_RED = 0xcc3300,
32 | PANIC_RED = 0xac1616,
33 | };
34 |
35 | OBOS_EXPORT size_t printf(const char* format, ...);
36 | OBOS_EXPORT size_t vprintf(const char* format, va_list list);
37 | OBOS_EXPORT size_t vsprintf(char* dest, const char* format, va_list list);
38 | OBOS_EXPORT size_t sprintf(char* dest, const char* format, ...);
39 |
40 | constexpr const char* DEBUG_PREFIX_MESSAGE = "[Debug] ";
41 | constexpr const char* LOG_PREFIX_MESSAGE = "[Log] ";
42 | constexpr const char* INFO_PREFIX_MESSAGE = "[Log] ";
43 | constexpr const char* WARNING_PREFIX_MESSAGE = "[Warning] ";
44 | constexpr const char* ERROR_PREFIX_MESSAGE = "[Error] ";
45 |
46 | OBOS_EXPORT size_t debug(const char* format, ...);
47 | OBOS_EXPORT size_t log(const char* format, ...);
48 | OBOS_EXPORT size_t info(const char* format, ...);
49 | OBOS_EXPORT size_t warning(const char* format, ...);
50 | OBOS_EXPORT size_t error(const char* format, ...);
51 | OBOS_EXPORT [[noreturn]] void panic(void* stackTraceParameter, const char* format, ...);
52 | OBOS_EXPORT [[noreturn]] void panicVariadic(void* stackTraceParameter, const char* format, va_list list);
53 |
54 | OBOS_EXPORT void stackTrace(void* stackTraceParameter);
55 | void dumpAddr(uint32_t* addr);
56 | }
57 | }
--------------------------------------------------------------------------------
/src/oboskrnl/memory_manipulation.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/memory_manipulation.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | namespace obos
14 | {
15 | namespace utils
16 | {
17 | OBOS_EXPORT uint32_t* dwMemcpy(uint32_t* dest, const uint32_t* src, size_t countDwords);
18 | OBOS_EXPORT uint32_t* dwMemset(uint32_t* dest, uint32_t src, size_t countDwords);
19 | OBOS_EXPORT void* memzero(void* block, size_t size);
20 | OBOS_EXPORT void* memcpy(void* dest, const void* src, size_t size);
21 | OBOS_EXPORT bool memcmp(const void* blk1, const void* blk2, size_t size);
22 | OBOS_EXPORT bool memcmp(const void* blk1, uint32_t val, size_t size);
23 | OBOS_EXPORT // Returns one less than the actual index of the character
24 | OBOS_EXPORT size_t strCountToChar(const char* string, char ch, bool stopAtZero = true);
25 | OBOS_EXPORT size_t strlen(const char* string);
26 | OBOS_EXPORT bool strcmp(const char* str1, const char* str2);
27 | }
28 | }
--------------------------------------------------------------------------------
/src/oboskrnl/multitasking/arch.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/multitasking/arch.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | // This file defines all platform-specific functions/structures that a port of the kernel to get the scheduler to work.
10 |
11 | #include
12 | #include
13 |
14 | #if defined(__x86_64__) || defined(_WIN64)
15 | #include
16 | #endif
17 |
18 | extern "C" void idleTask();
19 |
20 | namespace obos
21 | {
22 | #ifndef ALLOCATORS_VMM_VMM_H_INCLUDED
23 | namespace memory
24 | {
25 | class VirtualAllocator;
26 | }
27 | #endif
28 | namespace thread
29 | {
30 | void switchToThreadImpl(taskSwitchInfo* info, struct Thread* thread);
31 | bool callBlockCallbackOnThread(taskSwitchInfo* info, bool(*callback)(void* thread, void* userdata), void* par1, void* par2);
32 | void setupThreadContext(taskSwitchInfo* info, void* stackInfo, uintptr_t entry, uintptr_t userdata, size_t stackSize, memory::VirtualAllocator* vallocator, void* asProc);
33 | void freeThreadStackInfo(void* stackInfo, memory::VirtualAllocator* vallocator);
34 | void setupTimerInterrupt();
35 |
36 | OBOS_EXPORT uintptr_t stopTimer();
37 | OBOS_EXPORT void startTimer(uintptr_t);
38 |
39 | OBOS_EXPORT void callScheduler(bool allCores);
40 |
41 | void* getCurrentCpuLocalPtr();
42 | // For any kernel/driver developers, this does nothing but send the other cores to a trampoline.
43 | // It DOES NOT undo the action of StopCPUs()
44 | bool StartCPUs();
45 | OBOS_EXPORT void StopCPUs(bool includingSelf);
46 |
47 | bool inSchedulerFunction(struct Thread* thr);
48 | }
49 | }
--------------------------------------------------------------------------------
/src/oboskrnl/multitasking/cpu_local.h:
--------------------------------------------------------------------------------
1 | /*
2 | multitasking/cpu_local.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 | #include
14 |
15 | namespace obos
16 | {
17 | namespace thread
18 | {
19 | struct cpu_local
20 | {
21 | Thread::StackInfo startup_stack{};
22 | volatile Thread* currentThread = nullptr;
23 | volatile bool schedulerLock = false;
24 | uint32_t cpuId = 0;
25 | bool initialized = false;
26 | Thread::StackInfo temp_stack{};
27 | cpu_local_arch arch_specific{};
28 | bool isBSP = false;
29 | Thread* idleThread = nullptr;
30 | };
31 | extern cpu_local* g_cpuInfo;
32 | extern size_t g_nCPUs;
33 | OBOS_EXPORT cpu_local* GetCurrentCpuLocalPtr();
34 | }
35 | }
--------------------------------------------------------------------------------
/src/oboskrnl/multitasking/locks/mutex.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | multitasking/locks/mutex.cpp
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include
13 | #include
14 |
15 | #include
16 |
17 | #include
18 |
19 | extern obos::locks::Mutex g_allocatorMutex;
20 |
21 | #ifdef __INTELLISENSE__
22 | template
23 | bool __atomic_compare_exchange_n(type* ptr, type* expected, type desired, bool weak, int success_memorder, int failure_memorder);
24 | #endif
25 |
26 | namespace obos
27 | {
28 | namespace thread
29 | {
30 | extern locks::Mutex g_coreGlobalSchedulerLock;
31 | }
32 | namespace locks
33 | {
34 | bool Mutex::Lock(uint64_t timeout, bool block)
35 | {
36 | if (!block && Locked())
37 | {
38 | if (this != &thread::g_coreGlobalSchedulerLock)
39 | SetLastError(OBOS_ERROR_MUTEX_LOCKED);
40 | return false;
41 | }
42 | // Compare m_locked with zero, and if it is zero, then set it to true and return true, otherwise return false and keep m_locked intact.
43 | uint64_t wakeupTime = thread::g_timerTicks + timeout;
44 | if (timeout == 0)
45 | wakeupTime = 0xffffffffffffffff /* UINT64_MAX */;
46 | const bool expected = false;
47 | if (m_locked)
48 | {
49 | if (m_canUseMultitasking && thread::g_initialized)
50 | {
51 | thread::Thread* currentThread = (thread::Thread*)thread::GetCurrentCpuLocalPtr()->currentThread;
52 | currentThread->blockCallback.callback = [](thread::Thread* thr, void* udata)->bool
53 | {
54 | Mutex* _this = (Mutex*)udata;
55 | return _this->m_locked || _this->m_wake || thread::g_timerTicks < thr->wakeUpTime;
56 | };
57 | currentThread->blockCallback.userdata = this;
58 | currentThread->wakeUpTime = wakeupTime;
59 | currentThread->status = thread::THREAD_STATUS_CAN_RUN | thread::THREAD_STATUS_BLOCKED;
60 | thread::callScheduler(false);
61 | }
62 | else
63 | {
64 | while (m_locked && !m_wake && thread::g_timerTicks < wakeupTime);
65 | }
66 | }
67 | while ((__atomic_compare_exchange_n(&m_locked, (bool*)&expected, true, false, 0, 0) || m_wake) || thread::g_timerTicks >= wakeupTime);
68 | if (thread::g_timerTicks >= wakeupTime)
69 | {
70 | SetLastError(OBOS_ERROR_TIMEOUT);
71 | return false;
72 | }
73 | if (thread::g_initialized && m_canUseMultitasking)
74 | m_ownerThread = (thread::Thread*)thread::GetCurrentCpuLocalPtr()->currentThread;
75 | return true;
76 | }
77 | bool Mutex::Unlock()
78 | {
79 | if (thread::g_initialized && m_canUseMultitasking)
80 | {
81 | if (thread::GetCurrentCpuLocalPtr()->currentThread != m_ownerThread)
82 | {
83 | SetLastError(OBOS_ERROR_ACCESS_DENIED);
84 | return false;
85 | }
86 | }
87 | atomic_clear(&m_locked);
88 | m_ownerThread = nullptr;
89 | return true;
90 | }
91 | bool Mutex::Locked() const
92 | {
93 | return atomic_test(&m_locked);
94 | }
95 | Mutex::~Mutex()
96 | {
97 | atomic_set(&m_wake);
98 | thread::callScheduler(false);
99 | m_ownerThread = nullptr;
100 | atomic_clear(&m_locked);
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/src/oboskrnl/multitasking/locks/mutex.h:
--------------------------------------------------------------------------------
1 | /*
2 | multitasking/locks/mutex.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | namespace obos
15 | {
16 | #ifndef MULTIASKING_THREAD_H_INCLUDED
17 | namespace thread
18 | {
19 | struct Thread;
20 | }
21 | #endif
22 | namespace locks
23 | {
24 | class Mutex final
25 | {
26 | public:
27 | OBOS_EXPORT Mutex() : m_canUseMultitasking{ true }, m_initialized{ true } {};
28 | OBOS_EXPORT Mutex(bool canUseMultitasking) : m_canUseMultitasking{ canUseMultitasking }, m_initialized{ true } {};
29 |
30 | ///
31 | /// Locks the mutex.
32 | ///
33 | /// How long to block for, only effective if blockWithScheduler == true.
34 | /// Whether to block if the lock is locked, or to abort.
35 | /// Whether the mutex could be locked, otherwise false. If the function returned false, use GetLastError.
36 | OBOS_EXPORT bool Lock(uint64_t timeout = 0, bool block = true);
37 | ///
38 | /// Unlocks the mutex.
39 | ///
40 | /// Whether the mutex could be unlocked, otherwise false. If the function returned false, use GetLastError.
41 | OBOS_EXPORT bool Unlock();
42 |
43 | ///
44 | /// Returns whether the mutex is locked.
45 | ///
46 | /// Whether the mutex is locked..
47 | OBOS_EXPORT bool Locked() const;
48 |
49 | OBOS_EXPORT bool IsInitialized() const { return m_initialized; }
50 |
51 | OBOS_EXPORT void CanUseMultitasking(bool val) { m_canUseMultitasking = val; };
52 | OBOS_EXPORT bool CanUseMultitasking() const { return m_canUseMultitasking; };
53 |
54 | OBOS_EXPORT ~Mutex();
55 |
56 | [[nodiscard]] void* operator new(size_t )
57 | {
58 | return ImplSlabAllocate(ObjectTypes::Mutex);
59 | }
60 | void operator delete(void* ptr)
61 | {
62 | ImplSlabFree(ObjectTypes::Mutex, ptr);
63 | }
64 | void* operator new[](size_t sz)
65 | {
66 | return ImplSlabAllocate(ObjectTypes::Mutex, sz / sizeof(Mutex));
67 | }
68 | void operator delete[](void* ptr, size_t sz)
69 | {
70 | ImplSlabFree(ObjectTypes::Mutex, ptr, sz / sizeof(Mutex));
71 | }
72 | [[nodiscard]] void* operator new(size_t, void* ptr) noexcept { return ptr; }
73 | [[nodiscard]] void* operator new[](size_t, void* ptr) noexcept { return ptr; }
74 | void operator delete(void*, void*) noexcept {}
75 | void operator delete[](void*, void*) noexcept {}
76 | private:
77 | bool m_wake;
78 | bool m_locked;
79 | bool m_canUseMultitasking = true;
80 | bool m_initialized;
81 | thread::Thread* m_ownerThread;
82 | };
83 |
84 | struct SafeMutex final
85 | {
86 | public:
87 | SafeMutex() = delete;
88 | SafeMutex(Mutex* obj)
89 | :m_obj{obj}
90 | {}
91 | SafeMutex(const SafeMutex&) = default;
92 | SafeMutex& operator=(const SafeMutex&) = default;
93 | SafeMutex(SafeMutex&&) = default;
94 | SafeMutex& operator=(SafeMutex&&) = default;
95 |
96 | bool Lock(uint64_t timeout = 0, bool block = true)
97 | {
98 | if (!m_obj)
99 | return false;
100 | return m_obj->Lock(timeout, block);
101 | }
102 | bool Unlock()
103 | {
104 | if (!m_obj)
105 | return false;
106 | return m_obj->Unlock();
107 | }
108 |
109 | bool Locked() const
110 | {
111 | if (!m_obj)
112 | return false;
113 | return m_obj->Locked();
114 | }
115 |
116 | Mutex* Get() const
117 | {
118 | return m_obj;
119 | }
120 |
121 | ~SafeMutex()
122 | {
123 | Unlock();
124 | }
125 | private:
126 | Mutex* m_obj = nullptr;
127 | };
128 | }
129 | }
--------------------------------------------------------------------------------
/src/oboskrnl/multitasking/process/arch.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/process/arch.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | #if defined(__x86_64__) || defined(_WIN64)
14 | #include
15 | #endif
16 |
17 | namespace obos
18 | {
19 | namespace process
20 | {
21 | void setupContextInfo(procContextInfo* info);
22 | // Don't free the process' virtual address space, as that's done with virtual allocator in TerminateProcess.
23 | void freeProcessContext(procContextInfo* info);
24 | void switchToProcessContext(procContextInfo* info);
25 |
26 | // Makes the thread be at "function" with the current cpu's temporary stack, and passes par1 and par2 to the function.
27 | [[noreturn]] void putThreadAtFunctionWithCPUTempStack(thread::Thread* thread, void* function, void* par1, void* par2);
28 | }
29 | }
--------------------------------------------------------------------------------
/src/oboskrnl/multitasking/process/process.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/process/process.h
3 |
4 | Copyright (c) 2023-2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include