Custom OS (BaseDOS)

6/28/23

OS Development is a really cool concept for me. I've been poking and prodding at x86 for a long time, each time coming from it with a new perspective and trying again from scratch. The last time I tried, I came up with the name BaseDOS, which I am going to shamelessly reuse for this iteration since the old BOSP is dead.

Last time, I rolled my own bootloader, which was cool because it gave me infinite power and taught me how computer bootstrapping worked. This was fun but came with important drawbacks. Mainly, because I was basically booting my OS directly from the boot sector, that meant the disk had to be occupied solely by my OS, no multi-boot. This made it unusable in practice for testing on hardware, since I'd need to keep it on a drive by itself (could've used a usb but oh well).
With this in mind, I have decided to conform to the masses (and my own computer) I will use GRUB this time around as a bootloader. I doubt I could learn anything significant by doing it myself again, and using GRUB I can place my OS comfortably alongside my main Ubuntu install and test my OS on real metal.

Also just now thinking about it, I want to clarify. This page is going to act as a sort of blog as I develop BaseDOS again. Expect cool embedded pictures and lots of shitty rambling from me on this page in the future. If you're reading this in the future, scroll down, I assume there's at least one other post.

6/29/23

Howdy everyone! This is the first actual development update for my system. Only got to put a couple hours in and it's been hell. Been spending the whole damn time trying to debug and figure out this whole multiboot thing. No matter what I try GRUB always tells me it can't detect a multiboot header in my binary. It was so frustrating that I had to sleep it off. Well guess what I just found out a couple minutes ago?? GRUB doesn't support 64 bit systems! And guess what I've been doing this whole time?? That's right, writing and compiling and linking with my x86_64 compiler! There's the lesson for you, kiddos: Always ALWAYS read documentation and tutorials carefully. Saves you hours of debugging and frustration. Gonna set up a 32 bit cross-compiler and write a simple hello world where I boot from GRUB and jump to a C function that prints to screen in VGA text mode, just to prove to myself that I'm not completely incompetent. From there, I'll go back and see about setting up long mode and then jumping to 64 bit C code. I wonder if I can even link those together, if GRUB requires an ELF32 file. Can you link a 32 bit object file and a 64 bit object file together? I suppose we'll find out after I get that 32 bit test OS running on hardware. If I'm successful, hopefully you guys will get a picture in the next update!

6/30/23

I am living in a cycle of endless torment. Let me explain...

So good news first, I got my little 32 bit multiboot kernel test to boot. Under QEMU as a binary, as an iso image, under virtualbox as an iso image, and even on physical hardware as a bootable usb running under BIOS. And that right there is the issue. One of the "requirements" I have for this project is I want it integrated with my system so to speak. My main OS (Ubuntu) boots under GRUB on my computer. I was hoping to just slap the BaseDOS binary into the boot folder, add an entry for it, and go. This didn't work. It showed up as an entry sure, and before I fixed my cross compiler it even tried to boot and informed me that it couldn't find the header. Well now it "boots" and doesn't show a thing. I had no idea why, until I tried booting my flash drive under UEFI, and sure enough, a similar issue happened. Except this time, GRUB helpfully informed me that it couldn't find a suitable display mode for my kernel.

This is because UEFI doesn't support any sort of text mode, which is something that most, if not all, OS tutorials rely on for making their terminals. Booting through UEFI gives you access to nothing except for a framebuffer. I have never worked with this, and also I was informed that if I was planning to use UEFI booting, I should upgrade my header to be multiboot2 compatible. This means one thing...

I am writing everything from scratch. Again. For like the third time in three days. And you might be saying "But thor, why don't you just simply write a BIOS based (ha) OS and not worry about UEFI booting?" The answer is pretty simple: I don't wanna. I wanted the ease of being able to boot it straight off my hard drive, and on top of that, everyone and their mother has created a toy OS that can boot into VGA 80x40 or whatever the fuck text mode and print "Hello World" to the screen. I want to prove to myself that I can move away from the drab repetative tutorials everyone has that just writes the same shitty bootloader and mini kernel over and over again with a different accent. The way forward is going to absolutely suck, since I have to actually read and implement these concepts on my own, rather than having someone spoon feed them to me. On the upside, this means that all the code in the kernel will be truly mine and I won't have to feel guilty about stealing boilerplate from other people. On top of that, the satisfaction of having an OS that is relatively future proofed in the sense that even after CSM gets dropped, it will still work is exciting.

