I use a Custom Filesystem - What Bootloader Solution is right for me?: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
(Header, styling, excess whitespace removal)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(5 intermediate revisions by 4 users not shown)
Line 7: Line 7:
I must give a small overview of the boot process for an OS that is installed in a partition other than the first partition, which is also not the only OS installed on the hard Disk.
I must give a small overview of the boot process for an OS that is installed in a partition other than the first partition, which is also not the only OS installed on the hard Disk.


The Master Boot Record holds the Boot Manager for the disk. GRUB is techniacally a boot loader, but its functionality far exceeds that of a conventional boot loader, and crosses the line of a Boot Manager very convincingly. Upon completion of its initialization sequence, the BIOS, in order of the priority set in the CMOS, loads a bootloader from the default boot disk. Assume that the HDD is given priority for our example. So the BIOS loads the first HDD's (or second, or third, or fourth, depending on what you set the boot order to), [[MBR (x86) | Master Boot Record]] into RAM at 0x7C00 and jumps to it, passing the drive number via a register. The MBR contains code to bootstrap an OS, or a second stage of itself, depending on how considerate the bootloader in question is. GRUB loads its second stage, and displays a menu listing all of the OSs recorded in its configuration file.
The Master Boot Record holds the Boot Manager for the disk. GRUB is technically a boot loader, but its functionality far exceeds that of a conventional boot loader, and crosses the line of a Boot Manager very convincingly. Upon completion of its initialization sequence, the BIOS, in order of the priority set in the CMOS, loads a bootloader from the default boot disk. Assume that the HDD is given priority for our example. So the BIOS loads the first HDD's (or second, or third, or fourth, depending on what you set the boot order to), [[MBR (x86) | Master Boot Record]] into RAM at 0x7C00 and jumps to it, passing the drive number via a register. The MBR contains code to bootstrap an OS, or a second stage of itself, depending on how considerate the bootloader in question is. GRUB loads its second stage, and displays a menu listing all of the OSs recorded in its configuration file.


These OSs have given GRUB commands on how to boot them:
These OSs have given GRUB commands on how to boot them:
Line 13: Line 13:
* For Windows, a record is placed which indicates the partition Windows is installed on, and an instruction to ''chainload'' one sector (512 bytes) into RAM at 0x7C00, and jump to it; In other words, simply load the Windows bootloader into RAM as if it was placed there by the BIOS.
* For Windows, a record is placed which indicates the partition Windows is installed on, and an instruction to ''chainload'' one sector (512 bytes) into RAM at 0x7C00, and jump to it; In other words, simply load the Windows bootloader into RAM as if it was placed there by the BIOS.
* For OSs that use EXT, ReiserFS, or other directly supported GRUB filesystems, you have the convenience of being able to ask GRUB to look into the partition and ''find'' your kernel file and load it into memory.
* For OSs that use EXT, ReiserFS, or other directly supported GRUB filesystems, you have the convenience of being able to ask GRUB to look into the partition and ''find'' your kernel file and load it into memory.
* For OSs that do ''not'' use a GRUB supported File system, the convention has been to simply ask GRUB to chainload the partition boot sector for your OSs partition and jump to it. However, using some logic, it is possible to avoid having to do anything whatsoever in real mode, or having to write a bootloader, even for a custom FS, and have GRUB do all the work.
* For OSs that do ''not'' use a GRUB supported File system, the convention has been to simply ask GRUB to chainload the partition boot sector for your OSs partition and jump to it. However, using some logic, it is possible to avoid having to do anything whatsoever in real mode, or having to write a bootloader, even for a custom file system, and have GRUB do all the work.


=== The GRUB 'kernel' and 'chainloader' commands ===
=== The GRUB 'kernel' and 'chainloader' commands ===
Line 20: Line 20:


* Simply take note of the fact that the user wants to set that partition as the root, or
* Simply take note of the fact that the user wants to set that partition as the root, or
* If the partition has a recognizible Fs (one known by GRUB), GRUB can also ''mount'' it for file system parsing to actually locate a kernel image on disk.
* If the partition has a recognizable file system (one known by GRUB), GRUB can also ''mount'' it for file system parsing to actually locate a kernel image on disk.


