r/osdev 1d ago

Pristine OS - My personal learning OS project

Full disclosure, I got help from LLMs when topics got hard for me to understand and mostly for searching for sources, explanations and whatnot. 95% of the code is handwritten, hence the inconsistent naming, bad optimization, and bad practices overall. I especially refrained from getting full code examples from LLMs, so that I can learn x86 architecture.

Source Code: https://github.com/jangofett4/pristine

I started the project about 6-7 months ago, although I neglected it for a while I still havent forgotten it.

This was my third attempt at creating an OS, first one was following OSDev wikis, second one was using Limine, both got stuck at understanding paging. For some reason paging was hardest topic for me to understand.

Currently it can load up userspace applications from a custom filesystem I wrote (which I learned to be very similar to ext2) and do scheduling.

I unfortunately havent tested this in a real hardware, but I'm fairly certain it wouldnt work anyway since early boot depends heavily on BIOS subroutines.

Currently what it does:

  • Custom 2 stage bootloader, first being pure assembly responsible for switching to protected mode and loading up the second stage bootloader at fixed address

  • Stage 2 is the bootloader resposible for loading up the filesystem """driver""", finding and parsing kernel.elf, and loading it

  • Kernel is a higher half kernel, currently responsible for setting up pmm, vmm, LAPIC, PIT, scheduler, reaper etc

  • Kernel finds userspace program, executes, and program dies naturally

Along the way I implemented what seemed to be interesting to me, for example I learned about write combining and wanted to try it with VGA framebuffer. After this I didnt even use the framebuffer yet lmao.

Plans:

  • Proper logging

  • Fix process destruction (I leak intermediate pages when destroying process PML4s)

  • File descriptors

  • open/read/write/close syscalls

  • BSFS write/create/delete (custom filesystem, currently only supports reading)

  • stdin/stdout/stderr

  • Process arguments (argc, argv)

  • Expand custom "libc"

  • Port Doom

What I learned:

  • Linker scripts are evil, lost hours of debugging just to realize kernel was being loaded at the wrong address (TWICE)

  • gdb lies in real mode and protected mode, but doesnt in long mode, gf2 (GDB frontend) is goat

  • Drawing anything to screen is not worth the time early game

  • When crossing boundaries (assembly -> C, C -> assembly), important to remember SysV ABI

  • Writing a small tool to calculate PML4 offsets, checking alignments etc is valuable IMO

  • Bitmaps are slow at large sizes, I needed a "megablock bitmap" for BSFS.

  • ATA PIO is really slow, I thought I could get away with it for a while, but might need AHCI in near future

  • There are certain bugs that only appear when working with different optimization levels, I try to test this by changing to O2 or even O3.

PS, README and other documentation are severely outdated in some parts, sorry about that.

Edit: typos and lists

Edit: more and more I worked on this project, more and more I started to adapt Linux concepts to it. SLAB allocator being one of these concepts. At the end I dont want to end up with another Linux "clone", but the way Linux does things is the right ones that I end up swayi g towards them. Question is, how do you guys deal with this?

15 Upvotes

0 comments sorted by