<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ThatOSDeveloper</title>
    <description>The latest articles on DEV Community by ThatOSDeveloper (@thatosdeveloper).</description>
    <link>https://dev.to/thatosdeveloper</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3317965%2F56068a4b-1a1b-4af8-9f75-3df0abbd50f2.jpeg</url>
      <title>DEV Community: ThatOSDeveloper</title>
      <link>https://dev.to/thatosdeveloper</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thatosdeveloper"/>
    <language>en</language>
    <item>
      <title>ACPI, and why I hate intel for making it</title>
      <dc:creator>ThatOSDeveloper</dc:creator>
      <pubDate>Mon, 11 Aug 2025 17:20:15 +0000</pubDate>
      <link>https://dev.to/thatosdeveloper/acpi-and-why-i-hate-intel-for-making-it-33j0</link>
      <guid>https://dev.to/thatosdeveloper/acpi-and-why-i-hate-intel-for-making-it-33j0</guid>
      <description>&lt;p&gt;NOTE: I only have a small part of ACPI 1.0 implemented (some parsing and helper functions, just the FACP currently), so please comment and give me any knowledge you may know of it in case I am wrong about anything!&lt;/p&gt;

&lt;h2&gt;
  
  
  My opinion on ACPI
&lt;/h2&gt;

&lt;p&gt;I personally highly dislike ACPI but after some work its pretty easy to implement once you are willing to read hundreds of pages of documentation. I mostly dislike it because of one specific thing, how much memory and paging stuff you need to mess with, I mean seriously, everything you want to do, you need to search for its header in the RSDT, from there you need you unmap the header of the thing you just searched for, map the entire thing after you have its physical memory address, usually you identity map it, and then from here you setup a bunch of extra stuff, and finally, you parse the table, if its encoded in AML you need to pass it through your AML interpreter, and you see why its a mess now, don`t you?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we are stuck with ACPI
&lt;/h2&gt;

&lt;p&gt;Its a standard, and one used by intel at that, we will be stuck with it until we make a better, less cluttered and messy standard, but most of these issues were fixed with ACPI 2.0+, right, RIGHT?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why ACPI 2.0+ STILL SUCKS
&lt;/h2&gt;

&lt;p&gt;ACPI 2.0+ Is more clean, provides more things, but guess what, it is 64bit, and does a bunch of big messy stuff, and you know what that means? The same mess from before, but you need to use different things, instead of the RSDP you have the XSDP, instead of the RSDT, XSDT, because they wanted to use 64bit pointers, which means we are stuck with 2 versions of the RSDP and XSDP and almost everything else, including a bunch of ACPI 2.0+ only features, making even more issues, and now, we are stuck, with having to try to do a bunch of extra stuff to figure out what version of ACPI is running on your system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why ACPI is kinda nice still
&lt;/h2&gt;

&lt;p&gt;ACPI, while a mess to setup, once you give it a nice API frontend that handles most of the more complex CPU/Architecture specific stuff, works somewhat well, you can figure out what type of hardware you have, you know what to do to certain fans, you can read tempetures, and so on. While I hate ACPI, its still a little nice, its usable once you use a dedicated AML interpreter like LAI, uACPI, or ACPICA (which is just a giant mess of things you need to provide ACPICA, but its clean, and at least, somewhat usable)&lt;/p&gt;

</description>
      <category>osdev</category>
      <category>kernel</category>
      <category>acpi</category>
      <category>intel</category>
    </item>
    <item>
      <title>Ring 3, and why its a nightmare</title>
      <dc:creator>ThatOSDeveloper</dc:creator>
      <pubDate>Fri, 11 Jul 2025 07:12:30 +0000</pubDate>
      <link>https://dev.to/thatosdeveloper/ring-3-and-why-its-a-nightmare-3mjb</link>
      <guid>https://dev.to/thatosdeveloper/ring-3-and-why-its-a-nightmare-3mjb</guid>
      <description>&lt;p&gt;I think that custom OS development is a very fun project that everyone interested in programming should try out, OSDev is a very small and niche hobby, but has a surprisingly large user base of its forums, wikis, and subreddits. Anyways onto the actual Ring 3 hate club.&lt;/p&gt;

&lt;p&gt;Ring 3 is a nice idea, a separated part of the system with little to no rights when configured normally and the only way to do anything with hardware is via an API, ring 3, is the safest spot for user apps in my opinion (though some microkernel loving people think its amazing for drivers (FYI, they are wrong) monolithic kernel is 100% better) of course, some ring 0 only (kernel space only) operating systems exist, such as &lt;a href="https://templeos.org/" rel="noopener noreferrer"&gt;TempleOS&lt;/a&gt;, created by Terry A Davis.&lt;/p&gt;

&lt;p&gt;Now Ring 3 on X86_64 is simple in concept, where with Ring 3, it is perfect for user apps, it just runs them, and usually the apps are separated, and get to call upon the kernel for the API (to read files, and deal with whatever is needed). But the issue with ring 3 is not the API, or getting to it (while that is a little unorthodox using fake interrupt returns to enter it), the issue is the C standard library, which is required for almost anything written in the userland, the issue is that it is a MAJOR component for literally every single app that runs, directly or indirectly.&lt;/p&gt;

&lt;p&gt;The C standard library provides functions such as malloc, free, and all C functions that are used and expected to be present, and they all heavily rely on the OS to do stuff, AND are highly standardized. And because of that, porting anything to your OS, means porting a C standard library, which means having to use some external code written by someone else, expecting a different system, and so on, and because of this, porting a libc is very hard.&lt;/p&gt;

&lt;p&gt;Porting the libc is also very useful though, as since its the base for almost every app under the sun, its also doing all of the heavy lifting, and once its done, you can port tens of thousands of apps, system utilities, and so on. But the main issue, is how massive the C standard library is, and also how standardized it is (which is also really useful since it makes porting really easy), and just a tiny little difference in implementation, means breaking compatibility in a subtle, almost entirely unnoticeable way.&lt;/p&gt;

&lt;p&gt;Now if you don't want to write your own libc (like any sane person at this point) you should try to port one, which I have tried, and it sucks. For example, newlib, a common choice, but a licensing nightmare, it uses a lot of different licenses and external code. Some libraries are good on a license level such as PDCLib (Public Domain C Library) which is a (mostly) C99/C11 compliant C library, but needs a bit of work to setup and assumes POSIX and is a grand old thing to deal with. And when you design a non POSIX, non UNIX like system, you are forced to either write your own, or fork an exist C library and pretty much rewrite it from the ground up to work with system that uses spawn(); instead of fork(); and instead of sbrk, it just uses a usermalloc and userfree API call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Experience:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Personally I have chose the route of suffering, a custom libc, because I am diverging from POSIX and UNIX highly, instead of a / for my root its 0: (for the EFI boot partition/system critical file thing), I plan to use a bunch of non POSIX/UNIX system calls, no sbrk, instead of fork its exec(); and so on. Also I plan to never support C++ and have a C only kernelspace and C only userspace.&lt;/p&gt;

&lt;p&gt;I once thought about porting newlib, but its licensing mess was less than optimal for an MIT-0 (MIT license without attribution being required) project. Anyways to summarize ring 3 is okay, running apps in it suck because they need a standard C library to port anything, and that needs a full scale API, or a LOT of suffering.&lt;/p&gt;

</description>
      <category>osdev</category>
      <category>kernel</category>
      <category>assembly</category>
      <category>c</category>
    </item>
    <item>
      <title>Dynamic Linking, and why I hate it and love it</title>
      <dc:creator>ThatOSDeveloper</dc:creator>
      <pubDate>Thu, 10 Jul 2025 04:26:12 +0000</pubDate>
      <link>https://dev.to/thatosdeveloper/dynamic-linking-and-why-i-hate-it-and-love-it-554a</link>
      <guid>https://dev.to/thatosdeveloper/dynamic-linking-and-why-i-hate-it-and-love-it-554a</guid>
      <description>&lt;p&gt;Dynamic linking is a method of loading libraries on the fly instead of compiling them directly into the binary. For example: &lt;code&gt;.dll&lt;/code&gt; files on Windows or &lt;code&gt;.so&lt;/code&gt; files on Linux. These files are loaded into a spot in memory and then used by the application as if they were part of the code.&lt;/p&gt;

&lt;p&gt;What I love about this is that app binaries stay small and can share common libraries. The downside, in my opinion, is that to support dynamic linking, you need a more advanced ELF loader that can parse and work with these types of files. Implementing this means parsing even more of the ELF standard, which is around 300 pages long. While it's not impossible to implement fully, it's far more difficult than supporting a minimal subset for static binaries (ones that don't use dynamic linking at all).&lt;/p&gt;

&lt;p&gt;I like the idea and do plan to implement it in the Mantle kernel, but it's going to be on the backburner for quite some time.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I’ve moved the Mantle kernel to Codeberg, since I disagree with some of the privacy violations on GitHub.&lt;br&gt;&lt;br&gt;
The repository is now &lt;a href="https://codeberg.org/SlugOS/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Note:&lt;/strong&gt; You’ll need a Codeberg account and be logged in to view it — this is to stop AI scrapers from accessing it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side note 2:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I also created a repository called &lt;strong&gt;SlugOS-base&lt;/strong&gt;, which is meant to be the "base" version of SlugOS — a minimal foundation that other "distros" can build upon.&lt;/p&gt;

</description>
      <category>elf</category>
      <category>osdev</category>
      <category>linking</category>
      <category>kernel</category>
    </item>
    <item>
      <title>SlugOS, my little hobby OS</title>
      <dc:creator>ThatOSDeveloper</dc:creator>
      <pubDate>Thu, 03 Jul 2025 02:02:22 +0000</pubDate>
      <link>https://dev.to/thatosdeveloper/slugos-my-little-hobby-os-45hl</link>
      <guid>https://dev.to/thatosdeveloper/slugos-my-little-hobby-os-45hl</guid>
      <description>&lt;p&gt;SlugOS is my little hobby OS project that I have been working on for a bit now (about 7 - 8 months, almost a year), though SlugOS is its name, the kernel itself is called &lt;a href="https://github.com/SlugOS/mantle" rel="noopener noreferrer"&gt;Mantle&lt;/a&gt; and is on its 10th rewrite (I am a perfectionist and sometimes stuff gets to complex, I am very deep into stuff I do not know, and have to rewrite to get an improved version and fix any issues that pop up), it uses limine, has a full PMM, VMM, and a heap allocation system, and even a very simple API (only printing strings and single characters), the plan is to at some point get a shell, and run actual apps from an initramfs (which it can do with flat binaries, but I want ELF64), and then a real filesystem, dev.to will act as my place to blog/talk about SlugOS/Mantle.&lt;/p&gt;

&lt;p&gt;Mantle has some other features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SSE1/SSE2 support&lt;/li&gt;
&lt;li&gt;The legacy 8259 PIC (Programmable Interrupt Chip)&lt;/li&gt;
&lt;li&gt;The legacy Intel 8253/8254 PIT (Programmable Interrupt Timer)&lt;/li&gt;
&lt;li&gt;A full kprint (printf) implementation, minus some things, like floating point support, but works with most stuff.&lt;/li&gt;
&lt;li&gt;A disk driver (ATA PIO mode, not very good)&lt;/li&gt;
&lt;li&gt;FAT32 disk driver&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An example program (in NASM assembly) that would print out a string, might look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BITS 64
section .text
global _start

_start:
    mov rsi 1 ; Print string code
    mov rdi string ; The 2nd arg
    int 0x70 ; The system API
    ret ; Return to the program calling this

section .data
string db "API test!", 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course this will not work unless I get a working ELF loader which could mean a full libelf implementation, or at least a very basic ELF loader, and in theory a ring 3/userspace setup. I plan to get a FAT32 driver beforehand. The current setup for running apps is a flat binary and just doing a direct jump to them, due to not having any idea on where it goes, in the binary it must have hardcoded values instead of strings at a memory address, an app might look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BITS 64

; This is for the system API, this is compiled and put into the initramfs

; System call 0 (print char) - 'H'
mov rdi, 0
mov rsi, 0x48
int 0x70

; System call 0 (print char) - 'E'
mov rdi, 0
mov rsi, 0x45
int 0x70

; System call 0 (print char) - 'L'
mov rdi, 0
mov rsi, 0x4C
int 0x70

; System call 0 (print char) - 'L'
mov rdi, 0
mov rsi, 0x4C
int 0x70

; System call 0 (print char) - 'O'
mov rdi, 0
mov rsi, 0x4F
int 0x70

; System call 0 (print char) - ','
mov rdi, 0
mov rsi, 0x2C
int 0x70

; System call 0 (print char) - ' '
mov rdi, 0
mov rsi, 0x20
int 0x70

; System call 0 (print char) - 'A'
mov rdi, 0
mov rsi, 0x41
int 0x70

; System call 0 (print char) - 'P'
mov rdi, 0
mov rsi, 0x50
int 0x70

; System call 0 (print char) - 'I'
mov rdi, 0
mov rsi, 0x49
int 0x70

; System call 0 (print char) - ' '
mov rdi, 0
mov rsi, 0x20
int 0x70

; System call 0 (print char) - 'W'
mov rdi, 0
mov rsi, 0x57
int 0x70

; System call 0 (print char) - 'O'
mov rdi, 0
mov rsi, 0x4F
int 0x70

; System call 0 (print char) - 'R'
mov rdi, 0
mov rsi, 0x52
int 0x70

; System call 0 (print char) - 'L'
mov rdi, 0
mov rsi, 0x4C
int 0x70

; System call 0 (print char) - 'D'
mov rdi, 0
mov rsi, 0x44
int 0x70

; System call 0 (print char) - '!'
mov rdi, 0
mov rsi, 0x21
int 0x70

; System call 0 (print char) - Newline
mov rdi, 0
mov rsi, 0x0A
int 0x70

; Return
ret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which, of course, is long, ugly, and not very readable or useful since it lacks basic features. Moving beyond these flat binaries to a proper ELF loader and a more robust API is a key next step for the Mantle kernel, and I'm excited to share that progress with you as SlugOS continues to evolve. Have a great day or night wherever you are.&lt;/p&gt;

</description>
      <category>osdev</category>
      <category>c</category>
      <category>assembly</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