When a partition is chosen as the root for GRUB's operations, there are two ways to load an executable image:
When a partition is chosen as the root for GRUB's operations, there are two ways to load an executable image:
Line 29: Line 29:
'''The 'chainloader' command:'''
'''The 'chainloader' command:'''
The chainloader command loads an executable image of the assumed format 'binary' at 0x7C00 and jumps to the address 0x7C00.
The chainloader command loads an executable image of the assumed format 'binary' at 0x7C00 and jumps to the address 0x7C00.



== How may I use this information to ensure that GRUB can load an executable image off my custom FS? ==
== How may I use this information to ensure that GRUB can load an executable image off my custom FS? ==
Line 37: Line 36:
To load the program, your instructions to GRUB will be something like the following:
To load the program, your instructions to GRUB will be something like the following:


<source lang="text">rootnoverify (hd0,PARTITION_NUMBER)
<syntaxhighlight lang="text">rootnoverify (hd0,PARTITION_NUMBER)
kernel 0+BOOT_RESERVED_OFFSET
kernel 0+BOOT_RESERVED_OFFSET
boot</source>
boot</syntaxhighlight>


The kernel command loads a multiboot compliant kernel, and in this case, we have specified an absolute number of sectors to load. The 'kernel' command can automatically detect if the file it's loading from the sectors is an ELF program. In other words, your 'bootloader' may even be a full ELF program, using this trick. In fact, you may even decide to place your kernel's executable image ''as the first N sectors, and have GRUB ELF load the kernel as absolute sectors, and not have to worry about parsing your custom FS at all.''
The kernel command loads a Multiboot compliant kernel, and in this case, we have specified an absolute number of sectors to load. The 'kernel' command can automatically detect if the file it's loading from the sectors is an ELF program. In other words, your 'bootloader' may even be a full ELF program, using this trick. In fact, you may even decide to place your kernel's executable image ''as the first N sectors, and have GRUB ELF load the kernel as absolute sectors, and not have to worry about parsing your custom FS at all.''


