2

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)?

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
Peter
  • 2,919
  • 1
  • 16
  • 35
  • Here's an example of [getting the size of available memory](https://hg.ulukai.org/ecm/ldosboot/file/dee4acc4db2f/boot.asm#l1304) then [relocating the loader](https://hg.ulukai.org/ecm/ldosboot/file/dee4acc4db2f/boot.asm#l1372). The optional RPL support is not needed for a custom OS if you don't want to be loaded from a DOS RPL. – ecm Mar 27 '21 at 11:52

1 Answers1

3

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).

Brendan
  • 35,656
  • 2
  • 39
  • 66
  • Thanks, that clears it up. But shouldn't the lowest usable address be `0x500`? And why isn't the bootloader placed there to begin with? – Peter Nov 13 '20 at 09:05
  • Or just load the bootloader into unused text video space ;-) – Michael Petch Nov 13 '20 at 17:50
  • 1
    @Peter: There's no official standard for that either (but there's no run-time test like `int 0x12`). Ralph Brown's Interrupt List (which comes with other lists - memory, IO ports, CMOS, etc) shows a few things at/after 0x00000500 ("print-screen status", "NEC PC-9800 series - screen mode", and a bunch of stuff for BASIC ROMs) but you can't be too sure about newer computers (RBIL hasn't been kept up-to-date). MS-DOS used memory from 0x00000600. so that should be safe. Rounding up to a power of 2 is nicer and "more safe". I typically round up to page boundary (0x00001000) for other reasons. – Brendan Nov 14 '20 at 01:06