So yeah, unfortunately no pictures this time. Next time you hear from me, I will have Hello World printed in a framebuffer under UEFI mode, or I will have dropped the project. Let's hope for the former. See you all then.

7/1/23

Eureka! After 4 days I finally have something decent to show for my efforts: A single letter printed to screen! Those who have any inkling about what I am going through surely grasps the importance of this. No text mode to assist me, no BIOS calls, just a canvas and some raw bytes. This is not completely bug free however. I had some of my logic confused so the characters are actually drawn flipped horrizontally, which is probably not too big of a deal, but it's still something to change.
A picture of a computer screen showing a white capital A on a blue background, surrounded by magenta.
I am very excited right now it's hard to properly articulate. Right now, all my OS can do is fill the screen with a given color, and draw the letter 'A' to the screen at an arbitrary coordinate with a background and foreground color of your choosing. Even this small victory feels monumentous to me. All that I have left to do is easy: write bitmaps for the rest of the letters in the font, add error checking so that my driver never writes outside of screen memory, and then add functions like draw string and draw rect. It even runs on my physical hardware! Though I haven't been able to test it with the A character yet as I've been away from the main computer, I have verified I can fill its screen with beautiful eye-bleeding magenta.

7/2/23

Okay so this is kind of cheating since it just hit midnight, thus technically justifying me to make a new blog post. I am so unbelievably excited about how things are going so I had to share:
A screenshot of a QEMU window, with 3 distinct lines of text at various places around the screen. In order from top left going down they read 'BaseDOS!', 'This is arbitrary I hope', and 'Big uh oh stinky time'. The first two are white text, and the third is green text surrounded by a black box.
Let me explain what you're seeing. First, I got a whole font loaded! In addition, I've abstracted away a lot of the bitwise math you had to do to get things printed to the screen. On the kernel end, all I have to do is call put_string and pass a null-terminated string, and a pair of coordinates. My graphics library handles the conversion from coordinates to a position in memory to draw the font sprites. I also show off here how I can change the foreground and background color at any time if I wish. I have not yet tested to see if I can use a clear background, but I might try that next. Draw a rectangle of an arbitrary color (probably magenta because that seems to be a theme) and then print a string half on and half off the rectangle and see if it preserves both background colors. More updates coming!

Okay so my action plan for the future is to add keyboard inputs and then throw myself into the fire by trying to implement a filesystem. I want to be able to read from my disk so I can export my fonts as some sort of bitmap spritesheet and load it on startup. Also so I can have a list of programs that I can simply dump into a folder and call. It will probably be super tough and I don't know if I'm anywhere near skilled enough for it. Will I have to write a complicated driver for communicating with the disk? The only time I read from the disk during my last OS project, I was using BIOS calls, which I don't have access to here. I have many questions, and hope to find agreeable answers. Until next time my fellow crazies! :)

7/4/23

Hello everyone. I don't have keyboard interrupts working (I was working on them and my OS triple faults whenever it boots so oops!) But in the meantime I developed the start of a basic set of terminal features. Right now, you can specify up to 8 terminals, each with their own foreground and background colors, along with bounds on the screen. This lets you keep information compartmentalized while printing debug messages and the like, and eventually should provide a convienent way of drawing multiple terminals to screen when I actually end up getting the rest of the things neccessary for the terminal (parsing, keyboard inputs, command buffer etc) implemented.

That's all I have for now in terms of new cool features, but I'm hoping next time you hear from me, I'll have keyboard and timer interrupts working just fine.

1/31/24

Happy new year everyone! So funny story... I never got those interrupts working. It's been so long that I don't even know what the problem was, but I'm willing to suspect it was entirely my fault. I actually don't know where any of the code for this is. Maybe on github but I'm not about to go looking. I am starting fresh. From scratch. Again. For like the billionth time. So welcome back to my journey.

Current plans for this time around: Stick with my general attitude from before, so uefi, 64 bit kernel. I want this to run on actual hardware alongside the rest of my operating systems. I am just hoping that if I take it slowly and carefully, and document my progress more closely, I won't end up with a random unfixable bug haha.

In additional news, for this run through I plan on recording all of my development. This of course means I won't be able to develop as often, since I have to have enough time to sit and record what I'm doing, but hopefully it means that I can sanity check my work for the future. Should mean that I make more progress in the long run. Idk if I'll upload the videos or where, but I want to at least keep a personal record.

Until next we speak, friends.