Search code examples
x86bootloaderbiosreal-mode

Relocating bootloader into EBDA?


For educational purposes, I am trying to write a simple x86 bootloader that boots a dummy OS from a floppy disk image.

I am currently at the stage where I have gotten my bootloader to output "Hello world" via BIOS video interrupts. I would now like to relocate the bootloader to a higher memory address so I can load an OS image to where it is currently located.

Now here is where I am confused: the textbook I am reading suggests to relocate the bootloader (which is 512 bytes large) to segment 0x9800 which is 32 kB before segment 0xA000. But as far as I understand, the Extended BIOS Data Area (EBDA) can extend up to 128 kB down from address 0xA0000 and should not be overwritten.

So is my textbook wrong? Should I instead move the bootloader to segment 0x7800 (or a bit higher if the EBDA is smaller)?


Solution

  • Now here is where I am confused: the textbook I am reading suggests to relocate the bootloader (which is 512 bytes large) to segment 0x9800 which is 32 kB before segment 0ax000. But as far as I understand, the Extended BIOS Data Area (EBDA) can extend up to 128 kiB down from address 0xa0000 and should not be overwritten.

    So is my textbook wrong?

    Yes, the textbook is wrong.

    The second best option would be to use int 0x12 to determine how much memory you can safely use; then relocate the boot loader to the "highest safe address" (and use segmentation so that it works without much trouble, because all the code/data offsets remain the same regardless of how you need to set cs/ds segments).

    Note that there isn't an official limit on how large the EBDA can be. The closest thing to an official limit is the PXE specification (used for network boot) which says that the PXE firmware/ROM can take memory at 0x00080000 (and make the EBDA bigger so the OS/boot loader won't trample that memory). With that in mind; you could assume memory below 0x00080000 can be used "relatively safely" without checking.

    The best approach would be to relocate the boot loader to the lowest address (e.g. 0x00000800) so you don't need to worry about figuring out what is/isn't usable RAM until later (not forgetting that "later" you'll probably be using "int 0x15, eax=0xE820" to get a full memory map anyway).