assemblybootloaderosdevfat32mbr

How can I copy an existent BPB and put it in my bootloader code


I am currently working on a simple operating system (GitHub: https://github.com/Nutty000/PlanetOS)

I would like to make the os work on real hardware, but I am having trouble doing it because of the file system... I want my OS to be based on the FAT32 file system, but I need to somehow not overwrite the BPB which is on the MBR. I thought about writing a program that copies the existent BPB and puts it in the beginning of my .bin bootable file, but:

  1. I have no idea how to make that program, disk related stuff is too hard and confusing for me

  2. The BPB is too large and if I copy it then my bootloader code wont fit in 512 bytes

  3. I don't know what parts of the existent MBR code I should copy

I am trying to solve this for hours so excuse me if I make any grammatical mistakes.


Solution

  • For MBR

    The only case where the MBR "should" (see note) have a BPB is for un-partitioned disks, where the first sector of the disk is also the first sector of the file system. This is primarily old floppy disks and nothing else (everything else either uses partitions or a file system like ISO9660 that has different rules).

    Note: "should" means some operating systems (e.g. Windows) will whine about the disk being unformatted if there's no BPB. There's no strict requirement from firmware or hardware for a BPB to exist; and your OS can make up its own rules for what it wants.

    For old floppy disks, typically an OS developer does the reverse - e.g. they'll have (or write) a utility to create floppy disk image/s that are the right/desired size (e.g. 1440 KiB for standard 3.5 inch floppy disks) that creates a suitable BPB for that floppy disk format; then copy the image into whatever floppy disks they want without caring about the floppy disk's previous contents (possibly immediately after, or as part of, formatting the floppy disk). More often (now that floppy disks themselves are so obsolete that they effectively don't exist in practice) the floppy disk image is used directly in an emulator, or incorporated into a CD image/ISO and used for floppy emulation, where no physical floppy disk (and no "previous contents") is involved.

    If you ever actually do need to write a new first sector of the disk while preserving an existing BPB; then you can write a utility to do it (e.g. read the old 1st sector into a buffer, then overwrite the first few bytes before the BPB and the remainder after the BPB in the buffer, then write the modified buffer back to disk); or you might be able to use existing tools (specifically, the dd utility on most *nix systems).

    Also note that FAT32 doesn't make sense for floppy disks (due to the tiny size of the volume you'd want FAT12 instead).

    For 1st sector of FAT32 partition (not MBR)

    For partitioned disks, if you use FAT32, the first sector of the partition may contain the 1st sector of a boot loader (for BIOS, not UEFI) in addition to the BPB (required by FAT32 file system). In this case it's mostly the same solutions applied to a different sector (e.g. overwrite with a good BPB to suit the partition/disk, or use tools to preserve old BPB and only modify the "non-BPB" portions of the 1st sector).

    Note that eventually you'll end up writing some kind of OS installer that allows the user to create partition/s, format partition/s and install the OS on the new partition/s (including boot loader/s and lots of other files). Typically the OS installer you write will run on top of the OS you wrote (and be booted from CD or USB); and will recycle a bunch of utilities you wrote for your OS (e.g. partition management tools, etc) in addition to using your kernel, your drivers, etc.

    1. I don't know what parts of the existent MBR or 1st sector of partition code I should copy

    The location and size of the BPB depends on which version it is. Fortunately they're all described on wikipedia (at https://en.wikipedia.org/wiki/BIOS_parameter_block ).

    Mostly, to cover "worst/largest case", you want to ensure that your boot loader doesn't use offsets 0x000B to 0x0059 (and that whatever tool/s you use to merge the boot loader's 1st sector with a pre-existing BPB preserves the bytes from offsets 0x000B to 0x0059).

    Of course with a 512 byte sector size, losing about 80 bytes for the BPB can make it even harder for 1st sector of boot loader to contain the code needed to find the right partition and then either load the remainder of itself or 2nd stage (especially if there's adequate sanity/error checks and adequate error messages). Sometimes people alleviate the problem by setting some variables (e.g. "LBA of 2nd sector in partition") when the boot loader is installed (which is relatively easy if you wrote your own boot loader installer).