Writing a bootloader: know what you are getting into!
Posted: Mon Apr 14, 2003 10:06 pm
Ah spring, when a young man's fancy turns to thoughts of... writing a bootloader.
Well, that's how it seems, with all these posts. I don't want to discourage anyone from writing a bootloader, but if you know what you're up against, you might change your mind and use GRUB after all.
First of all, the boot code must fit into 512 bytes.
some code into 512 bytes that works on your computer, but it won't be very robust. When you ask other people to try out your OS, your code will fail because their computers are different from yours.
So you give up on the filesystem-type bootloader. New plan:
embed a map of the disk sectors used by Stage 2 into the Stage 1 bootsector. This is how GRUB's Stage 1 works. No big filesystem code, so now there's room in the bootsector for both CHS and LBA code and for text error messages, though they're short and cryptic ("Geom Error"). And this type of loader works with any filesystem.
But where does the sector map come from? It must be created by an install program. GRUB has an installer that runs from the Linux command prompt. GRUB Stage 2 also has an install program built into it, invoked by the "setup" command. So you've made your Stage 1 loader smaller and simpler, but all the complexity has moved into the install program (or into Stage 2).
And an installer is not all that's built in to GRUB. It has:
Summary and suggestions:
Well, that's how it seems, with all these posts. I don't want to discourage anyone from writing a bootloader, but if you know what you're up against, you might change your mind and use GRUB after all.
First of all, the boot code must fit into 512 bytes.
- This is a job for assembly language. If you hate asm, forget it. If you don't know asm, forget it.
- You must know your tools. When I wrote a bootsector, NASM made code that was larger than necessary. I had to figure out why this was happening, and work around it.
- If the code for what you want to do won't fit into 512 bytes, then you must write the bootloader in stages. Stage 1 fits into 512 bytes, and does nothing more than find, load, and run the larger Stage 2.
- No room in the code for error messages. If something goes wrong, the loader just beeps
- Stage 2 must run in (or start running in) real mode (16-bit)
- Stage 2 must be in binary format, without headers or relocations
- Stage 2 must be stored in the root directory of the disk
some code into 512 bytes that works on your computer, but it won't be very robust. When you ask other people to try out your OS, your code will fail because their computers are different from yours.
So you give up on the filesystem-type bootloader. New plan:
embed a map of the disk sectors used by Stage 2 into the Stage 1 bootsector. This is how GRUB's Stage 1 works. No big filesystem code, so now there's room in the bootsector for both CHS and LBA code and for text error messages, though they're short and cryptic ("Geom Error"). And this type of loader works with any filesystem.
But where does the sector map come from? It must be created by an install program. GRUB has an installer that runs from the Linux command prompt. GRUB Stage 2 also has an install program built into it, invoked by the "setup" command. So you've made your Stage 1 loader smaller and simpler, but all the complexity has moved into the install program (or into Stage 2).
And an installer is not all that's built in to GRUB. It has:
- read/write code for various filesystems (and VFS layer!)
- code to switch to real mode to call 16-bit BIOS interrupts
- command-line and menu user interfaces
- code to read ELF, a.out, and Multiboot executable files
- code to support compressed (gzip) kernels and modules
- simple memory management code
- serial port code
- network code!
- C library code: printf(), strcpy(), etc.
Summary and suggestions:
- Writing a bootloader is not as easy, fun, or interesting as you might think
- Use GRUB to boot 32-bit kernels
- Use MS-DOS or FreeDOS to boot 16-bit kernels
- If using GRUB really bothers you, write your own bootloader LATER, when you have something worth booting