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.
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 TempleOS, created by Terry A Davis.
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.
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.
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.
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.
My Experience:
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.
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.
Top comments (0)