Peper OS
A single threaded operating system developed as a hobby project to understand low level computing.

Problem Statement
This project was done to understand how computers work in the lowest level near to the bear metal. When writing software, I was always bothered by how a simple operation we do such as reading a file or even drawing something on the screen works. This is my self-tried attempt to find answers for that.
Project Description
Peper OS is a very basic, bare minimum operating system. It currently only features the capability to switch on the computer, print some statements and power off.
The project uses Assembly language to write the boot loader portion which sits in the 1st 512 bytes of the booting disk (ISO). There's a assembly language code portion written to read from the hard disk so that the bootloader can load other data segments in to the memory. After that, C code is used to implement printing to screen and also a proper hard disk driver to read from the hard disk.
Since the OS don't have a linker, I compiled GNU C compiler disabling the libC i.e C standard library. Hence in this environment, only capability is to print to the screen. There are no other syscalls implemented yet. Code for reading from the hard drive is implemented however, it needs to be manually called. It's not exposed via syscalls.
Challenges & Learning Experience
This project was a huge learning experience for me and more importantly, even though the project itself is not useful in real-world, I was able to translate the knowledge gained here into real world scenarios.
This project exposed me to learn how programming languages work under the hood with dynamic linking. My first attempts of writing C code failed because my code used standard library. After several attempts, I learnt that I have to implement the functionalities provided by the standard library my self, since this is an OS from scratch. Hence I compiled GNU C Compiler without the standard library. The knowledge I gained from here directly translates to problems using modern tech stacks where we need static linking instead of dynamic linking. For example, if we are containerizing a Go application into an Alpine Linux base, it is necessary to statically compile the application since musl, the standard library Alpine linux uses lacks many features offered by LibC.
Through this project, I also learnt that printing to the screen means placing the data we need to write, i.e pixel data in the correct segments in memory and then hardware components will consume the data to render them. I learnt about the specific way we need to configure data in our hard disk or ISO file so that the code in ROM can locate our operating system and dump the bootloader into 0x7c00 memory address.
I learnt that everything we do in high level languages is nothing but making requests to the operating system and it is impossible to do anything useful other than calling the OS in such a high level language (or even assembly, when we are in a running OS). For example, we can't write letters into the terminal. All we can do is to make a request from the OS to write those letters onto the terminal on behalf of our application. This knowledge translates well into concurrency (as now I know our programs run only a small time in the CPU, and for most times, it is the OS that's executing for us). I learnt clearly that we are limited by the operating system about the things we can do. For example, if we prefer a window with a custom shape, we can't create that unless OS supports that feature.