Hi,
Solar wrote:If you enjoy doing the nitty-gritty, writing your own bootloader can be interesting and satisfying. But it is by no means a necessary exercise on the road to a real good, very own OS.
For a "real good" OS, deciding on whether or not to use GRUB depends on the OS design, not whether it's easier or if the developer likes doing boot loaders, and writing your own bootloader can be necessary.
A simple example would be allowing the user to select a video mode to use during boot, regardless of which version of VBE the video card supports.
A more complex example would be an OS design that treats all data segment registers as constants, so that DS, ES, FS and GS are never changed and never need to be saved/reloaded during a task switch or when user code enters kernel space (cpl=3 <-> cpl=0 transitions). Reloading a segment register is slow because it involves accessing the GDT (probable cache miss and cache line eviction) and a pile of protection checks, so this can improve performance (and make it easier to port to long mode). However, this does imply that virtual 8086 mode and the special segments needed to use the protected interface for BIOS functions (VBE, plug & play, PCI, APM, etc) aren't desirable because the data segment registers are no longer constants. In this case it can be considered better to use these services during boot in real mode instead.
One (admittedly subjective) problem I have with the "just use GRUB" mentality is that it tends to promote "lack of thought" in inexperienced OS developers. Often "just use GRUB" is followed by "GRUB boots the kernel", which isn't required by GRUB and isn't necessarily a good idea either. Writing your own boot loader forces you to consider things like where the kernel should be loaded, whether or not to have intermediate stages and how the boot should work. An example would be an OS where the boot loader loads a boot image and starts some intermediate code, and the intermediate code detects what hardware is present and automatically selects one of several kernels depending on what was detected. Another example would be an OS that has several different copies of the same kernel in physical memory - one copy for each NUMA domain (so that all CPUs can access the kernel's code from local memory rather than slower remote memory). Of course the same things can still be done if the OS is booted from GRUB - it's just less likely when "GRUB boots the kernel" is assumed without any prior design work.
I also agree with reasons given by others - mostly, that writing your own boot loader can be a good way to gain some experience before jumping into paging and schedulers. I've heard it argued that writing a boot loader teaches nothing that can be applied later, which I refute. It helps gain experience with basic assembly, segementation, protected mode initialization, etc - all things that a very experienced C programmer may never have come across, and all things that are required knowledge, if not strongly recommended, before designing a kernel.
Further, there's one last argument that is often neglected due to it's non-technical nature - "personal pride". To be able to say "I wrote all of the code for this OS" is something that a person can be proud of, much more so than "I wrote the code for this OS, except for X and Y and Z". Personal pride is one of the reasons people want to write
thier own OS to start with.
Anyway, my advice is to write your own boot loader and do a whole pile of research (Intel manuals, etc), then start writing a kernel. After you've implemented the memory manager, scheduler and possibly a few device drivers, chuck everything in the bin. After this, write a good OS design on "paper" and decide for yourself, based on everything you've learned, exactly what you do and don't want (including GRUB).
Cheers,
Brendan