├── .github
└── workflows
│ └── obos-build.yml
├── .gitignore
├── CMakeLists.txt
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── config
├── hyper.cfg
├── hyper_uefi_boot.bin
└── hyper_uefi_boot_old.bin
├── dependencies
├── hyper.cmake
└── uacpi.cmake
├── screenshots
├── 20240512_2114.png
├── 20240728_2338.png
├── 20240729_2257.png
├── 20240730_1559.png
├── 20240730_1639.png
├── 20240806_1401.png
├── 20240806_1612.png
├── 20240807_1158.png
├── 20240823_1544.png
├── 20241017_1948.png
└── 20241230_1558.png
├── scripts
├── find_addr.sh
├── find_addr_m68k.sh
├── generate_initrd-x86_64.sh
├── launch_qemu-m68k.sh
├── launch_qemu.bat
├── launch_qemu.sh
├── make_bp.sh
└── mangle.sh
└── src
├── build
├── m68k
│ ├── driver_link.ld
│ ├── link.ld
│ └── toolchain.cmake
└── x86_64
│ ├── driver_link.ld
│ ├── link.ld
│ └── toolchain.cmake
├── drivers
├── generic
│ ├── ahci
│ │ ├── CMakeLists.txt
│ │ ├── ahci_irq.c
│ │ ├── ahci_irq.h
│ │ ├── command.c
│ │ ├── command.h
│ │ ├── interface.c
│ │ ├── main.c
│ │ └── structs.h
│ ├── initrd
│ │ ├── CMakeLists.txt
│ │ ├── main.c
│ │ ├── name.h
│ │ ├── parse.c
│ │ ├── parse.h
│ │ └── ustar_hdr.h
│ ├── libps2
│ │ ├── CMakeLists.txt
│ │ ├── controller.h
│ │ ├── detect.c
│ │ ├── detect.h
│ │ ├── keyboard.c
│ │ ├── keyboard.h
│ │ ├── main.c
│ │ └── scancode_tables.h
│ ├── r8169
│ │ ├── CMakeLists.txt
│ │ ├── device.c
│ │ ├── main.c
│ │ └── structs.h
│ └── slowfat
│ │ ├── CMakeLists.txt
│ │ ├── alloc.h
│ │ ├── cls_alloc.c
│ │ ├── create.c
│ │ ├── fat_irp.c
│ │ ├── interface.c
│ │ ├── io.c
│ │ ├── lookup.c
│ │ ├── main.c
│ │ ├── probe.c
│ │ └── structs.h
├── test_driver
│ ├── CMakeLists.txt
│ ├── fireworks.c
│ ├── main.c
│ ├── rand.c
│ ├── rand.h
│ └── sin_table.h
└── x86
│ ├── bochs_vbe
│ ├── CMakeLists.txt
│ ├── io.c
│ ├── io.h
│ ├── main.c
│ └── suspend.c
│ ├── i8042
│ ├── CMakeLists.txt
│ ├── ctlr.c
│ ├── main.c
│ ├── ps2_irql.h
│ └── ps2_structs.h
│ └── uart
│ ├── CMakeLists.txt
│ ├── main.c
│ ├── serial_port.c
│ └── serial_port.h
├── inc
└── dev_prefix.h.in
├── init
├── CMakeLists.txt
├── main.c
├── motd.c
└── x86_64-syscall.S
├── isogen
└── CMakeLists.txt
├── oboskrnl
├── CMakeLists.txt
├── allocators
│ ├── base.h
│ ├── basic_allocator.c
│ └── basic_allocator.h
├── arch
│ ├── m68k
│ │ ├── asm_helpers.S
│ │ ├── asm_helpers.h
│ │ ├── boot_info.h
│ │ ├── cpu_local_arch.h
│ │ ├── driver_loader.c
│ │ ├── entry.c
│ │ ├── exception_handlers.c
│ │ ├── goldfish_pic.c
│ │ ├── goldfish_pic.h
│ │ ├── goldfish_rtc.c
│ │ ├── interrupt_frame.h
│ │ ├── irq.c
│ │ ├── irql.c
│ │ ├── isr.S
│ │ ├── loader
│ │ │ ├── Allocator.h
│ │ │ ├── CMakeLists.txt
│ │ │ ├── CppUtils.h
│ │ │ ├── Elf.h
│ │ │ ├── Elf32.h
│ │ │ ├── Entry.S
│ │ │ ├── LICENSE.txt
│ │ │ ├── Limine.h
│ │ │ ├── Linker.lds
│ │ │ ├── List.h
│ │ │ ├── Loader.cpp
│ │ │ ├── Loader.h
│ │ │ ├── Main.cpp
│ │ │ ├── Maths.h
│ │ │ ├── Memory.cpp
│ │ │ ├── Memory.h
│ │ │ ├── NanoPrintf.h
│ │ │ ├── NativePtr.h
│ │ │ ├── README.md
│ │ │ ├── Syslib.cpp
│ │ │ ├── Util.cpp
│ │ │ ├── Util.h
│ │ │ └── Vector.h
│ │ ├── mmu.c
│ │ ├── pmm.c
│ │ ├── pmm.h
│ │ ├── thread_ctx.S
│ │ ├── thread_ctx.c
│ │ └── thread_ctx.h
│ └── x86_64
│ │ ├── asm_helpers.asm
│ │ ├── asm_helpers.h
│ │ ├── bgdt.asm
│ │ ├── boot_info.h
│ │ ├── cmos.c
│ │ ├── cmos.h
│ │ ├── cpu_local_arch.h
│ │ ├── drv_loader.c
│ │ ├── entry.asm
│ │ ├── entry.c
│ │ ├── except.c
│ │ ├── execve.c
│ │ ├── gdbstub
│ │ ├── alloc.c
│ │ ├── alloc.h
│ │ ├── bp.c
│ │ ├── bp.h
│ │ ├── breakpoint.h
│ │ ├── connection.c
│ │ ├── connection.h
│ │ ├── debug.c
│ │ ├── debug.h
│ │ ├── general_query.c
│ │ ├── general_query.h
│ │ ├── packet_dispatcher.c
│ │ ├── packet_dispatcher.h
│ │ ├── stop_reply.c
│ │ └── stop_reply.h
│ │ ├── hpet_table.h
│ │ ├── idt.c
│ │ ├── idt.h
│ │ ├── interrupt_frame.h
│ │ ├── ioapic.c
│ │ ├── ioapic.h
│ │ ├── irq_vector.h
│ │ ├── isr.asm
│ │ ├── lapic.c
│ │ ├── lapic.h
│ │ ├── lapic_timer_calibration.asm
│ │ ├── madt.h
│ │ ├── map.c
│ │ ├── memmanip.asm
│ │ ├── mtrr.c
│ │ ├── mtrr.h
│ │ ├── pci.c
│ │ ├── pmm.c
│ │ ├── pmm.h
│ │ ├── sdt.h
│ │ ├── smp.asm
│ │ ├── smp.c
│ │ ├── sse.c
│ │ ├── sse.h
│ │ ├── ssignal.c
│ │ ├── syscall.asm
│ │ ├── syscall.c
│ │ ├── thread_ctx.asm
│ │ ├── thread_ctx.h
│ │ ├── timer.c
│ │ ├── timer.h
│ │ └── wake.c
├── cmdline.c
├── cmdline.h
├── driver_interface
│ ├── driverId.h
│ ├── drv_sys.c
│ ├── drv_sys.h
│ ├── header.h
│ ├── loader.c
│ ├── loader.h
│ ├── pci.c
│ ├── pci.h
│ ├── pci_irq.c
│ ├── pnp.c
│ └── pnp.h
├── elf
│ ├── elf.h
│ ├── elf32.h
│ ├── elf64.h
│ ├── load.c
│ └── load.h
├── error.h
├── execve.c
├── execve.h
├── external
│ ├── fixedptc.h
│ └── nanoprintf.h
├── font.h
├── gpt.c
├── gpt.h
├── handle.c
├── handle.h
├── init_proc.c
├── init_proc.h
├── int.h
├── irq
│ ├── dpc.c
│ ├── dpc.h
│ ├── irq.c
│ ├── irq.h
│ ├── irql.c
│ ├── irql.h
│ ├── timer.c
│ └── timer.h
├── klog.c
├── klog.h
├── locks
│ ├── event.c
│ ├── event.h
│ ├── mutex.c
│ ├── mutex.h
│ ├── pushlock.c
│ ├── pushlock.h
│ ├── semaphore.c
│ ├── semaphore.h
│ ├── spinlock.c
│ ├── spinlock.h
│ ├── sys_futex.c
│ ├── sys_futex.h
│ ├── wait.c
│ └── wait.h
├── mbr.c
├── mbr.h
├── memmanip.c
├── memmanip.h
├── mm
│ ├── aging.c
│ ├── alloc.c
│ ├── alloc.h
│ ├── bare_map.c
│ ├── bare_map.h
│ ├── context.c
│ ├── context.h
│ ├── disk_swap.c
│ ├── disk_swap.h
│ ├── fork.c
│ ├── fork.h
│ ├── handler.c
│ ├── handler.h
│ ├── init.c
│ ├── init.h
│ ├── initial_swap.c
│ ├── initial_swap.h
│ ├── mm_sys.c
│ ├── mm_sys.h
│ ├── page.h
│ ├── page_table.h
│ ├── pmm.c
│ ├── pmm.h
│ ├── swap.c
│ └── swap.h
├── partition.c
├── partition.h
├── power
│ ├── device.c
│ ├── device.h
│ ├── init.c
│ ├── init.h
│ ├── shutdown.c
│ ├── shutdown.h
│ ├── suspend.c
│ └── suspend.h
├── scheduler
│ ├── cpu_local.h
│ ├── process.c
│ ├── process.h
│ ├── sched_sys.c
│ ├── sched_sys.h
│ ├── schedule.c
│ ├── schedule.h
│ ├── thread.c
│ ├── thread.h
│ └── thread_context_info.h
├── sig_sys.c
├── signal.c
├── signal.h
├── struct_packing.h
├── syscall.c
├── syscall.h
├── text.c
├── text.h
├── utils
│ ├── hashmap.c
│ ├── hashmap.h
│ ├── list.h
│ ├── shared_ptr.c
│ ├── shared_ptr.h
│ ├── string.c
│ ├── string.h
│ ├── tree.h
│ ├── uuid.c
│ └── uuid.h
└── vfs
│ ├── alloc.c
│ ├── alloc.h
│ ├── create.c
│ ├── create.h
│ ├── dirent.c
│ ├── dirent.h
│ ├── dummy_devices.c
│ ├── fd.c
│ ├── fd.h
│ ├── fd_sys.c
│ ├── fd_sys.h
│ ├── init.c
│ ├── init.h
│ ├── irp.h
│ ├── keycode.h
│ ├── limits.h
│ ├── mount.c
│ ├── mount.h
│ ├── namecache.h
│ ├── pagecache.h
│ ├── pipe.c
│ ├── pipe.h
│ ├── tty.c
│ ├── tty.h
│ └── vnode.h
├── sanitizers
├── CMakeLists.txt
├── asan.c
├── asan.h
├── asan_memory.c
├── prof.c
├── prof.h
├── stack.c
└── ubsan.c
├── uACPI
├── CMakeLists.txt
├── ec.c
├── kernel_api.c
├── uacpi_arch_helpers.h
└── uacpi_libc.h
└── user_examples
├── CMakeLists.txt
├── fork_example.c
├── klog_level_example.c
├── mem_usage_example.c
├── mount_example.c
├── powerctl_example.c
├── umount_example.c
└── x86_timeofday_example.c
/.github/workflows/obos-build.yml:
--------------------------------------------------------------------------------
1 | # This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.
2 | # See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
3 | name: Build OBOS.
4 |
5 | on:
6 | push:
7 | branches: [ "master" ]
8 | pull_request:
9 | branches: [ "master" ]
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - uses: actions/checkout@v4
17 |
18 | - name: Set reusable strings
19 | # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
20 | id: strings
21 | shell: bash
22 | run: |
23 | echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
24 |
25 | - name: Get libgcc binaries
26 | run: |
27 | git clone https://codeberg.org/osdev/libgcc-binaries
28 |
29 | - name: Install dependencies.
30 | run: |
31 | sudo apt-get update
32 | sudo apt-get install xorriso nasm llvm clang
33 |
34 | - name: Make empty initrd.tar file
35 | run: touch ${{ github.workspace }}/config/initrd.tar
36 |
37 | - name: Configure CMake
38 | run: >
39 | cmake -B ${{ steps.strings.outputs.build-output-dir }}/x86_64
40 | -DCMAKE_BUILD_TYPE=Release
41 | -DOBOS_USE_CLANG=ON
42 | -DOBOS_ENABLE_UBSAN=ON
43 | -DLIBGCC=`realpath libgcc-binaries/libgcc-x86_64-no-red-zone.a`
44 | --toolchain ${{ github.workspace }}/src/build/x86_64/toolchain.cmake
45 | -S ${{ github.workspace }}
46 |
47 | - name: Build
48 | working-directory: ${{ github.workspace }}/scripts
49 | run: |
50 | chmod +x ${{ github.workspace }}/dependencies/hyper/hyper_install-linux-x86_64
51 | cmake --build ${{ steps.strings.outputs.build-output-dir }}/x86_64
52 | ./generate_initrd-x86_64.sh
53 | cmake --build ${{ steps.strings.outputs.build-output-dir }}/x86_64
54 | - name: Archive code coverage results
55 | uses: actions/upload-artifact@v4
56 | with:
57 | name: obos.iso
58 | path: ${{ github.workspace }}/out/obos.iso
59 | # TODO: Tests
60 | # - name: Test
61 | # working-directory: ${{ steps.strings.outputs.build-output-dir }}
62 | # run:
63 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.vs
2 | /.vscode
3 | /CMakePresets.json
4 | /out
5 | /build
6 | /dependencies/hyper
7 | /dependencies/UltraProtocol
8 | /dependencies/uACPI
9 | /dependencies/include/
10 | /dependencies/needs_download.cmake
11 | /qemu_log.txt
12 | /tar
13 | /src/oboskrnl/inc/*
14 | /.cache
15 | /.clangd
16 | /config/initrd.tar
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribution Guide (If you care)
2 | ## Commits
3 | Make sure to make your commits with a couple changes each.
4 | Don't forget to describe said changes with a relatively-descriptive commit message.
5 | ## Pull Requests
6 | Any pull requests are welcome, as long as no Rust, or other Esoteric languages are included in the code, and they include a feature that actually matters.
7 | All commits should be made on a separate local branch, pushed onto the main repo. You should make a pull request describing your changes (unless they're self explanatory because of the branch name).
8 | ## Notes
9 | Please don't add backdoors to the kernel or other parts of the OS.
10 | Don't modify src/oboskrnl/int.h, unless absolutely neccessary (it will cause a rebuild for any other contributors).
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024-2025 Omar Berrow and contributors
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.
22 |
--------------------------------------------------------------------------------
/config/hyper.cfg:
--------------------------------------------------------------------------------
1 | default-entry = "OBOS"
2 |
3 | [OBOS]
4 | protocol=ultra
5 | higher-half-exclusive=true
6 | kernel-as-module=true
7 | video-mode=auto
8 | cmdline='-initrd-module=initrd -initrd-driver-module=initrd_driver --root-fs-partid initrd --working-set-cap=8388608 --load-modules=/libps2,/slowfat --initial-swap-size=67108864 --log-level=1 --init-args /usr/bin/bash --login'
9 |
10 | binary:
11 | path="/obos/oboskrnl"
12 | allocate-anywhere=true
13 |
14 | page-table:
15 | levels=4
16 | constraint=exactly
17 | null-guard=true
18 |
19 | module:
20 | type="file"
21 | path="/obos/initrd.tar"
22 | name="initrd"
23 | module:
24 | type="file"
25 | path="/obos/initrd"
26 | name="initrd_driver"
27 |
--------------------------------------------------------------------------------
/config/hyper_uefi_boot.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/config/hyper_uefi_boot.bin
--------------------------------------------------------------------------------
/config/hyper_uefi_boot_old.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/config/hyper_uefi_boot_old.bin
--------------------------------------------------------------------------------
/dependencies/hyper.cmake:
--------------------------------------------------------------------------------
1 | # dependencies/hyper.cmake
2 |
3 | # Copyright (c) 2024 Omar Berrow
4 |
5 | include(FetchContent)
6 |
7 | file(MAKE_DIRECTORY "dependencies/include/UltraProtocol")
8 | file(DOWNLOAD
9 | https://github.com/UltraOS/Hyper/releases/download/v0.9.0/hyper_iso_boot
10 | ${CMAKE_SOURCE_DIR}/dependencies/hyper/hyper_iso_boot
11 | )
12 | file(DOWNLOAD
13 | https://github.com/UltraOS/Hyper/releases/download/v0.9.0/BOOTX64.EFI
14 | ${CMAKE_SOURCE_DIR}/dependencies/hyper/BOOTX64.efi
15 | )
16 | if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
17 | set (hyper_install ${CMAKE_SOURCE_DIR}/dependencies/hyper/hyper_install-win64.exe CACHE INTERNAL "The hyper install binary")
18 | file(DOWNLOAD
19 | https://github.com/UltraOS/Hyper/releases/download/v0.9.0/hyper_install-win64.exe
20 | ${hyper_install}
21 | )
22 | elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
23 | set (hyper_install ${CMAKE_SOURCE_DIR}/dependencies/hyper/hyper_install-linux-x86_64 CACHE INTERNAL "The hyper install binary")
24 | file(DOWNLOAD
25 | https://github.com/UltraOS/Hyper/releases/download/v0.9.0/hyper_install-linux-x86_64
26 | ${hyper_install}
27 | )
28 | else()
29 | message(FATAL_ERROR "You must be on windows or linux to compile OBOS.")
30 | endif()
31 | FetchContent_Declare(UltraProtocol
32 | GIT_REPOSITORY https://github.com/UltraOS/UltraProtocol.git
33 | GIT_TAG 69235d363c077a090a9b7a313ed8c6f73e4a4807
34 | SOURCE_DIR ${CMAKE_SOURCE_DIR}/dependencies/UltraProtocol
35 | )
36 | FetchContent_MakeAvailable(UltraProtocol)
37 | file (COPY_FILE "dependencies/UltraProtocol/ultra_protocol.h" "dependencies/include/UltraProtocol/ultra_protocol.h")
38 |
--------------------------------------------------------------------------------
/dependencies/uacpi.cmake:
--------------------------------------------------------------------------------
1 | # dependencies/uacpi.cmake
2 |
3 | # Copyright (c) 2024-2025 Omar Berrow
4 |
5 | if (OBOS_REFRESH_DEPENDENCIES)
6 | include(FetchContent)
7 |
8 | FetchContent_Declare(uACPI
9 | # In honor of the old uACPI link
10 | #GIT_REPOSITORY https://github.com/UltraOS/uACPI.git
11 | GIT_REPOSITORY https://github.com/uACPI/uACPI.git
12 | GIT_TAG 2.1.1
13 | SOURCE_DIR ${CMAKE_SOURCE_DIR}/dependencies/uACPI
14 | )
15 | FetchContent_MakeAvailable(uACPI)
16 |
17 | file (COPY "${CMAKE_SOURCE_DIR}/dependencies/uACPI/include/uacpi" DESTINATION "${CMAKE_SOURCE_DIR}/dependencies/include/")
18 | endif()
19 | set (uacpi_cmake_file ${CMAKE_SOURCE_DIR}/dependencies/uACPI/uacpi.cmake CACHE INTERNAL "The uACPI CMake file.")
20 |
--------------------------------------------------------------------------------
/screenshots/20240512_2114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/screenshots/20240512_2114.png
--------------------------------------------------------------------------------
/screenshots/20240728_2338.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/screenshots/20240728_2338.png
--------------------------------------------------------------------------------
/screenshots/20240729_2257.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/screenshots/20240729_2257.png
--------------------------------------------------------------------------------
/screenshots/20240730_1559.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/screenshots/20240730_1559.png
--------------------------------------------------------------------------------
/screenshots/20240730_1639.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/screenshots/20240730_1639.png
--------------------------------------------------------------------------------
/screenshots/20240806_1401.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/screenshots/20240806_1401.png
--------------------------------------------------------------------------------
/screenshots/20240806_1612.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/screenshots/20240806_1612.png
--------------------------------------------------------------------------------
/screenshots/20240807_1158.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/screenshots/20240807_1158.png
--------------------------------------------------------------------------------
/screenshots/20240823_1544.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/screenshots/20240823_1544.png
--------------------------------------------------------------------------------
/screenshots/20241017_1948.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/screenshots/20241017_1948.png
--------------------------------------------------------------------------------
/screenshots/20241230_1558.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OBOS-dev/obos/5ef388af87e2c9442ead5b552d2a7448f5f71eaa/screenshots/20241230_1558.png
--------------------------------------------------------------------------------
/scripts/find_addr.sh:
--------------------------------------------------------------------------------
1 | cd ..
2 | export address=$1
3 | export exe=$2
4 | if [ -z "$exe" ]
5 | then
6 | export exe=out/oboskrnl
7 | fi
8 | addr2line -e $exe -Cfpira $address
9 | gdb "$exe" -batch -ex "set disassembly-flavor intel" -ex "disassemble/sr $address" | grep --color -i -C 10 -n $address
10 | # objdump -d $exe -C -M intel | grep --color -i -C 10 -n $address
11 | cd scripts
12 |
--------------------------------------------------------------------------------
/scripts/find_addr_m68k.sh:
--------------------------------------------------------------------------------
1 | cd ..
2 | export address=$1
3 | export exe=$2
4 | if [ -z "$exe" ]
5 | then
6 | export exe=out/oboskrnl
7 | fi
8 | m68k-obos-addr2line -e $exe -Cfpira $address
9 | m68k-obos-gdb "$exe" -batch -ex "set disassembly-flavor intel" -ex "disassemble/sr $address" | grep --color -i -C 10 -n $address
10 | # objdump -d $exe -C -M intel | grep --color -i -C 10 -n $address
11 | cd scripts
12 |
--------------------------------------------------------------------------------
/scripts/generate_initrd-x86_64.sh:
--------------------------------------------------------------------------------
1 | export old_pwd=$PWD
2 | cd $(git rev-parse --show-toplevel)
3 | if [[ ! -d tar ]]
4 | then
5 | mkdir tar
6 | fi
7 | cp out/uart tar
8 | cp out/ahci tar
9 | cp out/slowfat tar
10 | cp out/bochs_vbe tar
11 | cp out/r8169 tar
12 | cp out/i8042 tar
13 | cp out/libps2 tar
14 | cp out/init tar
15 | if [[ ! -d tar/dev ]]
16 | then
17 | mkdir tar/dev
18 | fi
19 | cd tar
20 | tar -H ustar -cf ../config/initrd.tar `ls -A`
21 | cd $old_pwd
22 |
--------------------------------------------------------------------------------
/scripts/launch_qemu-m68k.sh:
--------------------------------------------------------------------------------
1 | cd ../
2 |
3 | rm qemu_log.txt
4 |
5 | qemu-system-m68k \
6 | -M virt \
7 | -kernel out/m68k_bootloader \
8 | -cpu m68040 \
9 | -monitor stdio \
10 | -s -S \
11 | -m 512M \
12 | -d int \
13 | -D qemu_log.txt \
14 | -serial file:/dev/stdout \
15 | -append "--root-fs-uuid=initrd --log-level=0" \
16 | -initrd "config/initrd.tar"
17 |
18 | cd scripts
19 |
--------------------------------------------------------------------------------
/scripts/launch_qemu.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | cd ../
4 |
5 | del qemu_log.txt
6 |
7 | qemu-system-x86_64 ^
8 | -drive file=out/obos.iso,format=raw ^
9 | -m 1G ^
10 | -gdb tcp:0.0.0.0:1234 -S ^
11 | -accel tcg ^
12 | -cpu "Haswell" ^
13 | -M q35 ^
14 | -monitor stdio ^
15 | -debugcon file:CON ^
16 | -serial tcp:0.0.0.0:1534,server,nowait ^
17 | -smp cores=4,threads=1,sockets=1 ^
18 | -d int ^
19 | -D qemu_log.txt
20 | rem -no-reboot ^
21 | rem -no-shutdown ^
22 | rem -drive if=pflash,format=raw,unit=1,file=ovmf/OVMF_VARS_4M.fd ^
23 | rem -drive if=pflash,format=raw,unit=0,file=ovmf/OVMF_CODE_4M.fd,readonly=on ^
24 | rem -drive id=disk2,file=disk.img,if=none,format=raw -device ide-hd,drive=disk2,bus=ahci1.1 ^
25 | rem -M smm=off ^
26 |
27 | cd scripts
--------------------------------------------------------------------------------
/scripts/launch_qemu.sh:
--------------------------------------------------------------------------------
1 | cd ../
2 |
3 | rm qemu_log.txt
4 |
5 | echo $@
6 | qemu-system-x86_64 \
7 | -drive format=raw,file=out/obos.iso,media=disk,index=0 \
8 | -m 2G \
9 | -gdb tcp:0.0.0.0:1234 -S \
10 | -M q35 \
11 | -cpu host \
12 | -accel kvm \
13 | -debugcon file:/dev/stdout \
14 | -monitor stdio \
15 | -serial tcp:0.0.0.0:1534,server,nowait \
16 | -smp cores=1,threads=1,sockets=1 \
17 | -d int \
18 | -D qemu_log.txt "$@"
19 |
20 | # -nographic
21 | # -enable-kvm \
22 | # -M smm=off \
23 | # -no-reboot
24 | # -enable-kvm \
25 | # -no-shutdown
26 |
27 | cd scripts
28 |
--------------------------------------------------------------------------------
/scripts/make_bp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | out="for (volatile bool b = ($1); b; );"
3 | which -s xsel
4 | if [ $? -eq 0 ]
5 | then
6 | echo $out | xsel -ibo
7 | else
8 | echo $out
9 | fi
10 |
--------------------------------------------------------------------------------
/scripts/mangle.sh:
--------------------------------------------------------------------------------
1 | echo -e $1 | x86_64-obos-g++ -ffreestanding -o /dev/stdout -xc++ -S -
2 |
--------------------------------------------------------------------------------
/src/build/m68k/link.ld:
--------------------------------------------------------------------------------
1 | OUTPUT_FORMAT(elf32-m68k)
2 |
3 | ENTRY(Arch_KernelEntryBootstrap)
4 |
5 | PHDRS
6 | {
7 | text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */
8 | rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */
9 | data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
10 |
11 | pageable_text PT_LOAD FLAGS((1 << 0) | (1 << 2)); /* Read + Execute */
12 | pageable_data PT_LOAD FLAGS((1 << 1) | (1 << 2)); /* Read + Write */
13 | pageable_rodata PT_LOAD FLAGS((1 << 2)); /* Read only */
14 | }
15 |
16 | SECTIONS
17 | {
18 | . = 0xC0000000;
19 | KERNEL_BASE = .;
20 |
21 | .text : {
22 | *(.text .text.*)
23 | } :text
24 |
25 | . = ALIGN(CONSTANT(MAXPAGESIZE));
26 |
27 |
28 | .rodata : {
29 | *(.rodata .rodata.*)
30 | } :rodata
31 |
32 | . = ALIGN(CONSTANT(MAXPAGESIZE));
33 |
34 | .data : {
35 | *(.data .data.*)
36 | } :data
37 |
38 | .bss : {
39 | *(.bss .bss.*)
40 | *(COMMON)
41 | } :data
42 |
43 | . = ALIGN(CONSTANT(MAXPAGESIZE));
44 |
45 | MmS_MMPageableRangeStart = .;
46 | /* Functions */
47 | .pageable.text : {
48 | *(.pageable.text)
49 | } :pageable_text
50 | . = ALIGN(CONSTANT(MAXPAGESIZE));
51 | /* RW Data. */
52 | .pageable.data : {
53 | *(.pageable.data)
54 | } :pageable_data
55 | . = ALIGN(CONSTANT(MAXPAGESIZE));
56 | .pageable.bss : {
57 | *(.pageable.bss)
58 | } :pageable_data
59 | /* RO Data */
60 | .pageable.rodata : {
61 | *(.pageable.rodata)
62 | } :pageable_rodata
63 | . = ALIGN(CONSTANT(MAXPAGESIZE));
64 | MmS_MMPageableRangeEnd = .;
65 |
66 | /DISCARD/ : {
67 | /* *(.eh_frame*) */
68 | *(.note .note.*)
69 | *(.comment)
70 | }
71 | KERNEL_TOP = .;
72 | }
--------------------------------------------------------------------------------
/src/build/x86_64/driver_link.ld:
--------------------------------------------------------------------------------
1 | OUTPUT_FORMAT(elf64-x86-64)
2 | OUTPUT_ARCH(i386:x86-64)
3 |
4 | ENTRY(OBOS_DriverEntry)
5 |
6 | PHDRS
7 | {
8 | headers PT_PHDR PHDRS;
9 | text PT_LOAD FILEHDR PHDRS FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */
10 | rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */
11 | data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
12 |
13 | /* 0x00010000=PF_OBOS_PAGEABLE */
14 | pageable_text PT_LOAD FLAGS((1 << 0) | (1 << 2) | 0x00010000); /* Read + Execute + Pageable */
15 | pageable_data PT_LOAD FLAGS((1 << 1) | (1 << 2) | 0x00010000); /* Read + Write + Pageable */
16 | pageable_rodata PT_LOAD FLAGS((1 << 2) | 0x00010000); /* Read only + Pageable */
17 |
18 | dynamic PT_DYNAMIC;
19 | }
20 |
21 |
22 | SECTIONS
23 | {
24 | Drv_Base = .;
25 | . = 0x0000000000000000 + SIZEOF_HEADERS;
26 |
27 | .text : {
28 | *(.text .text.*)
29 | } :text
30 |
31 | . = ALIGN(CONSTANT(MAXPAGESIZE));
32 |
33 | .rodata : {
34 | *(.rodata .rodata.*)
35 | } :rodata
36 |
37 | . = ALIGN(CONSTANT(MAXPAGESIZE));
38 |
39 | .data : {
40 | *(.data .data.*)
41 | *(.driverheader)
42 | } :data
43 |
44 | .bss : {
45 | *(.bss .bss.*)
46 | *(COMMON)
47 | } :data
48 |
49 | . = ALIGN(CONSTANT(MAXPAGESIZE));
50 |
51 | /* Functions */
52 | .pageable.text : {
53 | *(.pageable.text)
54 | } :pageable_text
55 | . = ALIGN(CONSTANT(MAXPAGESIZE));
56 | /* RW Data. */
57 | .pageable.data : {
58 | *(.pageable.data)
59 | } :pageable_data
60 | . = ALIGN(CONSTANT(MAXPAGESIZE));
61 | .pageable.bss : {
62 | *(.pageable.bss)
63 | } :pageable_data
64 | . = ALIGN(CONSTANT(MAXPAGESIZE));
65 | /* RO Data */
66 | .pageable.rodata : {
67 | *(.pageable.rodata)
68 | } :pageable_rodata
69 | . = ALIGN(CONSTANT(MAXPAGESIZE));
70 |
71 | /DISCARD/ : {
72 | *(.eh_frame)
73 | *(.note .note.*)
74 | *(.comment)
75 | }
76 |
77 | . = ALIGN(CONSTANT(MAXPAGESIZE));
78 | .dynamic : {
79 | *(.dynamic)
80 | } :data :dynamic
81 |
82 | Drv_Top = .;
83 | }
84 |
--------------------------------------------------------------------------------
/src/build/x86_64/link.ld:
--------------------------------------------------------------------------------
1 | OUTPUT_FORMAT(elf64-x86-64)
2 | OUTPUT_ARCH(i386:x86-64)
3 |
4 | ENTRY(Arch_KernelEntryBootstrap)
5 |
6 | PHDRS
7 | {
8 | text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */
9 | rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */
10 | data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
11 |
12 | pageable_text PT_LOAD FLAGS((1 << 0) | (1 << 2)); /* Read + Execute */
13 | pageable_data PT_LOAD FLAGS((1 << 1) | (1 << 2)); /* Read + Write */
14 | pageable_rodata PT_LOAD FLAGS((1 << 2)); /* Read only */
15 | }
16 |
17 | SECTIONS
18 | {
19 | . = 0xffffffff80000000;
20 | KERNEL_BASE = .;
21 |
22 | MmS_MMPageableRangeStart = .;
23 | /* Functions */
24 | .pageable.text : {
25 | *(.pageable.text)
26 | } :pageable_text
27 | . = ALIGN(CONSTANT(MAXPAGESIZE));
28 | /* RW Data. */
29 | .pageable.data : {
30 | *(.pageable.data)
31 | } :pageable_data
32 | . = ALIGN(CONSTANT(MAXPAGESIZE));
33 | .pageable.bss : {
34 | *(.pageable.bss)
35 | } :pageable_data
36 | /* RO Data */
37 | .pageable.rodata : {
38 | *(.pageable.rodata)
39 | } :pageable_rodata
40 | . = ALIGN(CONSTANT(MAXPAGESIZE));
41 | MmS_MMPageableRangeEnd = .;
42 |
43 | .text : {
44 | *(.text .text.*)
45 | } :text
46 |
47 | . = ALIGN(CONSTANT(MAXPAGESIZE));
48 |
49 |
50 | .rodata : {
51 | *(.rodata .rodata.*)
52 | } :rodata
53 |
54 | . = ALIGN(CONSTANT(MAXPAGESIZE));
55 |
56 | .data : {
57 | *(.data .data.*)
58 | } :data
59 |
60 | .bss : {
61 | *(.bss .bss.*)
62 | *(COMMON)
63 | } :data
64 |
65 | . = ALIGN(CONSTANT(MAXPAGESIZE));
66 |
67 | /DISCARD/ : {
68 | *(.eh_frame)
69 | *(.note .note.*)
70 | *(.comment)
71 | }
72 | KERNEL_TOP = .;
73 | }
74 |
--------------------------------------------------------------------------------
/src/drivers/generic/ahci/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/generic/ahci/CMakeLists.txt
2 | #
3 | # Copyright (c) 2024 Omar Berrow
4 |
5 | add_executable(ahci "main.c" "ahci_irq.c" "command.c" "interface.c")
6 |
7 | target_compile_options(ahci
8 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
9 | PRIVATE $<$:-ffreestanding>
10 | PRIVATE $<$:-Wall>
11 | PRIVATE $<$:-Wextra>
12 | PRIVATE $<$:-fstack-protector-all>
13 | PRIVATE $<$:-fno-builtin-memset>
14 | PRIVATE $<$:-fvisibility=hidden>
15 | PRIVATE $<$:-fPIC>
16 | )
17 |
18 | set_property(TARGET ahci PROPERTY link_depends ${DRIVER_LINKER_SCRIPT})
19 |
20 | target_include_directories(ahci
21 | PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl"
22 | PRIVATE ${OBOSKRNL_EXTERNAL_INCLUDES})
23 |
24 | target_link_options(ahci
25 | PRIVATE "-nostdlib"
26 | PRIVATE "-fPIC"
27 | PRIVATE "-Wl,-shared"
28 | # PRIVATE "-Wl,--allow-shlib-undefined"
29 | PRIVATE "-T" PRIVATE ${DRIVER_LINKER_SCRIPT}
30 | PRIVATE ${TARGET_DRIVER_LINKER_OPTIONS}
31 | )
32 | target_compile_definitions(ahci PRIVATE OBOS_DRIVER=1)
33 |
--------------------------------------------------------------------------------
/src/drivers/generic/ahci/ahci_irq.h:
--------------------------------------------------------------------------------
1 | /*
2 | * drivers/generic/ahci/ahci_irq.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 | #include
13 |
14 | #include
15 |
16 | bool ahci_irq_checker(struct irq* i, void* userdata);
17 | void ahci_irq_handler(struct irq* i, interrupt_frame* frame, void* userdata, irql oldIrql);
18 | extern pci_resource* PCIIrqResource;
19 |
--------------------------------------------------------------------------------
/src/drivers/generic/ahci/command.h:
--------------------------------------------------------------------------------
1 | /*
2 | * drivers/generic/ahci/command.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include "structs.h"
15 |
16 | struct ahci_phys_region
17 | {
18 | uintptr_t phys;
19 | uint32_t sz : 22;
20 | };
21 | enum {
22 | COMMAND_DIRECTION_READ,
23 | COMMAND_DIRECTION_WRITE,
24 | };
25 | struct command_data
26 | {
27 | struct ahci_phys_region* phys_regions;
28 | uint16_t physRegionCount;
29 | uint8_t direction;
30 | uint8_t cmd;
31 | bool awaitingSignal;
32 | // Set when the command is done.
33 | event completionEvent;
34 | obos_status commandStatus;
35 | struct {
36 | uint8_t cmdSlot;
37 | } internal;
38 | };
39 | obos_status SendCommand(Port* port, struct command_data* data, uint64_t lba, uint8_t device, uint16_t count);
40 | obos_status ClearCommand(Port* port, struct command_data* data);
41 | void StopCommandEngine(volatile HBA_PORT* port);
42 | void StartCommandEngine(volatile HBA_PORT* port);
43 |
44 | // Prevents any further transactions from happening.
45 | // This causes SendComamnd to return OBOS_STATUS_RETRY, thus making it's callers also return that.
46 | void HaltTranscations();
47 | // Allows transactions to happen.
48 | void ResumeTranscations();
49 |
50 | // Wait for transcations to complete.
51 | // If shutting down the ahci driver, or preparing to suspend,
52 | // then call this after halting transactions.
53 | void WaitForTranscations();
54 |
--------------------------------------------------------------------------------
/src/drivers/generic/initrd/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/generic/initrd/CMakeLists.txt
2 | #
3 | # Copyright (c) 2024 Omar Berrow
4 |
5 | add_executable(initrd "main.c" "parse.c")
6 |
7 | target_compile_options(initrd
8 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
9 | PRIVATE $<$:-ffreestanding>
10 | PRIVATE $<$:-Wall>
11 | PRIVATE $<$:-Wextra>
12 | PRIVATE $<$:-fstack-protector-all>
13 | PRIVATE $<$:-fno-builtin-memset>
14 | PRIVATE $<$:-fvisibility=hidden>
15 | PRIVATE $<$:-fPIC>
16 | )
17 |
18 | set_property(TARGET initrd PROPERTY link_depends ${DRIVER_LINKER_SCRIPT})
19 |
20 | target_include_directories(initrd
21 | PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl"
22 | PRIVATE ${OBOSKRNL_EXTERNAL_INCLUDES})
23 |
24 | target_link_options(initrd
25 | PRIVATE "-nostdlib"
26 | PRIVATE "-fPIC"
27 | PRIVATE "-T${DRIVER_LINKER_SCRIPT}"
28 | PRIVATE "-Wl,-shared"
29 | # PRIVATE "-Wl,--allow-shlib-undefined"
30 | PRIVATE ${TARGET_DRIVER_LINKER_OPTIONS}
31 | )
32 | target_compile_definitions(initrd PRIVATE OBOS_DRIVER=1)
33 |
--------------------------------------------------------------------------------
/src/drivers/generic/initrd/name.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #define INITRD_DRIVER_NAME "Initial Ramdisk (InitRD) Driver"
--------------------------------------------------------------------------------
/src/drivers/generic/initrd/parse.h:
--------------------------------------------------------------------------------
1 | /*
2 | * drivers/generic/initrd/parse.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include "ustar_hdr.h"
13 |
14 | extern initrd_inode* InitrdRoot;
15 | extern size_t CurrentInodeNumber;
16 |
17 | const ustar_hdr* GetFile(const char* path, obos_status* status);
18 | initrd_inode* DirentLookupFrom(const char* path, initrd_inode* root);
19 | inline static uint64_t oct2bin(const char* str, size_t size)
20 | {
21 | uint64_t n = 0;
22 | const char* c = str;
23 | while (size-- > 0)
24 | n = n * 8 + (uint64_t)(*c++ - '0');
25 | return n;
26 | }
27 | void* malloc(size_t sz);
28 | void* realloc(void* buf, size_t sz);
29 | void free(void* buf);
30 |
--------------------------------------------------------------------------------
/src/drivers/generic/initrd/ustar_hdr.h:
--------------------------------------------------------------------------------
1 | /*
2 | * drivers/generic/initrd/ustar_hdr.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | typedef struct ustar_hdr
15 | {
16 | char filename[100];
17 | char filemode[8];
18 | char owner_uid[8];
19 | char group_uid[8];
20 | char filesize[12]; // In octal!
21 | char last_mod[12]; // In octal!
22 | char chksum[8];
23 | char type;
24 | char linked[100];
25 | char magic[6]; // should be ustar\0
26 | char version[2];
27 | char owner_uname[32];
28 | char group_uname[32];
29 | char unused[16];
30 | char prefix[155];
31 | } OBOS_PACK ustar_hdr;
32 |
33 | typedef struct initrd_inode {
34 | struct {
35 | struct initrd_inode *head, *tail;
36 | size_t nChildren;
37 | } children;
38 | struct initrd_inode *next, *prev, *parent;
39 | char* name;
40 | char* path;
41 | char* data;
42 | size_t filesize;
43 | size_t path_len;
44 | size_t path_size;
45 | size_t name_len;
46 | size_t name_size;
47 | file_type type;
48 | uint32_t ino;
49 | bool persistent : 1;
50 | driver_file_perm perm;
51 | } initrd_inode;
52 |
53 | enum {
54 | FILEMODE_EXEC = BIT(0),
55 | FILEMODE_WRITE = BIT(1),
56 | FILEMODE_READ = BIT(2),
57 | FILEMODE_OTHER_EXEC = FILEMODE_EXEC << 0,
58 | FILEMODE_OTHER_WRITE = FILEMODE_WRITE << 0,
59 | FILEMODE_OTHER_READ = FILEMODE_READ << 0,
60 | FILEMODE_GROUP_EXEC = FILEMODE_EXEC << 3,
61 | FILEMODE_GROUP_WRITE = FILEMODE_WRITE << 3,
62 | FILEMODE_GROUP_READ = FILEMODE_READ << 3,
63 | FILEMODE_OWNER_EXEC = FILEMODE_EXEC << 6,
64 | FILEMODE_OWNER_WRITE = FILEMODE_WRITE << 6,
65 | FILEMODE_OWNER_READ = FILEMODE_READ << 6,
66 | };
67 | enum
68 | {
69 | AREGTYPE = '\0',
70 | REGTYPE = '0',
71 | LNKTYPE = '1',
72 | SYMTYPE = '2',
73 | CHRTYPE = '3',
74 | BLKTYPE = '4',
75 | DIRTYPE = '5',
76 | FIFOTYPE = '6',
77 | CONTYPE = '7',
78 | };
79 | #define USTAR_MAGIC "ustar\0"
--------------------------------------------------------------------------------
/src/drivers/generic/libps2/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/generic/libps2/CMakeLists.txt
2 |
3 | # Copyright (c) 2025 Omar Berrow
4 |
5 | # The motive behind having this instead of directly intergrating PS/2 drivers
6 | # into a file is to allow PS/2 keyboard/mouse drivers to be shared between
7 | # platforms with different controllers.
8 |
9 | add_executable(libps2 "keyboard.c" "detect.c" "main.c")
10 |
11 | target_compile_options(libps2
12 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
13 | PRIVATE $<$:-ffreestanding>
14 | PRIVATE $<$:-Wall>
15 | PRIVATE $<$:-Wextra>
16 | PRIVATE $<$:-fstack-protector-all>
17 | PRIVATE $<$:-fno-builtin-memset>
18 | PRIVATE $<$:-fvisibility=hidden>
19 | PRIVATE $<$:-fPIC>
20 | )
21 |
22 | set_property(TARGET libps2 PROPERTY link_depends ${DRIVER_LINKER_SCRIPT})
23 |
24 | target_include_directories(libps2
25 | PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl"
26 | PRIVATE "${CMAKE_SOURCE_DIR}/src/drivers"
27 | PRIVATE ${OBOSKRNL_EXTERNAL_INCLUDES})
28 |
29 | target_link_options(libps2
30 | PRIVATE "-nostdlib"
31 | PRIVATE "-fPIC"
32 | PRIVATE "-Wl,-shared"
33 | # PRIVATE "-Wl,--allow-shlib-undefined"
34 | PRIVATE "-T" PRIVATE ${DRIVER_LINKER_SCRIPT}
35 | PRIVATE ${TARGET_DRIVER_LINKER_OPTIONS}
36 | )
37 | target_compile_definitions(libps2 PRIVATE OBOS_DRIVER=1)
38 |
39 | target_compile_definitions(libps2
40 | PRIVATE $<$:OBOS_DEBUG>
41 | PRIVATE $<$:OBOS_RELEASE>
42 | PRIVATE $<$:OBOS_RELEASE>
43 | PRIVATE $<$:OBOS_RELEASE>
44 | PUBLIC OBOS_DRIVER=1
45 | )
46 |
--------------------------------------------------------------------------------
/src/drivers/generic/libps2/controller.h:
--------------------------------------------------------------------------------
1 | /*
2 | * drivers/generic/libps2/controller.h
3 | *
4 | * Copyright (c) 2025 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include
15 |
16 | #if defined(__x86_64__) || defined(__i686__)
17 | # include
18 | #endif
19 |
20 | enum {PS2_PORT_MAGIC=0x1BADBEEF};
21 |
22 | enum {
23 | PS2_DEV_TYPE_UNKNOWN = 'u',
24 | PS2_DEV_TYPE_KEYBOARD = 'k',
25 | PS2_DEV_TYPE_MOUSE = 'm',
26 | };
27 |
28 | typedef struct ps2_port {
29 | union {
30 | uint64_t data;
31 | void* pdata;
32 | };
33 | union {
34 | uint64_t udata;
35 | void* pudata;
36 | };
37 |
38 | union {
39 | obos_status(*read_code)(void* handle, keycode* out, bool block);
40 | obos_status(*read_raw)(void* handle, void* buf, bool block);
41 | };
42 | // Gets the amount of readable objects for that handle.
43 | obos_status(*get_readable_count)(void* handle, size_t* nReadable);
44 | obos_status(*make_handle)(struct ps2_port* port, void** handle);
45 | // To be set by the driver when there is at least one object ready to be read by read_*
46 | // Should be a 'EVENT_NOTIFICATION'
47 | event* data_ready_event;
48 |
49 | // NOTE: Remove this and make it correct when the net-stack branch is
50 | // merged, and add the (un)reference_interface callbacks.
51 | void* default_handle;
52 |
53 | struct irq* irq;
54 | void(*data_ready)(struct ps2_port* channel, uint8_t data);
55 |
56 | size_t blk_size;
57 |
58 | union {
59 | OBOS_PACK struct {
60 | char id[4];
61 | uint8_t padding;
62 | };
63 | char str_id[5];
64 | };
65 |
66 | uint32_t magic;
67 | uint32_t gsi;
68 |
69 | uint16_t model;
70 |
71 | char type;
72 |
73 | bool works : 1;
74 | bool suppress_irqs : 1;
75 | bool second : 1;
76 | } ps2_port;
77 |
78 | DRV_EXPORT void PS2_DeviceWrite(bool channel_two, uint8_t val);
79 | DRV_EXPORT uint8_t PS2_DeviceRead(uint32_t spin_timeout, obos_status* status);
80 | DRV_EXPORT obos_status PS2_EnableChannel(bool channel_two, bool status);
81 | DRV_EXPORT obos_status PS2_MaskChannelIRQs(bool channel_two, bool mask);
82 | DRV_EXPORT obos_status PS2_FlushInput();
83 | DRV_EXPORT ps2_port* PS2_GetPort(bool channel_two);
--------------------------------------------------------------------------------
/src/drivers/generic/libps2/detect.h:
--------------------------------------------------------------------------------
1 | /*
2 | * generic/libps2/detect.h
3 | *
4 | * Copyright (c) 2025 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include "controller.h"
12 |
13 | void PS2_DetectDevice(ps2_port* port);
14 |
15 | uint8_t PS2_SendCommand(ps2_port* port, uint8_t cmd, size_t nArgs, ...);
--------------------------------------------------------------------------------
/src/drivers/generic/libps2/keyboard.h:
--------------------------------------------------------------------------------
1 | /*
2 | * drivers/generic/libps2/keyboard.h
3 | *
4 | * Copyright (c) 2025 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include
15 |
16 | #include
17 |
18 | #include "controller.h"
19 |
20 | #define PS2_ACK 0xfa
21 | #define PS2_RESEND 0xfe
22 | #define PS2_INVALID_RESPONSE 0xff
23 |
24 | enum {
25 | PS2K_MAGIC_VALUE = 0xFEE1DEAD,
26 | PS2K_HND_MAGIC_VALUE = 0xFEE1DEAE
27 | };
28 |
29 | typedef struct ps2k_ringbuffer
30 | {
31 | event e;
32 | union {
33 | void* buff;
34 | keycode* keycodes;
35 | };
36 | size_t size;
37 | size_t nElements;
38 | size_t out_ptr;
39 | size_t handle_count;
40 | } ps2k_ringbuffer;
41 |
42 | typedef struct ps2k_handle {
43 | uint32_t magic; // PS2K_HND_MAGIC_VALUE
44 | ps2_port* port;
45 | size_t in_ptr;
46 | } ps2k_handle;
47 |
48 | obos_status PS2_RingbufferInitialize(ps2k_ringbuffer* buff);
49 | obos_status PS2_RingbufferAppend(ps2k_ringbuffer* buff, keycode code, bool signal);
50 | obos_status PS2_RingbufferFetch(const ps2k_ringbuffer* buff, size_t* in_ptr, keycode* code);
51 | obos_status PS2_RingbufferFree(ps2k_ringbuffer* buff);
52 |
53 | typedef struct ps2k_data {
54 | struct ps2k_ringbuffer input;
55 | ps2_port* port;
56 | uint32_t ps2k_magic;
57 | dpc dpc;
58 | uint8_t set;
59 | bool initialized : 1;
60 | bool processing_extended : 1;
61 | bool processing_release : 1; // only valid if set == 2
62 | bool super_key : 1;
63 | bool caps_lock : 1;
64 | bool num_lock : 1;
65 | bool ctrl : 1;
66 | bool shift : 1;
67 | bool alt : 1;
68 | bool fn : 1;
69 | } ps2k_data;
70 |
71 | void PS2_InitializeKeyboard(ps2_port* port);
72 | void PS2_FreeKeyboard(ps2_port* port);
--------------------------------------------------------------------------------
/src/drivers/generic/r8169/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/generic/r8169/CMakeLists.txt
2 | #
3 | # Copyright (c) 2025 Omar Berrow
4 |
5 | add_executable(r8169 "main.c" "device.c")
6 |
7 | target_compile_options(r8169
8 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
9 | PRIVATE $<$:-ffreestanding>
10 | PRIVATE $<$:-Wall>
11 | PRIVATE $<$:-Wextra>
12 | PRIVATE $<$:-fstack-protector-all>
13 | PRIVATE $<$:-fno-builtin-memset>
14 | PRIVATE $<$:-fvisibility=hidden>
15 | PRIVATE $<$:-fPIC>
16 | )
17 |
18 | set_property(TARGET r8169 PROPERTY link_depends ${DRIVER_LINKER_SCRIPT})
19 |
20 | target_include_directories(r8169
21 | PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl"
22 | PRIVATE ${OBOSKRNL_EXTERNAL_INCLUDES})
23 |
24 | target_link_options(r8169
25 | PRIVATE "-nostdlib"
26 | PRIVATE "-fPIC"
27 | PRIVATE "-Wl,-shared"
28 | # PRIVATE "-Wl,--allow-shlib-undefined"
29 | PRIVATE "-T" PRIVATE ${DRIVER_LINKER_SCRIPT}
30 | PRIVATE ${TARGET_DRIVER_LINKER_OPTIONS}
31 | )
32 | target_compile_definitions(r8169 PRIVATE OBOS_DRIVER=1)
33 |
--------------------------------------------------------------------------------
/src/drivers/generic/slowfat/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/generic/slowfat/CMakeLists.txt
2 | #
3 | # Copyright (c) 2024 Omar Berrow
4 |
5 | add_executable(slowfat "main.c" "probe.c" "lookup.c" "interface.c"
6 | "cls_alloc.c" "io.c" "create.c" "fat_irp.c"
7 | )
8 |
9 | target_compile_options(slowfat
10 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
11 | PRIVATE $<$:-ffreestanding>
12 | PRIVATE $<$:-Wall>
13 | PRIVATE $<$:-Wextra>
14 | PRIVATE $<$:-fstack-protector-all>
15 | PRIVATE $<$:-fno-builtin-memset>
16 | PRIVATE $<$:-fvisibility=hidden>
17 | PRIVATE $<$:-fPIC>
18 | )
19 |
20 | set_property(TARGET slowfat PROPERTY link_depends ${DRIVER_LINKER_SCRIPT})
21 |
22 | target_include_directories(slowfat
23 | PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl"
24 | PRIVATE ${OBOSKRNL_EXTERNAL_INCLUDES})
25 |
26 | target_link_options(slowfat
27 | PRIVATE "-nostdlib"
28 | PRIVATE "-fPIC"
29 | PRIVATE "-T${DRIVER_LINKER_SCRIPT}"
30 | PRIVATE "-Wl,-shared"
31 | # PRIVATE "-Wl,--allow-shlib-undefined"
32 | PRIVATE ${TARGET_DRIVER_LINKER_OPTIONS}
33 | )
34 | target_compile_definitions(slowfat PRIVATE OBOS_DRIVER=1)
35 |
--------------------------------------------------------------------------------
/src/drivers/generic/slowfat/alloc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * drivers/generic/slowfat/alloc.h
3 | *
4 | * Copyright (c) 2024-2025 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | #include "structs.h"
14 |
15 | // All functions in this file, unless otherwise specified, should take the fat lock in the fat_cache struct.
16 | // returns UINT32_MAX if no sector was found
17 | uint32_t AllocateClusters(fat_cache* volume, size_t nClusters);
18 | // Returns true if the cluster region was extended, otherwise you need to reallocate the clusters.
19 | bool ExtendClusters(fat_cache* volume, uint32_t cluster, size_t nClusters, size_t oldClusterCount);
20 | void TruncateClusters(fat_cache* volume, uint32_t cluster, size_t newClusterCount, size_t oldClusterCount);
21 | void FreeClusters(fat_cache* volume, uint32_t cluster, size_t nClusters);
22 | void InitializeCacheFreelist(fat_cache* volume);
23 |
24 | // if status is passed as OBOS_STATUS_SUCCESS, the cluster passed is valid.
25 | // if status is passed as OBOS_STATUS_EOF, the cluster passed is valid, and is the last cluster of the chain.
26 | // if status is passed as OBOS_STATUS_ABORTED, the cluster passed is not valid, as an error has occurred following the chain.
27 | typedef iterate_decision(*clus_chain_cb)(uint32_t cluster, obos_status status, void* userdata);
28 | obos_status NextCluster(fat_cache* cache, uint32_t cluster, uint8_t* sec_buf, uint32_t* ret);
29 | uint32_t ClusterSeek(fat_cache* cache, uint32_t cluster, uint32_t nClusters);
30 | void FollowClusterChain(fat_cache* volume, uint32_t clus, clus_chain_cb callback, void* userdata);
--------------------------------------------------------------------------------
/src/drivers/test_driver/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/test_driver/CMakeLists.txt
2 | #
3 | # Copyright (c) 2024 Omar Berrow
4 |
5 | add_executable(test_driver "main.c" "fireworks.c" "rand.c")
6 |
7 | target_compile_options(test_driver
8 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
9 | PRIVATE $<$:-ffreestanding>
10 | PRIVATE $<$:-Wall>
11 | PRIVATE $<$:-Wextra>
12 | PRIVATE $<$:-fstack-protector-all>
13 | PRIVATE $<$:-fno-builtin-memset>
14 | PRIVATE $<$:-fvisibility=hidden>
15 | PRIVATE $<$:-fPIC>
16 | )
17 |
18 | set_target_properties(test_driver PROPERTIES link_depends ${DRIVER_LINKER_SCRIPT})
19 |
20 | target_include_directories(test_driver
21 | PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl"
22 | PRIVATE ${OBOSKRNL_EXTERNAL_INCLUDES})
23 |
24 | target_link_options(test_driver
25 | PRIVATE "-nostdlib"
26 | PRIVATE "-fPIC"
27 | PRIVATE "-T${DRIVER_LINKER_SCRIPT}"
28 | PRIVATE "-Wl,-shared"
29 | # PRIVATE "-Wl,--allow-shlib-undefined"
30 | PRIVATE ${TARGET_DRIVER_LINKER_OPTIONS}
31 | )
32 |
33 | target_compile_definitions(test_driver PRIVATE OBOS_DRIVER=1)
34 |
--------------------------------------------------------------------------------
/src/drivers/test_driver/rand.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 |
6 | #include "rand.h"
7 |
8 | // shamelessly stolen from https://osdev.wiki/wiki/Random_Number_Generator#Mersenne_Twister
9 |
10 | #if OBOS_ARCHITECTURE_BITS == 32
11 | #define STATE_SIZE 624
12 | #define MIDDLE 397
13 | #define INIT_SHIFT 30
14 | #define INIT_FACT 1812433253
15 | #define TWIST_MASK 0x9908b0df
16 | #define SHIFT1 11
17 | #define MASK1 0xffffffff
18 | #define SHIFT2 7
19 | #define MASK2 0x9d2c5680
20 | #define SHIFT3 15
21 | #define MASK3 0xefc60000
22 | #define SHIFT4 18
23 | #else
24 | #define STATE_SIZE 312
25 | #define MIDDLE 156
26 | #define INIT_SHIFT 62
27 | #define TWIST_MASK 0xb5026f5aa96619e9
28 | #define INIT_FACT 6364136223846793005
29 | #define SHIFT1 29
30 | #define MASK1 0x5555555555555555
31 | #define SHIFT2 17
32 | #define MASK2 0x71d67fffeda60000
33 | #define SHIFT3 37
34 | #define MASK3 0xfff7eee000000000
35 | #define SHIFT4 43
36 | #endif
37 |
38 | #define LOWER_MASK 0x7fffffff
39 | #define UPPER_MASK (~(uintptr_t)LOWER_MASK)
40 | static uintptr_t state[STATE_SIZE];
41 | static size_t index = STATE_SIZE + 1;
42 |
43 | void mt_seed(uintptr_t s)
44 | {
45 | index = STATE_SIZE;
46 | state[0] = s;
47 | for (size_t i = 1; i < STATE_SIZE; i++)
48 | state[i] = (INIT_FACT * (state[i - 1] ^ (state[i - 1] >> INIT_SHIFT))) + i;
49 | }
50 |
51 | static void twist(void)
52 | {
53 | for (size_t i = 0; i < STATE_SIZE; i++)
54 | {
55 | uintptr_t x = (state[i] & UPPER_MASK) | (state[(i + 1) % STATE_SIZE] & LOWER_MASK);
56 | x = (x >> 1) ^ (x & 1? TWIST_MASK : 0);
57 | state[i] = state[(i + MIDDLE) % STATE_SIZE] ^ x;
58 | }
59 | index = 0;
60 | }
61 |
62 | uintptr_t mt_random(void)
63 | {
64 | if (index >= STATE_SIZE)
65 | {
66 | OBOS_ASSERT(index == STATE_SIZE || !"Generator never seeded");
67 | twist();
68 | }
69 |
70 | uintptr_t y = state[index];
71 | y ^= (y >> SHIFT1) & MASK1;
72 | y ^= (y << SHIFT2) & MASK2;
73 | y ^= (y << SHIFT3) & MASK3;
74 | y ^= y >> SHIFT4;
75 |
76 | index++;
77 | return y;
78 | }
79 |
80 | OBOS_WEAK uintptr_t random_seed()
81 | {
82 | return CoreS_GetNativeTimerTick();
83 | }
--------------------------------------------------------------------------------
/src/drivers/test_driver/rand.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | uintptr_t mt_random(void);
6 | void mt_seed(uintptr_t seed);
7 | uintptr_t random_seed();
--------------------------------------------------------------------------------
/src/drivers/x86/bochs_vbe/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/x86/bochs_vbe/CMakeLists.txt
2 | #
3 | # Copyright (c) 2024 Omar Berrow
4 |
5 | add_executable(bochs_vbe "main.c" "suspend.c" "io.c")
6 |
7 | target_compile_options(bochs_vbe
8 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
9 | PRIVATE $<$:-ffreestanding>
10 | PRIVATE $<$:-Wall>
11 | PRIVATE $<$:-Wextra>
12 | PRIVATE $<$:-fstack-protector-all>
13 | PRIVATE $<$:-fno-builtin-memset>
14 | PRIVATE $<$:-fvisibility=hidden>
15 | PRIVATE $<$:-fPIC>
16 | )
17 |
18 | set_property(TARGET bochs_vbe PROPERTY link_depends ${DRIVER_LINKER_SCRIPT})
19 |
20 | target_include_directories(bochs_vbe
21 | PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl"
22 | PRIVATE ${OBOSKRNL_EXTERNAL_INCLUDES})
23 |
24 | target_link_options(bochs_vbe
25 | PRIVATE "-nostdlib"
26 | PRIVATE "-fPIC"
27 | PRIVATE "-Wl,-shared"
28 | # PRIVATE "-Wl,--allow-shlib-undefined"
29 | PRIVATE "-T" PRIVATE ${DRIVER_LINKER_SCRIPT}
30 | PRIVATE ${TARGET_DRIVER_LINKER_OPTIONS}
31 | )
32 | target_compile_definitions(bochs_vbe PRIVATE OBOS_DRIVER=1)
33 |
--------------------------------------------------------------------------------
/src/drivers/x86/bochs_vbe/io.c:
--------------------------------------------------------------------------------
1 | /*
2 | * drivers/x86/bochs_vbe/io.c
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #include
8 |
9 | #include
10 |
11 | #include "io.h"
12 |
13 | #define INDEX_REG 0x1ce
14 | #define DATA_REG 0x1cf
15 |
16 | void WriteRegister(uint16_t index, uint16_t val)
17 | {
18 | outw(INDEX_REG, index);
19 | outw(DATA_REG, val);
20 | }
21 | uint16_t ReadRegister(uint16_t index)
22 | {
23 | outw(INDEX_REG, index);
24 | return inw(DATA_REG);
25 | }
26 |
--------------------------------------------------------------------------------
/src/drivers/x86/bochs_vbe/io.h:
--------------------------------------------------------------------------------
1 | /*
2 | * drivers/x86/bochs_vbe/io.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #define INDEX_ID 0
12 | #define INDEX_XRES 1
13 | #define INDEX_YRES 2
14 | #define INDEX_BPP 3
15 | #define INDEX_ENABLE 4
16 | #define INDEX_BANK 5
17 | #define INDEX_VIRT_WIDTH 6
18 | #define INDEX_VIRT_HEIGHT 7
19 | #define INDEX_X_OFFSET 8
20 | #define INDEX_Y_OFFSET 9
21 |
22 | void WriteRegister(uint16_t index, uint16_t val);
23 | uint16_t ReadRegister(uint16_t index);
24 |
--------------------------------------------------------------------------------
/src/drivers/x86/bochs_vbe/suspend.c:
--------------------------------------------------------------------------------
1 | /*
2 | * drivers/x86/bochs_vbe/suspend.c
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #include
8 |
9 | #include
10 |
11 | #include "io.h"
12 |
13 | /*
14 | * We need to save:
15 | * xres
16 | * yres
17 | * virtual width
18 | * virtual height
19 | * bpp
20 | * the bank
21 | * x offset
22 | * y offset
23 | * the value of the enable register
24 | */
25 |
26 | struct {
27 | uint32_t xres, yres;
28 | uint32_t virt_width, virt_height;
29 | uint32_t bpp;
30 | uint32_t bank;
31 | uint32_t xoffset, yoffset;
32 | uint32_t enable;
33 | } saved_vals;
34 |
35 | void on_suspend()
36 | {
37 | saved_vals.xres = ReadRegister(INDEX_XRES);
38 | saved_vals.yres = ReadRegister(INDEX_YRES);
39 | saved_vals.virt_height = ReadRegister(INDEX_VIRT_HEIGHT);
40 | saved_vals.virt_width = ReadRegister(INDEX_VIRT_WIDTH);
41 | saved_vals.bpp = ReadRegister(INDEX_BPP);
42 | saved_vals.bank = ReadRegister(INDEX_BANK);
43 | saved_vals.xoffset = ReadRegister(INDEX_X_OFFSET);
44 | saved_vals.yoffset = ReadRegister(INDEX_Y_OFFSET);
45 | saved_vals.enable = ReadRegister(INDEX_ENABLE);
46 | }
47 |
48 | #define VGA_ATT_W 0x3C0
49 | #define VGA_MIS_W 0x3C2
50 | #define VGA_IS1_RC 0x3DA
51 | #define VGA_MIS_COLOR 0x01
52 |
53 | void on_wake()
54 | {
55 | // for (volatile bool b = true; b; )
56 | // asm volatile ("" : :"r"(b) :"memory");
57 |
58 | // NOTE: PCI stuff is already restored by now.
59 |
60 | outb(VGA_MIS_W, VGA_MIS_COLOR);
61 | inb(VGA_IS1_RC);
62 | outb(VGA_ATT_W, 0);
63 |
64 | WriteRegister(INDEX_ENABLE, 0);
65 | WriteRegister(INDEX_BPP, saved_vals.bpp);
66 | WriteRegister(INDEX_XRES, saved_vals.xres);
67 | WriteRegister(INDEX_YRES, saved_vals.yres);
68 | WriteRegister(INDEX_BANK, saved_vals.bank);
69 | WriteRegister(INDEX_VIRT_WIDTH, saved_vals.virt_width);
70 | WriteRegister(INDEX_VIRT_HEIGHT, saved_vals.virt_height);
71 | WriteRegister(INDEX_X_OFFSET, saved_vals.xoffset);
72 | WriteRegister(INDEX_Y_OFFSET, saved_vals.yoffset);
73 | WriteRegister(INDEX_ENABLE, saved_vals.enable | BIT(7));
74 |
75 | outb(VGA_MIS_W, VGA_MIS_COLOR);
76 | inb(VGA_IS1_RC);
77 | outb(VGA_ATT_W, 0x20);
78 | }
79 |
--------------------------------------------------------------------------------
/src/drivers/x86/i8042/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/x86/i8042/CMakeLists.txt
2 | #
3 | # Copyright (c) 2025 Omar Berrow
4 |
5 | add_executable(i8042 "main.c" "ctlr.c")
6 |
7 | target_compile_options(i8042
8 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
9 | PRIVATE $<$:-ffreestanding>
10 | PRIVATE $<$:-Wall>
11 | PRIVATE $<$:-Wextra>
12 | PRIVATE $<$:-fstack-protector-all>
13 | PRIVATE $<$:-fno-builtin-memset>
14 | PRIVATE $<$:-fvisibility=hidden>
15 | PRIVATE $<$:-fPIC>
16 | )
17 |
18 | set_property(TARGET i8042 PROPERTY link_depends ${DRIVER_LINKER_SCRIPT})
19 |
20 | target_include_directories(i8042
21 | PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl"
22 | PRIVATE "${CMAKE_SOURCE_DIR}/src/drivers"
23 | PRIVATE ${OBOSKRNL_EXTERNAL_INCLUDES})
24 |
25 | target_link_options(i8042
26 | PRIVATE "-nostdlib"
27 | PRIVATE "-fPIC"
28 | PRIVATE "-Wl,-shared"
29 | # PRIVATE "-Wl,--allow-shlib-undefined"
30 | PRIVATE "-T" PRIVATE ${DRIVER_LINKER_SCRIPT}
31 | PRIVATE ${TARGET_DRIVER_LINKER_OPTIONS}
32 | )
33 | target_compile_definitions(i8042 PRIVATE OBOS_DRIVER=1)
34 |
--------------------------------------------------------------------------------
/src/drivers/x86/i8042/ps2_irql.h:
--------------------------------------------------------------------------------
1 | #ifndef IRQL_PS2
2 | # define IRQL_PS2 3
3 | #endif
--------------------------------------------------------------------------------
/src/drivers/x86/i8042/ps2_structs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * drivers/x86/uart/ps2_structs.h
3 | *
4 | * Copyright (c) 2025 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include
15 | #include
16 |
17 | #define PS2_DATA 0x60
18 | #define PS2_CMD_STATUS 0x64
19 |
20 | enum {
21 | PS2_OUTPUT_BUFFER_FULL = BIT(0),
22 | PS2_INPUT_BUFFER_FULL = BIT(1),
23 | PS2_SYSTEM_FLAG = BIT(2),
24 | // "0 = data written to input buffer is data for PS/2 device, 1 = data written to input buffer is data for PS/2 controller command"
25 | PS2_CMD_DATA = BIT(3),
26 | PS2_TIMEOUT = BIT(6),
27 | PS2_PARITY_ERROR = BIT(7),
28 | };
29 |
30 | #define PS2_CTLR_READ_RAM_CMD(n) (0x20+((n)&0x1f))
31 | #define PS2_CTLR_WRITE_RAM_CMD(n) (0x60+((n)&0x1f))
32 | #define PS2_CTLR_DISABLE_PORT_TWO 0xA7
33 | #define PS2_CTLR_ENABLE_PORT_TWO 0xA8
34 | #define PS2_CTLR_TEST_PORT_TWO 0xA9
35 | #define PS2_CTLR_TEST 0xAA
36 | #define PS2_CTLR_TEST_PORT_ONE 0xAB
37 | #define PS2_CTLR_DUMP_RAM 0xAC
38 | #define PS2_CTLR_DISABLE_PORT_ONE 0xAD
39 | #define PS2_CTLR_ENABLE_PORT_ONE 0xAE
40 | #define PS2_CTLR_READ_CTLR_OUT_BUFFER 0xD0
41 | #define PS2_CTLR_WRITE_CTLR_OUT_BUFFER 0xD1
42 | #define PS2_CTLR_WRITE_PORT_TWO 0xD4
43 |
44 | enum {
45 | PS2_CTLR_CONFIG_PORT_ONE_IRQ = BIT(0),
46 | PS2_CTLR_CONFIG_PORT_TWO_IRQ = BIT(1),
47 | PS2_CTLR_CONFIG_SYSTEM_FLAG = BIT(2),
48 | PS2_CTLR_CONFIG_PORT_ONE_CLOCK = BIT(4),
49 | PS2_CTLR_CONFIG_PORT_TWO_CLOCK = BIT(5),
50 | PS2_CTLR_CONFIG_PORT_ONE_TRANSLATION = BIT(6),
51 | };
52 |
53 | #include
54 |
55 | extern struct ps2_ctlr_data {
56 | bool dual_channel : 1;
57 | ps2_port ports[2];
58 | spinlock lock;
59 | } PS2_CtlrData;
60 |
61 | obos_status PS2_InitializeController();
--------------------------------------------------------------------------------
/src/drivers/x86/uart/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # drivers/x86/uart/CMakeLists.txt
2 | #
3 | # Copyright (c) 2024 Omar Berrow
4 |
5 | add_executable(uart "main.c" "serial_port.c")
6 |
7 | target_compile_options(uart
8 | PRIVATE $<$:${TARGET_DRIVER_COMPILE_OPTIONS_C}>
9 | PRIVATE $<$:-ffreestanding>
10 | PRIVATE $<$:-Wall>
11 | PRIVATE $<$:-Wextra>
12 | PRIVATE $<$:-fstack-protector-all>
13 | PRIVATE $<$:-fno-builtin-memset>
14 | PRIVATE $<$:-fvisibility=hidden>
15 | PRIVATE $<$:-fPIC>
16 | )
17 |
18 | set_property(TARGET uart PROPERTY link_depends ${DRIVER_LINKER_SCRIPT})
19 |
20 | target_include_directories(uart
21 | PRIVATE "${CMAKE_SOURCE_DIR}/src/oboskrnl"
22 | PRIVATE ${OBOSKRNL_EXTERNAL_INCLUDES})
23 |
24 | target_link_options(uart
25 | PRIVATE "-nostdlib"
26 | PRIVATE "-fPIC"
27 | PRIVATE "-Wl,-shared"
28 | # PRIVATE "-Wl,--allow-shlib-undefined"
29 | PRIVATE "-T" PRIVATE ${DRIVER_LINKER_SCRIPT}
30 | PRIVATE ${TARGET_DRIVER_LINKER_OPTIONS}
31 | )
32 | target_compile_definitions(uart PRIVATE OBOS_DRIVER=1)
33 |
--------------------------------------------------------------------------------
/src/inc/dev_prefix.h.in:
--------------------------------------------------------------------------------
1 | #cmakedefine OBOS_DEV_PREFIX "@OBOS_DEV_PREFIX@"
--------------------------------------------------------------------------------
/src/init/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # init/CMakeLists.txt
2 | #
3 | # Copyright (c) 2025 Omar Berrow
4 |
5 | if (${OBOS_ARCHITECTURE} STREQUAL "x86_64")
6 | add_library(syscall_invoke STATIC "x86_64-syscall.S")
7 | endif()
8 |
9 | if (OBOS_ENABLE_UBSAN)
10 | add_compile_options("-fno-sanitize=undefined")
11 | endif()
12 | if (OBOS_ENABLE_KASAN)
13 | add_compile_options("-fno-sanitize=address")
14 | endif()
15 |
16 | link_libraries(syscall_invoke)
17 |
18 | add_executable (init "main.c" "motd.c")
19 |
--------------------------------------------------------------------------------
/src/init/motd.c:
--------------------------------------------------------------------------------
1 | /*
2 | * init/motd.c
3 | *
4 | * Copyright (c) 2025 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | int print_motd()
14 | {
15 | struct stat st = {};
16 | if (stat("/etc/motd", &st) != 0)
17 | {
18 | perror("stat(\"/etc/motd\")");
19 | return -1;
20 | }
21 | int motd_fd = open("/etc/motd", O_RDONLY);
22 | if (motd_fd < 0)
23 | {
24 | perror("open(\"/etc/motd\", O_RDONLY)");
25 | return -1;
26 | }
27 | void* motd = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, motd_fd, 0);
28 | write(STDOUT_FILENO, motd, st.st_size);
29 | write(STDOUT_FILENO, "\n", 1);
30 | close(motd_fd);
31 | munmap(motd, st.st_size);
32 | }
--------------------------------------------------------------------------------
/src/init/x86_64-syscall.S:
--------------------------------------------------------------------------------
1 | // This helper library allows one to use syscalln(...) in a user-program, since obos'
2 | // sysdep marks it as hidden
3 |
4 | .intel_syntax noprefix
5 |
6 | .global syscall
7 |
8 | syscall:
9 | push rbp
10 | mov rbp, rsp
11 |
12 | mov eax, edi
13 | mov rdi, rsi
14 | mov rsi, rdx
15 | mov rdx, rcx
16 |
17 | syscall
18 |
19 | leave
20 | ret
21 |
22 | .att_syntax prefix
--------------------------------------------------------------------------------
/src/isogen/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # isogen/CMakeLists.txt
2 |
3 | # Copyright (c) 2024 Omar Berrow
4 |
5 | set (ISODIR ${CMAKE_SOURCE_DIR}/out/isodir/)
6 |
7 | if (OBOS_ARCHITECTURE STREQUAL "m68k")
8 | return()
9 | endif()
10 |
11 | if (NOT EXISTS ${ISODIR})
12 | file (MAKE_DIRECTORY ${ISODIR})
13 | endif()
14 | if (NOT EXISTS ${ISODIR}/obos)
15 | file (MAKE_DIRECTORY ${ISODIR}/obos)
16 | endif()
17 | if (NOT EXISTS ${CMAKE_SOURCE_DIR}/config/hyper.cfg)
18 | message(FATAL_ERROR "No hyper configuration file detected!")
19 | endif()
20 |
21 | if (CMAKE_HOST_WIN32)
22 | set(SUPPRESS_OUTPUT > NUL 2>&1)
23 | elseif(CMAKE_HOST_LINUX)
24 | set(SUPPRESS_OUTPUT > /dev/null 2>&1)
25 | endif()
26 |
27 | add_custom_target(isogen ALL
28 | COMMAND ${OBJCOPY} -g ${OUTPUT_DIR}/oboskrnl ${ISODIR}/obos/oboskrnl ${SUPPRESS_OUTPUT}
29 | COMMAND cmake -E copy ${CMAKE_SOURCE_DIR}/config/hyper.cfg ${ISODIR}/ ${SUPPRESS_OUTPUT}
30 | COMMAND cmake -E copy ${CMAKE_SOURCE_DIR}/dependencies/hyper/hyper_iso_boot ${ISODIR} ${SUPPRESS_OUTPUT}
31 | COMMAND cmake -E copy ${CMAKE_SOURCE_DIR}/config/hyper_uefi_boot.bin ${ISODIR} ${SUPPRESS_OUTPUT}
32 | COMMAND cmake -E copy ${CMAKE_SOURCE_DIR}/out/initrd ${ISODIR}/obos ${SUPPRESS_OUTPUT}
33 | COMMAND cmake -E copy ${CMAKE_SOURCE_DIR}/config/initrd.tar ${ISODIR}/obos ${SUPPRESS_OUTPUT}
34 | COMMAND xorriso -as mkisofs -b hyper_iso_boot -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot hyper_uefi_boot.bin -efi-boot-part --efi-boot-image --protective-msdos-label out/isodir -o ${OUTPUT_DIR}/obos.iso ${SUPPRESS_OUTPUT}
35 | COMMAND chmod +x ${hyper_install}
36 | COMMAND ${hyper_install} ${OUTPUT_DIR}/obos.iso ${SUPPRESS_OUTPUT}
37 | SOURCES ${CMAKE_SOURCE_DIR}/config/hyper.cfg ${CMAKE_SOURCE_DIR}/config/hyper_uefi_boot.bin ${CMAKE_SOURCE_DIR}/dependencies/hyper/hyper_iso_boot ${CMAKE_SOURCE_DIR}/config/initrd.tar
38 | BYPRODUCTS ${ISODIR}/hyper.cfg
39 | BYPRODUCTS ${ISODIR}/EFI/BOOT/BOOTX64.efi
40 | BYPRODUCTS ${ISODIR}/hyper_iso_boot
41 | BYPRODUCTS ${ISODIR}/obos/oboskrnl
42 | BYPRODUCTS ${ISODIR}/obos/initrd
43 | BYPRODUCTS ${ISODIR}/obos/initrd.tar
44 | BYPRODUCTS ${OUTPUT_DIR}/obos.iso
45 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
46 | COMMENT "Generating ${OUTPUT_DIR}/obos.iso"
47 | )
48 | add_dependencies(isogen oboskrnl)
49 | if (EXISTS initrd)
50 | add_dependencies(isogen initrd)
51 | endif()
52 |
--------------------------------------------------------------------------------
/src/oboskrnl/allocators/basic_allocator.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/allocators/basic_allocator.c
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include
15 |
16 | #define MEMBLOCK_MAGIC 0x6AB450AA
17 | #define PAGEBLOCK_MAGIC 0x768AADFC
18 | #define MEMBLOCK_DEAD 0x3D793CCD
19 | #define OBOS_BASIC_ALLOCATOR_MAGIC (0x7E046A92E7735)
20 |
21 | #define OBOS_NODE_ADDR(n) ((void*)(n + 1))
22 |
23 | enum blockSource
24 | {
25 | BLOCK_SOURCE_INVALID = -1, // It is an error to get this.
26 | BLOCK_SOURCE_PHYSICAL_MEMORY, // See allocateBlock "if ((allocator_info*)This == Mm_Allocator)"
27 | BLOCK_SOURCE_BASICMM, // OBOS_BasicMMAllocatePages
28 | BLOCK_SOURCE_VMA, // Mm_AllocateVirtualMemory
29 | };
30 |
31 | typedef struct freelist_node {
32 | struct freelist_node *next, *prev;
33 | } freelist_node;
34 |
35 | _Static_assert(sizeof(freelist_node) <= 16, "Internal bug, report this.");
36 |
37 | typedef struct freelist {
38 | freelist_node *head, *tail;
39 | size_t nNodes;
40 | } freelist;
41 |
42 | enum {
43 | REGION_MAGIC = 0xb49ad907c56c8
44 | };
45 |
46 | typedef struct cache {
47 | freelist free;
48 | spinlock lock;
49 | } cache;
50 |
51 | typedef struct basic_allocator
52 | {
53 | allocator_info header;
54 | cache caches[28];
55 | enum blockSource blkSource;
56 | } basic_allocator;
57 |
58 | obos_status OBOSH_ConstructBasicAllocator(basic_allocator* This);
59 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/asm_helpers.S:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/m68k/asm_helpers.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | .cpu 68040
8 |
9 | // void setSR(uint32_t to);
10 | // uint32_t getSR();
11 | .global setSR
12 | .global getSR
13 | .global pflush
14 | setSR:
15 | move.l (+4,%a7), %d0
16 | move.w %d0, %sr
17 | rts
18 | getSR:
19 | move.w %sr, %d0
20 | rts
21 | pflush:
22 | move.l (4, %sp), %a0
23 | pflush %a0
24 | rts
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/asm_helpers.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/m68k/asm_helpers.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | void setSR(uint16_t to);
12 | uint16_t getSR();
13 | void pflush(uintptr_t virt);
14 | // Calls the interrupt vector at 'vector'
15 | void Arch_SimulateIRQ(uint8_t vector);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/boot_info.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/m68k/boot_info.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 |
10 | typedef enum BootInfoType
11 | {
12 | BootInfoType_Last = 0,
13 | BootInfoType_MachType = 1,
14 | BootInfoType_CpuType = 2,
15 | BootInfoType_FpuType = 3,
16 | BootInfoType_MmuType = 4,
17 | BootInfoType_MemChunk = 5,
18 | BootInfoType_InitRd = 6,
19 | BootInfoType_CommandLine = 7,
20 | BootInfoType_RngSeed = 8,
21 |
22 | BootInfoType_QemuVersion = 0x8000,
23 | BootInfoType_GoldfishPicBase = 0x8001,
24 | BootInfoType_GoldfishRtcBase = 0x8002,
25 | BootInfoType_GoldfishTtyBase = 0x8003,
26 | BootInfoType_VirtioBase = 0x8004,
27 | BootInfoType_ControlBase = 0x8005
28 | } BootInfoType;
29 |
30 | typedef struct BootDeviceBase
31 | {
32 | uint32_t base;
33 | uint32_t irq;
34 | } BootDeviceBase;
35 | typedef struct BootInfoTag
36 | {
37 | uint16_t type;
38 | uint16_t size;
39 | } OBOS_PACK BootInfoTag;
40 |
41 | OBOS_EXPORT BootInfoTag* Arch_GetBootInfo(BootInfoType type);
42 | OBOS_EXPORT BootInfoTag* Arch_GetBootInfoFrom(BootInfoType type, BootInfoTag* tag);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/cpu_local_arch.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/m68k/cpu_local_arch.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | // deferred irq
12 | typedef struct m68k_dirq
13 | {
14 | struct m68k_dirq *next, *prev;
15 | size_t nDefers;
16 | // Is called after the defer happens
17 | void(*on_defer_callback)(void* udata); // used by the PIC code.
18 | void* udata;
19 | uint8_t irql;
20 | } m68k_dirq;
21 | typedef struct m68k_dirq_list
22 | {
23 | m68k_dirq *head, *tail;
24 | size_t nNodes;
25 | } m68k_dirq_list;
26 | typedef struct cpu_local_arch
27 | {
28 | m68k_dirq irqs[256];
29 | m68k_dirq_list deferred;
30 | } cpu_local_arch;
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/exception_handlers.c:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/m68k/exception_handlers.c
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #include
12 | #include
13 |
14 | #include
15 |
16 | #include
17 |
18 | // well technically it's an access fault but whatever
19 | void Arch_PageFaultHandler(interrupt_frame* frame)
20 | {
21 | uint32_t mm_ec = 0;
22 | if (frame->format_7.ssw.atc)
23 | mm_ec &= ~PF_EC_PRESENT;
24 | if (!frame->format_7.ssw.rw)
25 | mm_ec |= PF_EC_RW;
26 | if (!(frame->sr & (1<<13) /* Supervisor */))
27 | mm_ec |= PF_EC_UM;
28 | if (Mm_IsInitialized())
29 | {
30 | mm_ec &= ~PF_EC_PRESENT;
31 | page_info curr = {};
32 | context* ctx = CoreS_GetCPULocalPtr()->currentContext;
33 | MmS_QueryPageInfo(ctx->pt, frame->format_7.fa & ~0xfff, &curr, nullptr);
34 | if (curr.prot.present)
35 | mm_ec |= PF_EC_PRESENT;
36 | obos_status status = Mm_HandlePageFault(ctx, frame->format_7.fa & ~0xfff, mm_ec);
37 | switch (status)
38 | {
39 | case OBOS_STATUS_SUCCESS:
40 | return;
41 | case OBOS_STATUS_UNHANDLED:
42 | break;
43 | default:
44 | {
45 | static const char format[] = "Handling page fault with error code 0x%x on address %p failed.\n";
46 | OBOS_Warning(format, mm_ec, frame->format_7.fa);
47 | break;
48 | }
49 | }
50 | }
51 | OBOS_Panic(OBOS_PANIC_EXCEPTION,
52 | "Access fault in %s-mode at 0x%p while trying to %s the %spresent page at 0x%p.\nRegister dump:\n"
53 | "d0: 0x%p, d1: 0x%p, d2: 0x%p, d3: 0x%p\n"
54 | "d1: 0x%p, d5: 0x%p, d6: 0x%p, d7: 0x%p\n"
55 | "a0: 0x%p, a1: 0x%p, a2: 0x%p, a3: 0x%p\n"
56 | "a4: 0x%p, a5: 0x%p, a6: 0x%p, sp: 0x%p\n"
57 | "pc: 0x%p, sr: 0x%p\n",
58 | (mm_ec & PF_EC_UM) ? "user" : "kernel",
59 | frame->pc,
60 | (mm_ec & PF_EC_RW) ? "write" : "read",
61 | (mm_ec & PF_EC_PRESENT) ? "" : "non-",
62 | frame->format_7.fa,
63 | frame->d0, frame->d1, frame->d2, frame->d3,
64 | frame->d4, frame->d5, frame->d6, frame->d7,
65 | frame->a0, frame->a1, frame->a2, frame->a3,
66 | frame->a4, frame->a5, frame->a6, frame->usp,
67 | frame->pc, frame->sr
68 | );
69 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/goldfish_pic.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/m68k/goldfish_pic.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | typedef struct pic_irq {
14 | uint8_t vector;
15 | bool masked;
16 | } pic_irq;
17 | typedef struct pic
18 | {
19 | uintptr_t base;
20 | uintptr_t phys_base;
21 | pic_irq irqs[32];
22 | } pic;
23 | extern pic* Arch_PICBases;
24 | extern size_t Arch_PICCount;
25 | void Arch_PICClearPending(pic* on);
26 | void Arch_PICDisable(pic*, uint32_t line);
27 | void Arch_PICEnable(pic*, uint32_t line);
28 | uint8_t Arch_PICGetPendingCount(pic*);
29 | uint32_t Arch_PICGetPending(pic*);
30 | void Arch_PICRegisterIRQ(uint32_t line, uint8_t irq);
31 | void Arch_PICMaskIRQ(uint32_t line, bool mask);
32 | void Arch_PICHandleIRQ(interrupt_frame*);
33 | void Arch_PICHandleSpurious(interrupt_frame*);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/interrupt_frame.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/m68k/interrupt_frame.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | struct OBOS_PACK ssw_68040 {
13 | uint16_t cp : 1;
14 | uint16_t cu : 1;
15 | uint16_t ct : 1;
16 | uint16_t cm : 1;
17 | uint16_t ma : 1;
18 | uint16_t atc : 1;
19 | uint16_t lk : 1;
20 | uint16_t rw : 1;
21 | uint16_t x : 1;
22 | uint16_t size : 2;
23 | uint16_t tt : 2;
24 | uint16_t tm : 3;
25 | };
26 | typedef struct interrupt_frame
27 | {
28 | uint32_t intNumber;
29 | uint32_t vector; // intNumber-64
30 | uintptr_t usp;
31 | uintptr_t d0,d1,d2,d3,d4,d5,d6,d7;
32 | uintptr_t a0,a1,a2,a3,a4,a5,a6;
33 | uint16_t padding;
34 | uint16_t sr;
35 | uintptr_t pc;
36 | uint16_t unused;
37 | struct format_7
38 | {
39 | // Effective address (whatever that means)
40 | uint32_t ea;
41 | struct ssw_68040 ssw;
42 | uint16_t wb3s, wb2s, wb1s;
43 | // Fault address
44 | uint32_t fa;
45 | uint32_t wb3a, wb3d, wb2a, fb2d, wb1a, wb1d;
46 | uint32_t pd1, pd2, pd3;
47 | } OBOS_PACK format_7;
48 | } OBOS_PACK interrupt_frame;
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/irq.c:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/m68k/irq.c
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include
15 | #include
16 |
17 | #include
18 | #include
19 |
20 | uint32_t vector_base[256];
21 | uintptr_t Arch_IRQHandlers[256];
22 | extern void isr_stub();
23 |
24 | void Arch_InitializeVectorTable()
25 | {
26 | for (size_t i = 0; i < 256; i++)
27 | vector_base[i] = (uintptr_t)isr_stub;
28 | asm volatile("movec.l %0, %%vbr;" : :"r"(vector_base) :);
29 | }
30 | void Arch_RawRegisterInterrupt(uint8_t vec, uintptr_t f)
31 | {
32 | Arch_IRQHandlers[vec] = f;
33 | }
34 | obos_status CoreS_RegisterIRQHandler(irq_vector_id vector, void(*handler)(interrupt_frame* frame))
35 | {
36 | obos_status s = OBOS_STATUS_SUCCESS;
37 | if ((s = CoreS_IsIRQVectorInUse(vector)) && handler)
38 | return s;
39 | if ((uintptr_t)handler < OBOS_KERNEL_ADDRESS_SPACE_BASE && handler)
40 | return OBOS_STATUS_INVALID_ARGUMENT;
41 | Arch_IRQHandlers[vector + 0x40] = (uintptr_t)handler;
42 | return OBOS_STATUS_SUCCESS;
43 | }
44 | OBOS_PAGEABLE_FUNCTION obos_status CoreS_IsIRQVectorInUse(irq_vector_id vector)
45 | {
46 | if (vector > OBOS_MAX_INTERRUPT_VECTORS)
47 | return OBOS_STATUS_INVALID_ARGUMENT;
48 | return Arch_IRQHandlers[vector+0x40] ? OBOS_STATUS_IN_USE : OBOS_STATUS_SUCCESS;
49 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/isr.S:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/m68k/isr.S
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | .global isr_stub
8 | .global Arch_SimulateIRQ
9 | .extern Arch_IrqHandlers
10 |
11 | isr_stub:
12 | .cfi_startproc simple
13 | .cfi_signal_frame
14 |
15 | // Disable IRQs
16 | or #0x700, %sr
17 |
18 | // Align the stack
19 | move.w #0, -(%sp)
20 |
21 | .cfi_def_cfa %sp, 0
22 | .cfi_offset %pc, 4
23 |
24 | // Push the GPRs d0-d7 and a0-a6.
25 | // Functionally equivalent to a pushad on x86
26 | movem.l %d0-%d7/%a0-%a6, %sp@-
27 | .cfi_adjust_cfa_offset 60
28 |
29 | // Push the user stack pointer
30 | move.l %usp, %a0
31 | move.l %a0, %sp@-
32 | .cfi_adjust_cfa_offset 4
33 |
34 | // Push 'vector'
35 | move.l #0, %d0
36 | move.l #0, %d1
37 | move.w (0x48,%sp), %d0
38 | and #0xfff, %d0
39 | divu #4, %d0
40 | move.w %d0, %d1
41 | sub.l #64, %d1
42 | move.l %d1, -(%sp)
43 | move.l %d0, -(%sp)
44 | .cfi_adjust_cfa_offset 8
45 |
46 | // Call the handler
47 | mulu #4, %d0
48 | move.l (%d0,Arch_IRQHandlers), %a0
49 |
50 | move.l %sp, -(%sp)
51 | .cfi_adjust_cfa_offset 4
52 |
53 | cmp #0, %a0
54 | beq .L1
55 |
56 | jsr (%a0)
57 |
58 | .L1:
59 | // Restore GPRs
60 |
61 | add #12, %sp
62 | .cfi_adjust_cfa_offset -12
63 |
64 | move.l %sp@+, %a0
65 | move.l %a0, %usp
66 | .cfi_adjust_cfa_offset -4
67 |
68 | movem.l %sp@+, %d0-%d7/%a0-%a6
69 | .cfi_adjust_cfa_offset -60
70 |
71 | add #2, %sp
72 |
73 | rte
74 | .cfi_endproc
75 | // Simulates an incoming IRQ on the vector passed.
76 | Arch_SimulateIRQ:
77 | // d0: Contains the VBR.
78 | // d1: Contains the vector.
79 | // a0: Contains the vector handler.
80 | move.l (4,%sp), %d1
81 | movec.l %vbr, %d0
82 | mulu #4, %d1
83 | move.l %d1, %a0
84 | move.w %d1, %sp@-
85 | move.l #ret, %sp@-
86 | move.w %sr, %sp@-
87 | adda.l %d0, %a0
88 | move.l (%a0), %a0
89 | jmp (%a0)
90 | ret:
91 | rts
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/loader/Allocator.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | extern "C"
6 | {
7 | void* malloc(size_t length);
8 | void free(void* ptr, size_t length);
9 | }
10 |
11 | namespace sl
12 | {
13 | struct DefaultAllocator
14 | {
15 | constexpr DefaultAllocator()
16 | {}
17 |
18 | [[nodiscard]]
19 | inline void* Allocate(size_t length)
20 | {
21 | return malloc(length);
22 | }
23 |
24 | inline void Deallocate(void* ptr, size_t length)
25 | {
26 | free(ptr, length);
27 | }
28 | };
29 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/loader/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # oboskrnl/arch/m68k/loader/CMakeLists.txt
2 | #
3 | # Copyright (c) 2024 Omar Berrow
4 |
5 | # CMake file for the m68k loader "borrowed" from northport
6 |
7 | add_executable(m68k_bootloader)
8 |
9 | target_sources(m68k_bootloader PRIVATE
10 | "Entry.S" "Main.cpp" "Loader.cpp" "Memory.cpp"
11 | "Syslib.cpp" "Util.cpp")
12 |
13 | add_dependencies(m68k_bootloader oboskrnl)
14 |
15 | set_source_files_properties(
16 | "Loader.cpp"
17 | PROPERTIES
18 | OBJECT_DEPENDS "${OUTPUT_DIR}/oboskrnl"
19 | )
20 |
21 | target_compile_options(m68k_bootloader
22 | PRIVATE "-w"
23 | PRIVATE "-fstack-protector-strong"
24 | PRIVATE "-ffreestanding"
25 | PRIVATE "-std=c++17"
26 | PRIVATE "-fno-rtti"
27 | PRIVATE "-fno-exceptions"
28 | PRIVATE "-fno-unwind-tables"
29 | PRIVATE "-fno-asynchronous-unwind-tables"
30 | PRIVATE "-g"
31 | PRIVATE "-m68040"
32 | )
33 | target_link_options(m68k_bootloader
34 | PRIVATE "-nostdlib"
35 | PRIVATE "-static"
36 | PRIVATE "-T" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/Linker.lds"
37 | )
38 | target_compile_definitions(m68k_bootloader
39 | PRIVATE NPL_ENABLE_LOGGING=1
40 | )
41 |
42 | target_include_directories(m68k_bootloader PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/loader/Elf.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #if __SIZEOF_POINTER__ == 8
4 | # error what are you doing? how the hell did you end up here?
5 | #elif __SIZEOF_POINTER__ == 4
6 | #include
7 |
8 | #define Elf_Addr Elf32_addr
9 | #define Elf_Off Elf32_Off
10 | #define Elf_Half Elf32_Half
11 | #define Elf_Word Elf32_Word
12 | #define Elf_Sword Elf32_Sword
13 | #define Elf_Xword Elf32_Xword
14 | #define Elf_Sxword Elf32_Sxword
15 | #define Elf_UnsignedChar Elf32_UnsignedChar
16 | #define Elf_Ehdr Elf32_Ehdr
17 | #define Elf_Shdr Elf32_Shdr
18 | #define Elf_Sym Elf32_Sym
19 | #define Elf_Rel Elf32_Rel
20 | #define Elf_Rela Elf32_Rela
21 | #define Elf_Phdr Elf32_Phdr
22 | #define Elf_Dyn Elf32_Dyn
23 |
24 | #define ELF_ST_BIND ELF32_ST_BIND
25 | #define ELF_ST_TYPE ELF32_ST_TYPE
26 | #define ELF_ST_INFO ELF32_ST_INFO
27 | #define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY
28 | #define ELF_R_TYPE ELF32_R_TYPE
29 | #define ELF_R_SYM ELF32_R_SYM
30 | #define ELF_R_INFO ELF32_R_INFO
31 | #else
32 | #error "Unsupported ELF spec"
33 | #endif
34 | #include
35 |
36 | namespace sl
37 | {
38 | bool ValidateElfHeader(const void* file, Elf_Half type);
39 |
40 | struct ComputedReloc
41 | {
42 | uintptr_t value;
43 | size_t length;
44 | bool usedSymbol;
45 | };
46 |
47 | ComputedReloc ComputeRelocation(Elf_Word type, uintptr_t a, uintptr_t b, uintptr_t s, uintptr_t p);
48 |
49 | sl::Vector FindPhdrs(const Elf_Ehdr* hdr, Elf_Word type);
50 | const Elf_Shdr* FindShdr(const Elf_Ehdr* hdr, const char* name);
51 | sl::Vector FindShdrs(const Elf_Ehdr* hdr, Elf_Word type);
52 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/loader/Entry.S:
--------------------------------------------------------------------------------
1 | .global LoaderEntry
2 | .global LoaderExit
3 |
4 | .extern LoaderEntryNext
5 |
6 | LoaderEntry:
7 | lea StackTop, %a7
8 | jmp LoaderEntryNext
9 |
10 | # void LoaderExit(uintptr_t hhdmbase, uintptr_t jumpTarget)
11 | LoaderExit:
12 | move.l 8(%a7), %a0
13 |
14 | lea StackTop, %a1
15 | add.l 4(%a7), %a1
16 | exg %a1, %a7
17 |
18 | move.l #0, -(%a7)
19 | move.l #0, -(%a7)
20 | jmp (%a0)
21 |
22 | .section .bss
23 | .align 16
24 | StackBase:
25 | .zero 0x4000
26 | StackTop:
27 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/loader/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Dean T.
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.
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/loader/Linker.lds:
--------------------------------------------------------------------------------
1 | OUTPUT_FORMAT(elf32-m68k)
2 |
3 | ENTRY(LoaderEntry)
4 |
5 | PHDRS
6 | {
7 | text PT_LOAD FLAGS((1 << 0) | (1 << 2));
8 | rodata PT_LOAD FLAGS((1 << 2));
9 | data PT_LOAD FLAGS((1 << 1) | (1 << 2));
10 | }
11 |
12 | SECTIONS
13 | {
14 | . = 0x1000;
15 |
16 | LOADER_BLOB_BEGIN = .;
17 | .text :
18 | {
19 | *(.text)
20 | *(.text.*)
21 | } :text
22 |
23 | . += CONSTANT(MAXPAGESIZE);
24 |
25 | .rodata :
26 | {
27 | *(.rodata)
28 | *(.rodata.*)
29 | } :rodata
30 |
31 | . += CONSTANT(MAXPAGESIZE);
32 |
33 | .data :
34 | {
35 | *(.data)
36 | *(.data.*)
37 | } :data
38 |
39 | .bss :
40 | {
41 | *(COMMON)
42 | *(.bss)
43 | } :data
44 |
45 | /DISCARD/ :
46 | {
47 | *(.note)
48 | *(.note.*)
49 | }
50 | LOADER_BLOB_END = .;
51 | }
52 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/loader/Loader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | namespace Npl
7 | {
8 | bool LoadKernel();
9 | void ExecuteKernel();
10 | void GetKernelBases(uint64_t* phys, uint64_t* virt);
11 |
12 | struct LbpRequest
13 | {
14 | uint64_t id[4];
15 | uint64_t revision;
16 | union
17 | {
18 | uint64_t pad;
19 | void* response;
20 | };
21 | };
22 |
23 | LbpRequest* LbpNextRequest(LbpRequest* current = nullptr);
24 | }
25 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/loader/Memory.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | namespace Npl
7 | {
8 | constexpr uintptr_t DontCare = 0;
9 | constexpr uintptr_t HhdmBase = 0x8000'0000;
10 |
11 | enum class MemoryType
12 | {
13 | Usable,
14 | Reclaimable,
15 | KernelModules,
16 | };
17 |
18 | void InitMemoryManager();
19 | void EnableMmu();
20 | size_t HhdmLimit();
21 | size_t GenerateLbpMemoryMap(void* store, size_t count);
22 |
23 | uintptr_t AllocPages(size_t count, MemoryType type = MemoryType::Reclaimable);
24 | void* AllocGeneral(size_t size);
25 | void* MapMemory(size_t length, uintptr_t vaddr, uintptr_t paddr = DontCare);
26 | uintptr_t GetMap(uintptr_t vaddr);
27 | }
28 |
29 | // NOTE(oberrow):
30 | // Taken from https://github.com/DeanoBurrito/northport/blob/730f3c531f6190c238801f1abe180c1e0c8c61de/libs/np-syslib/include/Memory.h
31 | namespace sl
32 | {
33 | template
34 | void memsetT(void* const start, T value, size_t valueCount)
35 | {
36 | T* const si = reinterpret_cast(start);
37 |
38 | for (size_t i = 0; i < valueCount; i++)
39 | si[i] = value;
40 | }
41 |
42 | void* memset(void* const start, uint8_t val, size_t count);
43 |
44 | void* memcopy(const void* const source, void* const destination, size_t count);
45 | void* memcopy(const void* const source, size_t sourceOffset, void* const destination, size_t destOffset, size_t count);
46 |
47 | int memcmp(const void* const a, const void* const b, size_t count);
48 | int memcmp(const void* const a, size_t offsetA, const void* const b, size_t offsetB, size_t count);
49 |
50 | size_t memfirst(const void* const buff, uint8_t target, size_t upperLimit);
51 | size_t memfirst(const void* const buff, size_t offset, uint8_t target, size_t upperLimit);
52 | }
53 |
54 | //These MUST be provided by the program, we'll forward declare them here to make them available.
55 | extern "C"
56 | {
57 | void* malloc(size_t length);
58 | void free(void* ptr, size_t length);
59 |
60 | //clang requires these to exist for __builtin_xyz, while GCC provides its own.
61 | void* memcpy(void* dest, const void* src, size_t len);
62 | void* memset(void* dest, int value, size_t len);
63 | void* memmove(void* dest, const void* src, size_t len);
64 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/loader/Util.cpp:
--------------------------------------------------------------------------------
1 | #include "Util.h"
2 | #include
3 |
4 | #ifdef NPL_ENABLE_LOGGING
5 | #define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1
6 | #define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 1
7 | #define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 0
8 | #define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 0
9 | #define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 0
10 | #define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0
11 |
12 | #define NANOPRINTF_IMPLEMENTATION
13 | #include
14 | #endif
15 |
16 | namespace Npl
17 | {
18 | void Panic(PanicReason r)
19 | {
20 | NPL_LOG("LOADER PANIC: %u", (unsigned)r);
21 | asm("clr %d1; add #0xDEAD, %d1");
22 | asm("clr %d2; add #0xDEAD, %d2");
23 | asm("clr %d3; add #0xDEAD, %d3");
24 | while (true)
25 | asm("stop #0x2700");
26 | __builtin_unreachable();
27 | }
28 |
29 | sl::CNativePtr FindBootInfoTag(BootInfoType type, sl::CNativePtr begin)
30 | {
31 | constexpr size_t ReasonableSearchCount = 50;
32 |
33 | if (begin.ptr == nullptr)
34 | begin = sl::AlignUp((uintptr_t)LOADER_BLOB_END, 2);
35 |
36 | for (size_t i = 0; i < ReasonableSearchCount; i++)
37 | {
38 | auto tag = begin.As();
39 | if (tag->type == BootInfoType::Last)
40 | return nullptr;
41 | if (tag->type == type)
42 | return begin;
43 | begin = begin.Offset(tag->size);
44 | }
45 |
46 | return nullptr;
47 | }
48 |
49 | #ifdef NPL_ENABLE_LOGGING
50 | sl::NativePtr uart = nullptr;
51 |
52 | void UartWrite(int c, void* ignored)
53 | {
54 | (void)ignored;
55 | if (uart.ptr != nullptr)
56 | uart.Write(c); //registers are 32-bits wide
57 | }
58 | #endif
59 | }
60 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/loader/Util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "NativePtr.h"
4 | #include
5 |
6 | extern "C"
7 | {
8 | extern char LOADER_BLOB_BEGIN[];
9 | extern char LOADER_BLOB_END[];
10 | extern char KERNEL_BLOB_BEGIN[];
11 | extern char KERNEL_BLOB_END[];
12 | }
13 |
14 | namespace Npl
15 | {
16 | constexpr size_t PageSize = 0x1000;
17 |
18 | enum class PanicReason
19 | {
20 | KernelReturned = 1,
21 | InternalAllocFailure = 2,
22 | LoadAllocFailure = 3,
23 | StackCheckFail = 4,
24 | HhdmSetupFail = 5,
25 | BadLbpRevision = 6,
26 | DeleteCalled = 7,
27 | };
28 |
29 | enum class BootInfoType : uint16_t
30 | {
31 | Last = 0,
32 | MachType = 1,
33 | CpuType = 2,
34 | FpuType = 3,
35 | MmuType = 4,
36 | MemChunk = 5,
37 | InitRd = 6,
38 | CommandLine = 7,
39 | RngSeed = 8,
40 |
41 | QemuVersion = 0x8000,
42 | GoldfishPicBase = 0x8001,
43 | GoldfishRtcBase = 0x8002,
44 | GoldfishTtyBase = 0x8003,
45 | VirtioBase = 0x8004,
46 | ControlBase = 0x8005
47 | };
48 |
49 | struct [[gnu::packed]] BootInfoTag
50 | {
51 | BootInfoType type;
52 | uint16_t size;
53 | };
54 |
55 | struct [[gnu::packed]] BootInfoMemChunk
56 | {
57 | uint32_t addr;
58 | uint32_t size;
59 | };
60 |
61 | void Panic(PanicReason reason);
62 | sl::CNativePtr FindBootInfoTag(BootInfoType type, sl::CNativePtr begin = nullptr);
63 |
64 | #ifdef NPL_ENABLE_LOGGING
65 | extern sl::NativePtr uart;
66 |
67 | void UartWrite(int c, void* ignored);
68 |
69 | #define NPL_LOG(...) npf_pprintf(UartWrite, nullptr, __VA_ARGS__)
70 | #else
71 | #define NPL_LOG(msg, ...) do {} while(false)
72 | #endif
73 | }
74 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/pmm.c:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/pmm.c
3 |
4 | Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include
15 | #include
16 |
17 | extern volatile struct limine_memmap_request Arch_MemmapRequest;
18 | extern volatile struct limine_hhdm_request Arch_HHDMRequest;
19 | extern volatile struct limine_memmap_request Arch_MemmapRequest;
20 | extern volatile struct limine_hhdm_request Arch_HHDMRequest;
21 | obos_pmem_map_entry* MmS_GetFirstPMemMapEntry(uintptr_t* index)
22 | {
23 | *index = 0;
24 | return Arch_MemmapRequest.response->entries[0];
25 | }
26 | // returns nullptr at the end of the list.
27 | obos_pmem_map_entry* MmS_GetNextPMemMapEntry(obos_pmem_map_entry* current, uintptr_t* index)
28 | {
29 | OBOS_UNUSED(current);
30 | size_t nEntries = (Arch_MemmapRequest.response->entry_count);
31 | if (!nEntries)
32 | OBOS_Panic(OBOS_PANIC_FATAL_ERROR, "No memory map entries.\n");
33 | if ((*index) > nEntries)
34 | return nullptr;
35 | return Arch_MemmapRequest.response->entries[++(*index)];
36 | }
37 | #define MAP_TO_HHDM(addr, type) ((type*)((uintptr_t)Arch_HHDMRequest.response->offset + (uintptr_t)(addr)))
38 | #define UNMAP_FROM_HHDM(addr) ((uintptr_t)(addr) - (uintptr_t)Arch_HHDMRequest.response->offset)
39 |
40 | OBOS_NO_UBSAN OBOS_NO_KASAN void* Arch_MapToHHDM(uintptr_t phys)
41 | {
42 | return MAP_TO_HHDM(phys, void);
43 | }
44 | OBOS_NO_UBSAN OBOS_NO_KASAN uintptr_t Arch_UnmapFromHHDM(void* virt)
45 | {
46 | return UNMAP_FROM_HHDM(virt);
47 | }
48 | void* MmS_MapVirtFromPhys(uintptr_t addr)
49 | {
50 | return Arch_MapToHHDM(addr);
51 | }
52 | uintptr_t MmS_UnmapVirtFromPhys(void* virt)
53 | {
54 | return Arch_UnmapFromHHDM(virt);
55 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/pmm.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/pmm.h
3 |
4 | Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | typedef struct limine_memmap_entry obos_pmem_map_entry;
15 | #define pmem_map_base base
16 | #define pmem_map_size length
17 | #define pmem_map_type type
18 | #define PHYSICAL_MEMORY_TYPE_USABLE LIMINE_MEMMAP_USABLE
19 | #define PHYSICAL_MEMORY_TYPE_RECLAIMABLE LIMINE_MEMMAP_ACPI_RECLAIMABLE
20 | #define PHYSICAL_MEMORY_TYPE_LOADER_RECLAIMABLE LIMINE_MEMMAP_LOADER_RECLAIMABLE
21 |
22 | void* Arch_MapToHHDM(uintptr_t phys);
23 | uintptr_t Arch_UnmapFromHHDM(void* virt);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/thread_ctx.c:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/m68k/thread_ctx.c
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #include "error.h"
8 | #include
9 |
10 | #include
11 | #include
12 |
13 | // Thread context manipulation functions.
14 |
15 | void CoreS_SetThreadIRQL(thread_ctx* ctx, irql newIRQL)
16 | {
17 | ctx->irql = newIRQL;
18 | }
19 | irql CoreS_GetThreadIRQL(const thread_ctx* ctx)
20 | {
21 | return ctx->irql;
22 | }
23 | void* CoreS_GetThreadStack(const thread_ctx* ctx)
24 | {
25 | return ctx->stackBase;
26 | }
27 | size_t CoreS_GetThreadStackSize(const thread_ctx* ctx)
28 | {
29 | return ctx->stackSize;
30 | }
31 | obos_status CoreS_SetupThreadContext(thread_ctx* ctx, uintptr_t entry, uintptr_t arg1, bool makeUserMode, void* stackBase, size_t stackSize)
32 | {
33 | if (!ctx)
34 | return OBOS_STATUS_INVALID_ARGUMENT;
35 | ctx->pc = entry;
36 | if (!makeUserMode)
37 | ctx->sr |= (1<<13);
38 | ctx->sp = (uintptr_t)stackBase+stackSize;
39 | ctx->sp -= 4;
40 | *(uintptr_t*)ctx->sp = arg1;
41 | ctx->sp -= 4;
42 | *(uintptr_t*)ctx->sp = 0;
43 | ctx->stackBase = stackBase;
44 | ctx->stackSize = stackSize;
45 | return OBOS_STATUS_SUCCESS;
46 | }
47 | obos_status CoreS_FreeThreadContext(thread_ctx* ctx)
48 | {
49 | OBOS_UNUSED(ctx);
50 | return OBOS_STATUS_SUCCESS;
51 | }
52 | void CoreS_SetThreadPageTable(thread_ctx* ctx, page_table pt)
53 | {
54 | if (!pt || !ctx)
55 | return;
56 | ctx->urp = pt;
57 | }
58 |
59 | void CoreS_SetKernelStack(void* stck)
60 | {
61 | // TODO: Set kernel stack
62 | OBOS_UNUSED(stck);
63 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/m68k/thread_ctx.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/m68k/thread_ctx.asm
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include
15 |
16 | struct thread_context_info
17 | {
18 | // 0x00
19 | uintptr_t urp;
20 | // 0x04
21 | uintptr_t sp;
22 | // 0x08,0x0C,0x10,0x14,0x18,0x2C,0x30,0x34
23 | uintptr_t d0,d1,d2,d3,d4,d5,d6,d7;
24 | // 0x38,0x3C,0x40,0x44,0x48,0x4C,0x50
25 | uintptr_t a0,a1,a2,a3,a4,a5,a6;
26 | // 0x54
27 | uint16_t padding;
28 | // 0x56
29 | uint16_t sr;
30 | // 0x58
31 | uintptr_t pc;
32 | // 0x5c
33 | uint16_t unused;
34 | // 0x5e
35 | irql irql;
36 | // 0x61
37 | void* stackBase;
38 | // 0x65
39 | size_t stackSize;
40 | } OBOS_ALIGN(8);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/asm_helpers.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/asm_helpers.h
3 |
4 | Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | void outb(uint16_t port, uint8_t data);
12 | void outw(uint16_t port, uint16_t data);
13 | void outd(uint16_t port, uint32_t data);
14 | uint8_t inb(uint16_t port);
15 | uint16_t inw(uint16_t port);
16 | uint32_t ind(uint16_t port);
17 |
18 | uintptr_t getCR0();
19 | uintptr_t getCR2();
20 | uintptr_t getCR3();
21 | uintptr_t getCR4();
22 | uintptr_t getCR8();
23 | uintptr_t getEFER();
24 |
25 | uintptr_t getDR6();
26 |
27 | uint64_t rdtsc();
28 |
29 | void __cpuid__(uint64_t initialEax, uint64_t initialEcx, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx);
30 |
31 | uint64_t rdmsr(uint32_t msr);
32 | void wrmsr(uint32_t msr, uint64_t val);
33 |
34 | void pause();
35 |
36 | void invlpg(uintptr_t addr);
37 | void wbinvd();
38 |
39 | void xsave(void* region);
40 |
41 | void cli();
42 | void sti();
43 | void hlt();
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/bgdt.asm:
--------------------------------------------------------------------------------
1 | ; oboskrnl/arch/x86_64/bgdt.asm
2 |
3 | ; Copyright (c) 2024 Omar Berrow
4 |
5 | [BITS 64]
6 |
7 | section .bss
8 | Arch_InitialISTStack:
9 | resb 0x20000
10 | global Arch_InitialISTStack:data hidden
11 | section .data
12 | align 1
13 | TSS:
14 | .rsv1: dd 0
15 | .rsp0: dq 0
16 | .rsp1: dq 0
17 | .rsp2: dq 0
18 | .rsv2: dq 0
19 | .ist0: dq 0
20 | .ist1: dq 0
21 | .ist2: dq 0
22 | .ist3: dq 0
23 | .ist4: dq 0
24 | .ist5: dq 0
25 | .ist6: dq 0
26 | .ist7: dq 0
27 | .rsv3: dq 0
28 | .rsv4: dw 0
29 | .iopb: dw 103
30 | .end:
31 | TSS_Len equ TSS.end-TSS
32 | global GDT:data hidden
33 | GDT:
34 | .null: dq 0
35 | .kcode: dq 0x00af9b000000ffff
36 | .kdata: dq 0x00af93000000ffff
37 | .tss_limitLow: dw 0
38 | .tss_baseLow: dw 0
39 | .tss_baseMiddle1: db 0
40 | .tss_access: db 0x89
41 | .tss_gran: db 0x40
42 | .tss_baseMiddle2: db 0
43 | .tss_baseHigh: dd 0
44 | .tss_resv1: dd 0
45 | .end:
46 | GDTPtr:
47 | .len: dw GDT.end-GDT-1
48 | .base: dq GDT
49 | section .text
50 |
51 | global Arch_InitBootGDT:function hidden
52 |
53 | Arch_InitBootGDT:
54 | push rbp
55 | mov rbp, rsp
56 | sub rsp, 10
57 |
58 | mov rax, TSS
59 | mov word [GDT.tss_limitLow], TSS_Len
60 | mov [GDT.tss_baseLow], ax
61 | mov rdx, rax
62 | shr rdx, 16
63 | mov [GDT.tss_baseMiddle1], dl
64 | shr rdx, 8
65 | mov [GDT.tss_baseMiddle2], dl
66 | shr rdx, 8
67 | mov [GDT.tss_baseHigh], edx
68 |
69 | lea rax, [Arch_InitialISTStack+0x20000]
70 | mov [TSS.ist0], rax
71 |
72 | lgdt [GDTPtr]
73 |
74 | mov ax, 0x18
75 | ltr ax
76 |
77 | mov ax, 0x10
78 | mov ds, ax
79 | mov ss, ax
80 | mov es, ax
81 | mov fs, ax
82 | mov gs, ax
83 |
84 | leave
85 | pop rax
86 | push 0x8
87 | push rax
88 | retfq
89 | global Arch_FlushGDT:function hidden
90 | Arch_FlushGDT:
91 | push rbp
92 | mov rbp, rsp
93 |
94 | lgdt [rdi]
95 |
96 | mov ax, 0x10
97 | mov ds, ax
98 | mov ss, ax
99 | mov es, ax
100 | mov fs, ax
101 | mov gs, ax
102 |
103 | mov ax, 0x28
104 | ltr ax
105 |
106 | leave
107 | pop rax
108 | push 0x8
109 | push rax
110 | retfq
111 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/boot_info.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/boot_info.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | extern volatile struct ultra_memory_map_attribute* Arch_MemoryMap;
12 | extern volatile struct ultra_platform_info_attribute* Arch_LdrPlatformInfo;
13 | extern volatile struct ultra_kernel_info_attribute* Arch_KernelInfo;
14 | extern volatile struct ultra_module_info_attribute* Arch_KernelBinary;
15 | extern volatile struct ultra_module_info_attribute* Arch_InitialSwapBuffer;
16 | extern volatile struct ultra_framebuffer* Arch_Framebuffer;
17 | extern volatile struct ultra_boot_context* Arch_BootContext;
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/cmos.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/cmos.h
3 | *
4 | * Copyright (c) 2025 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | enum {
13 | CMOS_SELECT = 0x70,
14 | CMOS_DATA = 0x71,
15 | };
16 |
17 | // Century register should be fetched from the FADT
18 | enum {
19 | // 1-byte, range 0-60
20 | CMOS_REGISTER_SECONDS = 0x00,
21 | // 1-byte, range 0-60
22 | CMOS_REGISTER_MINUTES = 0x02,
23 | // 1-byte, range 0-23 in 24-hour mode, 0-12 in 12-hour mode
24 | CMOS_REGISTER_HOURS = 0x04,
25 | // 1-byte, range 1-7
26 | CMOS_REGISTER_WEEKDAY = 0x06,
27 | // 1-byte, range 0-31
28 | CMOS_REGISTER_DAY_OF_MONTH = 0x07,
29 | // 1-byte, range 1-12
30 | CMOS_REGISTER_MONTH = 0x08,
31 | // 1-byte, range 0-99
32 | CMOS_REGISTER_YEAR = 0x09,
33 | // 1-byte
34 | CMOS_REGISTER_STATUS_A = 0x0A,
35 | // 1-byte
36 | CMOS_REGISTER_STATUS_B = 0x0B,
37 | };
38 |
39 | enum {
40 | CMOS_SUNDAY = 1,
41 | CMOS_MONDAY,
42 | CMOS_TUESDAY,
43 | CMOS_WEDNESDAY,
44 | CMOS_THURSDAY,
45 | CMOS_FRIDAY,
46 | CMOS_SATURDAY,
47 | };
48 |
49 | typedef struct cmos_timeofday
50 | {
51 | uint8_t seconds;
52 | uint8_t minutes;
53 | uint8_t hours;
54 | uint8_t day_of_month;
55 | uint8_t month;
56 | uint16_t year;
57 | } cmos_timeofday;
58 |
59 | obos_status Arch_CMOSInitialize();
60 | obos_status Arch_CMOSGetTimeOfDay(cmos_timeofday* time);
61 |
62 | obos_status SysS_ClockGet(int clock, long *secs, long *nsecs);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/cpu_local_arch.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/cpu_local_arch.h
3 |
4 | Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | #include
14 |
15 | #include
16 |
17 | typedef struct cpu_local_arch
18 | {
19 | uint64_t gdtEntries[7];
20 | struct
21 | {
22 | uint32_t rsv1;
23 | uint64_t rsp0;
24 | uint64_t rsp1;
25 | uint64_t rsp2;
26 | uint64_t rsv2;
27 | uint64_t ist0;
28 | uint64_t ist1;
29 | uint64_t ist2;
30 | uint64_t ist3;
31 | uint64_t ist4;
32 | uint64_t ist5;
33 | uint64_t ist6;
34 | uint64_t ist7;
35 | uint64_t rsv3;
36 | uint16_t rsv4;
37 | uint16_t iopb;
38 | } OBOS_PACK tss;
39 | // Size: 0x20000 bytes, divided into the IST1 stack (offset 0 to 0x10000), and the cpu temp stack (offset 0x10000 to 0x20000)
40 | void* ist_stack;
41 | void* startup_stack; // Size: 0x4000 bytes, freed after smp initialization.
42 | bool initializedSchedulerTimer;
43 | bool pf_handler_running;
44 | gdb_ctx dbg_ctx;
45 | dpc dbg_dpc;
46 | uint64_t stack_check_guard;
47 | uint8_t lapicId;
48 | } cpu_local_arch;
49 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/entry.asm:
--------------------------------------------------------------------------------
1 | ; oboskrnl/arch/x86_64/entry.asm
2 |
3 | ; Copyright (c) 2024 Omar Berrow
4 |
5 | [BITS 64]
6 |
7 | default rel
8 |
9 | ; Bootstrap code to initialize the stack guard.
10 |
11 | extern __stack_chk_guard
12 | extern Arch_disablePIC
13 | extern Arch_KernelEntry
14 | global Arch_KernelEntryBootstrap:function hidden
15 | Arch_KernelEntryBootstrap:
16 | cmp rsi, 0x554c5442
17 | je .ok ; should triple fault on failure
18 | xor rax,rax
19 | jmp rax ; All hope is lost.
20 | .ok:
21 | push rdi
22 | push rsi
23 | ; Get a hardware-generated random value.
24 | ; If both methods are unsupported, it will fallback to using the default value used.
25 | .rdrand:
26 | mov eax, 1
27 | xor ecx,ecx
28 | cpuid
29 | bt ecx, 30
30 | jnc .rdseed
31 | rdrand rax
32 | jnc .rdrand
33 | jmp .move
34 | .rdseed:
35 | mov eax, 7
36 | xor ecx,ecx
37 | cpuid
38 | bt ebx, 18
39 | jnc .done
40 | rdseed rax
41 | jnc .rdseed
42 | .move:
43 | ; Move the (likely) random value into the stack guard variable.
44 | mov [__stack_chk_guard], rax
45 | .done:
46 | call Arch_disablePIC
47 | ; Turn on cr0.WP (write protect)
48 | mov rax, cr0
49 | or rax, (1<<16) ; WP
50 | mov cr0, rax
51 | ; Restore rdi and rsi
52 | pop rsi
53 | pop rdi
54 | ; Call into the kernel entry.
55 | push 0 ; Make sure if the kernel entry returns, it triple faults and doesn't do goofy things.
56 | jmp Arch_KernelEntry
57 | global Arch_IdleTask:function hidden
58 | section .data
59 | global Arch_MakeIdleTaskSleep:data hidden
60 | Arch_MakeIdleTaskSleep: db 0
61 | section .text
62 | Arch_IdleTask:
63 | hlt
64 | cmp byte [Arch_MakeIdleTaskSleep], 1
65 | jne Arch_IdleTask
66 | cli
67 | .slp:
68 | pause
69 | cmp byte [Arch_MakeIdleTaskSleep], 1
70 | je .slp
71 | sti
72 | jmp Arch_IdleTask
73 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdbstub/alloc.c:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/gdbstub/alloc.c
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 |
10 | #include
11 |
12 | void* Kdbg_Malloc(size_t sz)
13 | {
14 | return Allocate(OBOS_NonPagedPoolAllocator, sz, nullptr);
15 | }
16 | void* Kdbg_Calloc(size_t nObjs, size_t szObj)
17 | {
18 | return ZeroAllocate(OBOS_NonPagedPoolAllocator, nObjs, szObj, nullptr);
19 | }
20 | void* Kdbg_Realloc(void* ptr, size_t newSz)
21 | {
22 | return Reallocate(OBOS_NonPagedPoolAllocator, ptr, newSz, nullptr);
23 | }
24 | void Kdbg_Free(void* ptr)
25 | {
26 | size_t sz = 0;
27 | QueryBlockSize(OBOS_NonPagedPoolAllocator, ptr, &sz);
28 | Free(OBOS_NonPagedPoolAllocator, ptr, sz);
29 | }
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdbstub/alloc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/gdbstub/alloc.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | // All memory for the gdb stub is allocated using the non-paged pool allocator
13 |
14 | void* Kdbg_Malloc(size_t sz);
15 | void* Kdbg_Calloc(size_t nObjs, size_t szObj);
16 | void* Kdbg_Realloc(void* ptr, size_t newSz);
17 | void Kdbg_Free(void* ptr);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdbstub/bp.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/gdbstub/bp.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | // Removes a software breakpoint.
15 | obos_status Kdbg_GDB_z0(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* dbg_ctx, void* userdata);
16 | // Adds a software breakpoint.
17 | obos_status Kdbg_GDB_Z0(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* dbg_ctx, void* userdata);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdbstub/breakpoint.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/gdbstub/breakpoint.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | typedef LIST_HEAD(sw_breakpoint_list, struct sw_breakpoint) sw_breakpoint_list;
15 | LIST_PROTOTYPE(sw_breakpoint_list, struct sw_breakpoint, node);
16 |
17 | typedef struct sw_breakpoint
18 | {
19 | uintptr_t addr;
20 | uint8_t at; // the byte at addr before setting it to a breakpoint instruction
21 | LIST_NODE(sw_breakpoint_list, struct sw_breakpoint) node;
22 | } sw_breakpoint;
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdbstub/connection.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/gdbstub/connection.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 | #include
14 |
15 | #include
16 |
17 | #include
18 |
19 | typedef struct gdb_connection
20 | {
21 | // Communication context
22 | const driver_ftable* pipe_interface;
23 | dev_desc pipe;
24 | uint32_t flags;
25 | bool connection_active;
26 |
27 | // Connection context.
28 | struct
29 | {
30 | bool received_first;
31 | thread_node* last_thread;
32 | } q_ThreadInfo_ctx;
33 | // bool swbreak_supported;
34 | // bool hwbreak_supported;
35 | // bool multiprocess_supported;
36 | // bool vCont_supported;
37 | // bool errormessage_supported;
38 | // Bitfield:
39 | // bit 0: swbreak
40 | // bit 1: hwbreak
41 | // bit 2: multiprocess
42 | // bit 3: vCont
43 | // bit 4: error-message
44 | uint32_t gdb_supported;
45 | sw_breakpoint_list sw_breakpoints;
46 | } gdb_connection;
47 | typedef struct gdb_ctx
48 | {
49 | thread* interrupted_thread;
50 | thread_ctx interrupt_ctx;
51 | bool wake;
52 | } gdb_ctx;
53 | extern OBOS_EXPORT gdb_connection* Kdbg_CurrentConnection;
54 |
55 | uintptr_t KdbgH_hex2bin(const char* str, unsigned size);
56 |
57 | // Must be a pipe-style driver, or stuff will go wrong.
58 | obos_status Kdbg_ConnectionInitialize(gdb_connection* conn, const driver_ftable* pipe_interface, dev_desc pipe);
59 | obos_status Kdbg_ConnectionSendPacket(gdb_connection* conn, const char* packet);
60 | // *packet is guaranteed to be nul-terminated.
61 | obos_status Kdbg_ConnectionRecvPacket(gdb_connection* conn, char** packet, size_t* szPacket);
62 | // NOTE: Does not send the packet to change the ack status
63 | // You must do that yourself.
64 | obos_status Kdbg_ConnectionSetAck(gdb_connection* conn, bool ack);
65 |
66 | char* KdbgH_FormatResponse(const char* format, ...);
67 | // size needs to be the exact size of the output, or bad things will happen.
68 | char* KdbgH_FormatResponseSized(size_t size, const char* format, ...);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdbstub/debug.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/gdbstub/debug.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include
15 |
16 | #include
17 |
18 | extern bool Kdbg_Paused;
19 |
20 | OBOS_EXPORT void Kdbg_Break();
21 |
22 | void Kdbg_CallDebugExceptionHandler(interrupt_frame* frame, bool isSource);
23 | void Kdbg_NotifyGDB(gdb_connection* con, uint8_t signal);
24 |
25 | void Kdbg_int3_handler(interrupt_frame* frame);
26 | void Kdbg_int1_handler(interrupt_frame* frame);
27 |
28 | void Kdbg_GeneralDebugExceptionHandler(gdb_connection* conn, gdb_ctx* dbg_ctx, bool isSource);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdbstub/general_query.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/gdbstub/general_query.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | obos_status Kdbg_GDB_qC(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
15 | obos_status Kdbg_GDB_q_ThreadInfo(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
16 | obos_status Kdbg_GDB_QStartNoAckMode(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
17 | obos_status Kdbg_GDB_qSupported(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
18 | obos_status Kdbg_GDB_qAttached(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
19 | obos_status Kdbg_GDB_qRcmd(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
20 | obos_status Kdbg_GDB_vMustReplyEmpty(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdbstub/packet_dispatcher.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/gdbstub/packet_dispatcher.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | typedef obos_status(*packet_handler)(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
15 | void Kdbg_AddPacketHandler(const char* name, packet_handler handler, void* userdata);
16 | // packet must be nul-terminated
17 | // or bad stuff might happen.
18 | obos_status Kdbg_DispatchPacket(gdb_connection* con, const char* packet, size_t packetLen, gdb_ctx* ctx);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/gdbstub/stop_reply.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/gdbstub/stop_reply.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | // '?' packet
15 | // Queries the stop reason.
16 | obos_status Kdbg_GDB_query_halt(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
17 | // Read Registers
18 | obos_status Kdbg_GDB_g(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
19 | // Write Registers
20 | obos_status Kdbg_GDB_G(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
21 | // Kill the kernel (shutdown)
22 | obos_status Kdbg_GDB_k(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
23 | // Detach from gdb.
24 | obos_status Kdbg_GDB_D(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
25 | // Read Memory
26 | obos_status Kdbg_GDB_m(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
27 | // Write Memory
28 | obos_status Kdbg_GDB_M(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
29 | // Queries thread status.
30 | obos_status Kdbg_GDB_T(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
31 | // Step
32 | obos_status Kdbg_GDB_s(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
33 | // Continue [at address]
34 | obos_status Kdbg_GDB_c(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
35 | obos_status Kdbg_GDB_C(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* dbg_ctx, void* userdata);
36 | // These packets: g,G,k,m,M
37 | // But multithreaded
38 | obos_status Kdbg_GDB_H(gdb_connection* con, const char* arguments, size_t argumentsLen, gdb_ctx* ctx, void* userdata);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/hpet_table.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/hpet_table.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | typedef struct OBOS_PACK HPET_Addr
15 | {
16 | uint8_t addressSpaceId;
17 | uint8_t registerBitWidth;
18 | uint8_t registerBitOffset;
19 | uint8_t resv;
20 | uintptr_t address;
21 | } HPET_Addr;
22 | typedef struct OBOS_PACK HPET_Table
23 | {
24 | ACPISDTHeader sdtHeader;
25 | uint32_t eventTimerBlockID;
26 | HPET_Addr baseAddress;
27 | uint8_t hpetNumber;
28 | uint16_t mainCounterMinimum;
29 | uint8_t pageProtectionAndOEMAttrib;
30 | } HPET_Table;
31 | typedef struct OBOS_PACK HPET_Timer
32 | {
33 | volatile uint64_t timerConfigAndCapabilities;
34 | volatile uint64_t timerComparatorValue;
35 | volatile struct
36 | {
37 | uint32_t fsbIntVal;
38 | uint32_t fsbIntAddr;
39 | } timerFSBInterruptRoute;
40 | const volatile uint64_t resv;
41 | } HPET_Timer;
42 | typedef struct OBOS_PACK HPET
43 | {
44 | volatile const struct {
45 | uint8_t revisionId;
46 | uint8_t numTimCap : 4;
47 | bool countSizeCap : 1;
48 | bool resv1 : 1;
49 | bool legRouteCap : 1;
50 | uint16_t vendorID;
51 | uint32_t counterCLKPeriod;
52 | } OBOS_PACK generalCapabilitiesAndID;
53 | volatile const uint64_t resv1;
54 | volatile uint64_t generalConfig;
55 | volatile const uint64_t resv2;
56 | volatile uint64_t generalInterruptStatus;
57 | volatile const uint64_t resv3[0x19];
58 | volatile uint64_t mainCounterValue;
59 | volatile const uint64_t resv4;
60 | volatile HPET_Timer timer0, timer1, timer2;
61 | // 0x160-0x400 are for timers 0-31
62 | } HPET;
63 | extern HPET* Arch_HPETAddress;
64 | extern uint64_t Arch_HPETFrequency;
65 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/idt.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/idt.h
3 |
4 | Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | struct idtEntry
14 | {
15 | uint16_t offset1;
16 | uint16_t selector;
17 | uint8_t ist;
18 | uint8_t typeAttributes;
19 | uint16_t offset2;
20 | uint32_t offset3;
21 | uint32_t resv1;
22 | };
23 |
24 | void Arch_InitializeIDT(bool isBSP);
25 | void Arch_RawRegisterInterrupt(uint8_t vec, uintptr_t f);
26 | void Arch_PutInterruptOnIST(uint8_t vec, uint8_t ist);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/interrupt_frame.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/interrupt_frame.h
3 |
4 | Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #define BITFIELD_FROM_BIT(n) (1<
10 |
11 | #include
12 |
13 | typedef uint8_t irq_vector_id;
14 | #define OBOS_IRQ_VECTOR_ID_MAX (224 /* 256 vectors - the 32 reserved vectors */)
15 | #define OBOS_IRQ_VECTOR_ID_TO_IRQL(x) ((irql)(((x)>>4)+2))
16 | #define OBOS_IRQL_TO_IRQ_VECTOR_ID(x) ((irq_vector_id)(((x)<<4)-0x20))
17 | #define OBOS_IRQ_VECTOR_ID_COUNT_PER_IRQL (16)
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/lapic_timer_calibration.asm:
--------------------------------------------------------------------------------
1 | ; oboskrnl/arch/x86_64/lapic_timer_calibration.asm
2 | ;
3 | ; Copyright (c) 2024 Omar Berrow
4 |
5 | [BITS 64]
6 |
7 | global Arch_FindCounter:function hidden
8 | extern Arch_LAPICAddress
9 | extern Arch_HPETAddress
10 | extern Arch_CalibrateHPET
11 |
12 | ; uint64_t Arch_FindCounter(uint64_t hz);
13 | ; (input) rdi: The expected frequency of the LAPIC count.
14 | ; (output) rax: The timer count for the LAPIC, assuming the divisor is LAPIC_TIMER_DIVISIOR_ONE (0b1101)
15 | Arch_FindCounter:
16 | push rbp
17 | mov rbp, rsp
18 | push r15
19 | push r13
20 |
21 | call Arch_CalibrateHPET
22 | mov r15, rax
23 | mov r13, [Arch_LAPICAddress]
24 | mov r11, [Arch_HPETAddress]
25 |
26 | mov r13, [Arch_LAPICAddress]
27 | mov dword [r13+0x3E0], 0xB ; DIVISOR_ONE
28 | mov dword [r13+0x380], 0xffffffff
29 |
30 | ; Start the HPET timer.
31 | mov rax, [r11+0x10]
32 | or rax, (1<<0)
33 | mov [r11+0x10], rax
34 |
35 | add r11, 0xf0
36 |
37 | .loop:
38 | mov r9, [r11]
39 | cmp r9, r15
40 | jnge .loop
41 |
42 | xor r9,r9
43 | mov r9d, [r13+0x390]
44 | mov dword [r13+0x380], 0
45 | mov rax, 0xffffffff
46 | sub rax, r9
47 |
48 | .end:
49 | pop r13
50 | pop r15
51 | leave
52 | ret
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/madt.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/irq/madt.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 |
13 | typedef struct OBOS_PACK MADTTable
14 | {
15 | ACPISDTHeader sdtHeader;
16 | uint32_t lapicAddress;
17 | uint32_t unwanted;
18 | // There are more entries.
19 | } MADTTable;
20 | typedef struct OBOS_PACK MADT_EntryHeader
21 | {
22 | uint8_t type;
23 | uint8_t length;
24 | } MADT_EntryHeader;
25 | typedef struct OBOS_PACK MADT_EntryType0
26 | {
27 | MADT_EntryHeader entryHeader;
28 | uint8_t processorID;
29 | uint8_t apicID;
30 | uint32_t flags;
31 | } MADT_EntryType0;
32 | typedef struct OBOS_PACK MADT_EntryType1
33 | {
34 | MADT_EntryHeader entryHeader;
35 | uint8_t ioApicID;
36 | uint8_t resv1;
37 | uint32_t ioapicAddress;
38 | uint32_t globalSystemInterruptBase;
39 | } MADT_EntryType1;
40 | typedef struct OBOS_PACK MADT_EntryType2
41 | {
42 | MADT_EntryHeader entryHeader;
43 | uint8_t busSource;
44 | uint8_t irqSource;
45 | uint32_t globalSystemInterrupt;
46 | uint16_t flags;
47 | } MADT_EntryType2;
48 | typedef struct OBOS_PACK MADT_EntryType3
49 | {
50 | MADT_EntryHeader entryHeader;
51 | uint8_t nmiSource;
52 | uint8_t resv;
53 | uint16_t flags;
54 | uint32_t globalSystemInterrupt;
55 | } MADT_EntryType3;
56 | typedef struct OBOS_PACK MADT_EntryType4
57 | {
58 | MADT_EntryHeader entryHeader;
59 | uint8_t processorID;
60 | uint16_t flags;
61 | uint8_t lINT;
62 | } MADT_EntryType4;
63 | typedef struct OBOS_PACK MADT_EntryType5
64 | {
65 | MADT_EntryHeader entryHeader;
66 | uint8_t resv1[2];
67 | uintptr_t lapic_address;
68 | } MADT_EntryType5;
69 | typedef struct OBOS_PACK MADT_EntryType9
70 | {
71 | MADT_EntryHeader entryHeader;
72 | uint8_t resv1[2];
73 | uint32_t x2APIC_ID;
74 | uint32_t flags;
75 | uint32_t acpiID;
76 | } MADT_EntryType9;
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/memmanip.asm:
--------------------------------------------------------------------------------
1 | ; oboskrnl/arch/x86_64/memmanip.asm
2 | ;
3 | ; Copyright (c) 2024 Omar Berrow
4 |
5 | [BITS 64]
6 |
7 | global memset:function default
8 | global memzero:function default
9 | global memcpy:function default
10 | global memcmp:function default
11 | global memcmp_b:function default
12 | global strcmp:function default
13 | global strlen:function default
14 | global strchr:function default
15 |
16 | section .text
17 |
18 | memset:
19 | push rbp
20 | mov rbp, rsp
21 |
22 | push rdi
23 | mov al, sil
24 | mov rcx, rdx
25 | rep stosb
26 | pop rax
27 |
28 | leave
29 | ret
30 | memzero:
31 | push rbp
32 | mov rbp, rsp
33 |
34 | push rdi
35 | xor eax, eax
36 | mov rcx, rsi
37 | rep stosb
38 | pop rax
39 |
40 | leave
41 | ret
42 | memcpy:
43 | push rbp
44 | mov rbp, rsp
45 |
46 | mov rax, rdi
47 | mov rcx, rdx
48 | rep movsb
49 |
50 | leave
51 | ret
52 | memcmp:
53 | push rbp
54 | mov rbp, rsp
55 |
56 | mov rcx, rdx
57 | repe cmpsb
58 | sete al
59 |
60 | leave
61 | ret
62 | memcmp_b:
63 | push rbp
64 | mov rbp, rsp
65 |
66 | mov al, sil
67 | mov rcx, rdx
68 | repe scasb
69 | sete al
70 |
71 | leave
72 | ret
73 | strcmp:
74 | push rbp
75 | mov rbp, rsp
76 | sub rsp, 0x8
77 |
78 | push rdi
79 | push rsi
80 | call strlen
81 | mov [rbp-8], rax
82 | mov rdi, rsi
83 | call strlen
84 | pop rsi
85 | pop rdi
86 | cmp rax, [rbp-8]
87 | sete al
88 | jne .end
89 |
90 | mov rdx, [rbp-8]
91 | call memcmp
92 |
93 | .end:
94 | leave
95 | ret
96 | strlen:
97 | push rbp
98 | mov rbp, rsp
99 |
100 | xor rcx, rcx
101 | not rcx
102 | xor eax,eax
103 | repne scasb
104 | sub rax, rcx
105 | sub rax, 2
106 |
107 | leave
108 | ret
109 | strchr:
110 | push rbp
111 | mov rbp, rsp
112 |
113 | push rdi
114 | call strlen
115 | pop rdi
116 | mov r8, rax
117 | cld
118 | mov rcx, rax
119 | mov rax, rsi
120 | repne scasb
121 | sub r8, rcx
122 | mov rax, r8
123 |
124 | leave
125 | ret
126 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/mtrr.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/mtrr.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | // Only to be called once on the BSP
12 | void Arch_SaveMTRRs();
13 | // Can be called on any CPU any amount of times.
14 | void Arch_RestoreMTRRs();
15 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/pmm.c:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/pmm.c
3 |
4 | Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include
15 |
16 | extern struct ultra_memory_map_attribute* Arch_MemoryMap;
17 | extern struct ultra_platform_info_attribute* Arch_LdrPlatformInfo;
18 | obos_pmem_map_entry* MmS_GetFirstPMemMapEntry(uintptr_t* index)
19 | {
20 | *index = 0;
21 | return &Arch_MemoryMap->entries[0];
22 | }
23 | // returns nullptr at the end of the list.
24 | obos_pmem_map_entry* MmS_GetNextPMemMapEntry(obos_pmem_map_entry* current, uintptr_t* index)
25 | {
26 | OBOS_UNUSED(current);
27 | size_t nEntries = (Arch_MemoryMap->header.size - sizeof(Arch_MemoryMap->header)) / sizeof(struct ultra_memory_map_entry);
28 | if (!nEntries)
29 | OBOS_Panic(OBOS_PANIC_FATAL_ERROR, "No memory map entries.\n");
30 | if ((*index) > nEntries)
31 | return nullptr;
32 | return &Arch_MemoryMap->entries[++(*index)];
33 | }
34 | #define MAP_TO_HHDM(addr, type) ((type*)(Arch_LdrPlatformInfo->higher_half_base + (uintptr_t)(addr)))
35 | #define UNMAP_FROM_HHDM(addr) ((uintptr_t)(addr) - Arch_LdrPlatformInfo->higher_half_base)
36 |
37 | OBOS_NO_KASAN OBOS_NO_UBSAN __attribute__((no_instrument_function)) void* Arch_MapToHHDM(uintptr_t phys)
38 | {
39 | return MAP_TO_HHDM(phys, void);
40 | }
41 | OBOS_NO_KASAN OBOS_NO_UBSAN __attribute__((no_instrument_function)) uintptr_t Arch_UnmapFromHHDM(void* virt)
42 | {
43 | return UNMAP_FROM_HHDM(virt);
44 | }
45 |
46 | __attribute__((no_instrument_function)) OBOS_EXPORT void* MmS_MapVirtFromPhys(uintptr_t addr)
47 | {
48 | return Arch_MapToHHDM(addr);
49 | }
50 |
51 | __attribute__((no_instrument_function)) OBOS_EXPORT uintptr_t MmS_UnmapVirtFromPhys(void* virt)
52 | {
53 | return Arch_UnmapFromHHDM(virt);
54 | }
55 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/pmm.h:
--------------------------------------------------------------------------------
1 | /*
2 | oboskrnl/arch/x86_64/pmm.h
3 |
4 | Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | typedef struct ultra_memory_map_entry obos_pmem_map_entry;
15 | #define pmem_map_base physical_address
16 | #define pmem_map_size size
17 | #define pmem_map_type type
18 | #define PHYSICAL_MEMORY_TYPE_USABLE ULTRA_MEMORY_TYPE_FREE
19 | #define PHYSICAL_MEMORY_TYPE_RECLAIMABLE ULTRA_MEMORY_TYPE_RECLAIMABLE
20 | #define PHYSICAL_MEMORY_TYPE_LOADER_RECLAIMABLE ULTRA_MEMORY_TYPE_LOADER_RECLAIMABLE
21 |
22 | void* Arch_MapToHHDM(uintptr_t phys);
23 | uintptr_t Arch_UnmapFromHHDM(void* virt);
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/sdt.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/sdt.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | typedef struct OBOS_PACK ACPIRSDPHeader {
13 | char Signature[8];
14 | uint8_t Checksum;
15 | char OEMID[6];
16 | uint8_t Revision;
17 | uint32_t RsdtAddress; // Deprecated
18 |
19 | // Fields only valid if Revision != 0
20 | uint32_t Length;
21 | uint64_t XsdtAddress;
22 | uint8_t ExtendedChecksum;
23 | uint8_t reserved[3];
24 | } ACPIRSDPHeader;
25 | typedef struct OBOS_PACK ACPISDTHeader {
26 | char Signature[4];
27 | uint32_t Length;
28 | uint8_t Revision;
29 | uint8_t Checksum;
30 | char OEMID[6];
31 | char OEMTableID[8];
32 | uint32_t OEMRevision;
33 | uint32_t CreatorID;
34 | uint32_t CreatorRevision;
35 | } ACPISDTHeader;
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/sse.c:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/sse.c
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #include
8 | #include
9 |
10 | #include
11 |
12 | #include
13 |
14 | static size_t xsave_size = 512;
15 | bool Arch_HasXSAVE = false;
16 |
17 | void* Arch_AllocateXSAVERegion()
18 | {
19 | return ZeroAllocate(OBOS_NonPagedPoolAllocator, 1, xsave_size, nullptr);
20 | }
21 |
22 | void Arch_FreeXSAVERegion(void* buf)
23 | {
24 | Free(OBOS_NonPagedPoolAllocator, buf, xsave_size);
25 | }
26 |
27 | // Enables stuff such as XSAVE, SSE(2), AVX, AVX512, etc.
28 | __attribute__((target("xsave"))) void Arch_EnableSIMDFeatures()
29 | {
30 | // Enable SSE.
31 |
32 | // Clear CR0.EM, set CR0.MP
33 | asm ("mov %0, %%cr0" : :"r"(getCR0() & ~BIT(2)));
34 | asm ("mov %0, %%cr0" : :"r"(getCR0() | BIT(1)));
35 | // Set CR4.OSFXSR, CR4.OSXMMEXCPT
36 | asm ("mov %0, %%cr4" : :"r"(getCR4() | BIT(9) | BIT(10)));
37 |
38 | // Enable XSAVE, if supported
39 | uint32_t ecx = 0;
40 | __cpuid__(0x1, 0x0, nullptr, nullptr, &ecx, nullptr);
41 | if (ecx & BIT(26))
42 | {
43 | asm ("mov %0, %%cr4" : :"r"(getCR4() | BIT(18)));
44 | Arch_HasXSAVE = true;
45 | __cpuid__(0xd, 0, nullptr, nullptr, (uint32_t*)&xsave_size, nullptr);
46 | }
47 |
48 | // Enable AVX.
49 | if (ecx & BIT(28))
50 | __builtin_ia32_xsetbv(0, __builtin_ia32_xgetbv(0)|0b111);
51 |
52 | // Enable AVX512.
53 | uint32_t eax = 0;
54 | __cpuid__(0xd, 0, &eax, nullptr,nullptr,nullptr);
55 | if (eax & (0x7<<5))
56 | __builtin_ia32_xsetbv(0, __builtin_ia32_xgetbv(0) | (0x7<<5));
57 | }
58 |
59 | size_t Arch_GetXSaveRegionSize()
60 | {return xsave_size;}
61 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/sse.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/sse.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | void* Arch_AllocateXSAVERegion();
12 | void Arch_FreeXSAVERegion(void* reg);
13 | // Enables stuff such as XSAVE, SSE(2), AVX, AVX512, etc.
14 | void Arch_EnableSIMDFeatures();
15 | size_t Arch_GetXSaveRegionSize();
16 |
17 | // Set to false if the thread context code should fallback to fxsave/fxrstor,
18 | // otherwise, the thread context code can and should use xsave/xrstor
19 | extern bool Arch_HasXSAVE;
20 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/thread_ctx.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/thread_ctx.asm
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | // Don't forget to update this in the assembly code (thread_ctx.asm)
15 | struct thread_context_info
16 | {
17 | void* extended_ctx_ptr;
18 | uint8_t irql;
19 | uintptr_t cr3;
20 | uint64_t gs_base, fs_base;
21 | interrupt_frame frame;
22 | void* stackBase;
23 | size_t stackSize;
24 | void* signal_extended_ctx_ptr;
25 | } OBOS_ALIGN(8);
26 |
27 | extern void Arch_UserYield(void* kstck);
28 |
--------------------------------------------------------------------------------
/src/oboskrnl/arch/x86_64/timer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/arch/x86_64/timer.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | // NOTE: To be called at > IRQL_PASSIVE.
12 | void Arch_InitializeSchedulerTimer();
13 |
--------------------------------------------------------------------------------
/src/oboskrnl/cmdline.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/cmdline.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | extern OBOS_EXPORT const char* OBOS_KernelCmdLine;
12 | extern OBOS_EXPORT const char* volatile OBOS_InitrdBinary;
13 | extern OBOS_EXPORT size_t volatile OBOS_InitrdSize;
14 | extern OBOS_EXPORT char** OBOS_argv;
15 | extern OBOS_EXPORT size_t OBOS_argc;
16 | extern size_t OBOS_InitArgumentsStart; // if SIZE_MAX, assume it doesn't exist
17 | extern size_t OBOS_InitArgumentsCount;
18 |
19 | // Parses the command line into OBOS_argv and OBOS_argc
20 | void OBOS_ParseCMDLine();
21 | // Gets the value of a string command line option.
22 | OBOS_EXPORT char* OBOS_GetOPTS(const char* opt);
23 | // Gets the value of an integer command line option.
24 | OBOS_EXPORT uint64_t OBOS_GetOPTD(const char* opt);
25 | OBOS_EXPORT uint64_t OBOS_GetOPTD_Ex(const char* opt, uint64_t default_value);
26 | // Gets the value of a flag command line option.
27 | // true if the flag was found on the command line, otherwise false.
28 | OBOS_EXPORT bool OBOS_GetOPTF(const char* opt);
29 |
--------------------------------------------------------------------------------
/src/oboskrnl/driver_interface/drv_sys.h:
--------------------------------------------------------------------------------
1 | /*
2 | * oboskrnl/driver_interface/drv_sys.h
3 | *
4 | * Copyright (c) 2024 Omar Berrow
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include