Your kernel image, now loaded into memory (if it's an ELF, you can link it to 1MB physical), can then set itself up painlessly, and it also gets the benefit of the GRUB multiboot Data structure passed to it. This method completely invalidates the need to write a real mode bootloader. There are other reasons why it is probably ''best'' that Hobbyist OS Developers use this method:
Your kernel image, now loaded into memory (if it's an ELF, you can link it to 1MB physical), can then set itself up painlessly, and it also gets the benefit of the GRUB Multiboot Data structure passed to it. This method completely invalidates the need to write a real mode bootloader. There are other reasons why it is probably ''best'' that Hobbyist OS Developers use this method:


The method implies that GRUB is placed into the MBR of a hobby OS partition installation, or even whole disk installation. If all hobby OSs use this method, whether or not they use a custom FS, it gives them the advantage of being able to load a full program, in ''protected mode'' via GRUB, and bypassing the Real Mode bootloader stage ''completely''. No more problems with writing an efficient program in 446 bytes.
The method implies that GRUB is placed into the MBR of a hobby OS partition installation, or even whole disk installation. If all hobby OSs use this method, whether or not they use a custom FS, it gives them the advantage of being able to load a full program, in ''protected mode'' via GRUB, and bypassing the Real Mode bootloader stage ''completely''. No more problems with writing an efficient program in 446 bytes.

=== Propaganda ===

The best advantage of all is that again, GRUB will then be able to allow Hobbyists one more, extremely essential advantage: The unification of all hobbyist OSs under one bootloader. This will mean that every OS coming out will be using GRUB. Then, since Windows doesn't care enough to be polite, if it overwrites GRUB and placed NTLDR into the MBR, then since everyone else is using GRUB, Windows ends up looking like the selfish, unpopular choice. Also, GRUB has code to handle all kinds of unexpected real hardware situations in Real Mode that you kernel's private bootloader cannot deal with most likely. There are too many benefits for this method not to become the champion of the boot process for hobbyist OSs.

By now the reader should be able to tell that the author favours this method highly, and recommends it avidly.


[[Category:Filesystems]]
[[Category:Filesystems]]
[[Category:Bootloaders]]
[[Category:FAQ]]
[[Category:FAQ]]

Latest revision as of 04:32, 9 June 2024

While rolling your own filesystem is not recommended, you may find yourself in a place where a specially designed filesystem is a must have. The most obvious solution is to write a custom bootloader specifically designed for the new filesystem, or you could use an existing bootloader - GRUB. This guide shows how you can use this tool for your work.

What GRUB can do

GRUB allows you to do a lot of things that you wouldn't be able to do with any other bootloader due to its ability to load an OS in raw sectors from a floppy or hard drive.

I must give a small overview of the boot process for an OS that is installed in a partition other than the first partition, which is also not the only OS installed on the hard Disk.

The Master Boot Record holds the Boot Manager for the disk. GRUB is technically a boot loader, but its functionality far exceeds that of a conventional boot loader, and crosses the line of a Boot Manager very convincingly. Upon completion of its initialization sequence, the BIOS, in order of the priority set in the CMOS, loads a bootloader from the default boot disk. Assume that the HDD is given priority for our example. So the BIOS loads the first HDD's (or second, or third, or fourth, depending on what you set the boot order to), Master Boot Record into RAM at 0x7C00 and jumps to it, passing the drive number via a register. The MBR contains code to bootstrap an OS, or a second stage of itself, depending on how considerate the bootloader in question is. GRUB loads its second stage, and displays a menu listing all of the OSs recorded in its configuration file.

These OSs have given GRUB commands on how to boot them:

  • For Windows, a record is placed which indicates the partition Windows is installed on, and an instruction to chainload one sector (512 bytes) into RAM at 0x7C00, and jump to it; In other words, simply load the Windows bootloader into RAM as if it was placed there by the BIOS.
  • For OSs that use EXT, ReiserFS, or other directly supported GRUB filesystems, you have the convenience of being able to ask GRUB to look into the partition and find your kernel file and load it into memory.
  • For OSs that do not use a GRUB supported File system, the convention has been to simply ask GRUB to chainload the partition boot sector for your OSs partition and jump to it. However, using some logic, it is possible to avoid having to do anything whatsoever in real mode, or having to write a bootloader, even for a custom file system, and have GRUB do all the work.

The GRUB 'kernel' and 'chainloader' commands

GRUB is able to make a particular partition on a hard drive the 'root' for its operations. It can do so in one of two ways:

  • Simply take note of the fact that the user wants to set that partition as the root, or
  • If the partition has a recognizable file system (one known by GRUB), GRUB can also mount it for file system parsing to actually locate a kernel image on disk.

When a partition is chosen as the root for GRUB's operations, there are two ways to load an executable image:

The 'kernel' command: The kernel command either reads an executable, Multiboot Compliant image from a recognized File system, or as absolute sectors from the start of the partition.

The 'chainloader' command: The chainloader command loads an executable image of the assumed format 'binary' at 0x7C00 and jumps to the address 0x7C00.

How may I use this information to ensure that GRUB can load an executable image off my custom FS?

Take some time to think. You are designing a custom filesystem. There is therefore no restriction on where on the partition (which absolute sector) the FS header, and therefore the FS itself should start. You are completely free to, in your FS specification, state that a partition complying with YourOwnFS should not touch the 1st, say, ~16-32KB, and that it is reserved for boot information, or other useful data. Therefore, in the Partition Table, your partition is stated to begin at Sector X, but the Fs itself may begin at sector X+BOOT_RESERVED_OFFSET. This way, we replace the old, completely illogical standard which dictates that a partition's boot sector contains boot code, and, using the reserved sectors for your FS, place an executable image at the absolute beginning of the partition containing a full, conveniently sized boot program for your OS.

To load the program, your instructions to GRUB will be something like the following:

rootnoverify (hd0,PARTITION_NUMBER)
kernel 0+BOOT_RESERVED_OFFSET
boot

The kernel command loads a Multiboot compliant kernel, and in this case, we have specified an absolute number of sectors to load. The 'kernel' command can automatically detect if the file it's loading from the sectors is an ELF program. In other words, your 'bootloader' may even be a full ELF program, using this trick. In fact, you may even decide to place your kernel's executable image as the first N sectors, and have GRUB ELF load the kernel as absolute sectors, and not have to worry about parsing your custom FS at all.

Your kernel image, now loaded into memory (if it's an ELF, you can link it to 1MB physical), can then set itself up painlessly, and it also gets the benefit of the GRUB Multiboot Data structure passed to it. This method completely invalidates the need to write a real mode bootloader. There are other reasons why it is probably best that Hobbyist OS Developers use this method:

The method implies that GRUB is placed into the MBR of a hobby OS partition installation, or even whole disk installation. If all hobby OSs use this method, whether or not they use a custom FS, it gives them the advantage of being able to load a full program, in protected mode via GRUB, and bypassing the Real Mode bootloader stage completely. No more problems with writing an efficient program in 446 bytes.