I wrote the basis for a simple OS in C++ and have had no luck with researching how to write a simple bootloader for this OS to possibly use with GRUB or something similar to make writing the bootloader a bit easier. Take a look at it's GitHub repository to see what code I'm trying to boot.
The OS requires some very simple things to run and be fully functional. It needs to be able to use the standard C++ libraries (such as iostream
, fstream
, string.h
, and possibly iomanip
). It also needs to have any sort filesystem (NTFS, FAT, FAT32, Ext4, etc). And, most importantly, it needs a way to execute other executables (through system()
or any safer methods).
Currently it can run executables (called "commands") from a hardcoded directory, run an executable before fully loading the kernel (called "kautorun"), and can be compiled and run over top of Win32, and GNU/Linux.
Preferably, I want to be able to make writing the bootloader easy and I'm thinking using GRUB and some special compiler commands would do it. I'm just not sure how to approach this. What can I do to get this working? And, am I approaching this from the wrong angle?
EDIT: To narrow it down a bit, I need a bootloader to run these executables, preserve the C++ libraries I used, and keep the directory structure intact. Hopefully that narrows it down enough and takes this question out of hold for being too broad.
To write a booting OS takes a lot of work. I would recommend using something like IncludeOS which will allow you to write a single "application" which will boot.
Writing a boot loader, you will need to know the hardware you are booting on. For PC's there are two main ones.
Since your talking about GRUB then most likely talking about a BIOS machine.
A BIOS machine boots into 16bit x86 mode with BIOS services that you can use. It boots by loading the first sector of the master HD into address "0x0000:0x7C00" and then jumps to it.
This first sector is "normally" a MBR with a partition table. One is marked as the "boot" partition (or you get some sort of "menu" boot). The MBR code then loads the first sector of the booting partition into address "0x0000:0x7C00" and then jumps to it.
The first sector of a partition is normally called a BPB.
The BPB is normally a mixture of data about the partition type (FAT,NTFS,EXT,etc) and code to start the OS boot. Since it's only 1 sector that is loaded you are very limited for code space. So this is written in assembler only, this code uses the BIOS services to find the "real" boot code for the OS within the filesystem and load it into memory and jumps to it.
UEFI is similar to BIOS but provides a complete booting environment where you write a EUFI application and the boot menu configuration runs this application to boot your OS. This application can be written in C++ and you use the UEFI services (which include a lot more services than BIOS as you get API's for network and graphics for example). This boot code normally uses the boot configuration to load the initial OS booting code from the partition and jump to it (and also turn off UEFI services as well as they are not normally used from some point onwards).
From this point what the OS booting code does highly depends on the OS that is booting. They normally:
IncludeOS makes it easier by providing a very simplified versions of the above into a simple library.