1
votes

So I found the following tutorial for building a simple bootloader: http://mikeos.sourceforge.net/write-your-own-os.html#firstos

Here is the start of his example and the area that I'm having trouble understanding:

start:
    mov ax, 07C0h       ; Set up 4K stack space after this bootloader
    add ax, 288         ; (4096 + 512) / 16 bytes per paragraph
    mov ss, ax
    mov sp, 4096

    mov ax, 07C0h       ; Set data segment to where we're loaded
    mov ds, ax

I understand that Mike here is trying to build a stack for his bootloader. The start of the program is at 07C0h in memory. What I don't understand is the following line 'add ax, 288 ; (4096 + 512) / 16 bytes per paragraph'. Why is he taking the total amount of the stack and boot sector, then dividing it by the 16-bit registers for the start of the stack segment? Shouldn't the stack segment start at 20h, right after the bootsector? Lastly, shouldn't the stack pointer then be set at the end of (512 + 4096)? Thanks

1
Do you already know how segmentation works? BTW the code is at 7c00h (double zero), 7c0h is the unique segment that starts at 7c00h. - Margaret Bloom
The stack can be placed anywhere that won't interfere. In the early versions of MikeOS and his tutorial he had a 4k buffer for reading data into after the bootloader and then placed the stack pointer 4k above that. In the actual OS the value is 544 instead of 244 to extend the data buffer to 8k. In MikeOS that buffer is used to read the FAT12 root directory into (14 sectors worth of data). The method used in MikeOS is valid - Michael Petch
Because the real mode interrupt vector table and the BIOS data area are between 0x0000 and 0x0520. When the first BIOSes were created they assumed that DOS had a 32kb memory requirement so they read the boot sector to near the top of the 32kb mark and then placed the stack the BIOS used at start up above that growing down from 0x8000. It happened to be DOS had a 32kb minimum memory requirement but most PC sold were 64KB or greater. They never changed the original 0x7c00 location for backwards compatibility. - Michael Petch
I'm not entirely sure why you think it is invalid. That code sets up this situation: i.stack.imgur.com/TGxxg.png .Not sure why that isn't valid. The blue is the stack area and the orange is the data area (including boot sector and 4kb buffer after that). That diagram has had the 20 bit segment:offset addressing converted to physical addresses - Michael Petch
I told you above that he uses the 4k after the boot sector to store data (from disk etc). In the real Mike OS he actually changes it to 8k (he adds 544) and he uses that buffer to read the entire root directory of the FAT12 file system to. Then he places the stack after that. He's just decided that the 4k above the boot sector will be used for whatever purpose he wants, and his OS he reads more disk sectors to. Just happens to be in the small tutorial he doesn't actually use that memory for anything. In real MikeOS bootloader he does use it and the comments are clearer on that point. - Michael Petch

1 Answers

0
votes

You are right. With the current implementation, the code will leave a gap of 4k. The way to resolve this is what you said, which is to set ss to end of bootsector / 16 and to load sp with 4k (not 4k + 512). Hence the correct implementation would be.

mov ax, 07c0h
add ax, 32     ; (512 / 16) i.e end of bootsector
mov ss, ax
mov sp, 4096

Aside, from the question, i would also like to mention that this type of bootloaders won't work on real machines anymore and you should focus on standards like UEFI to build a bootloader. It also takes care of other tasks such as switching the cpu modes.

If you wish to see a working UEFI based bootloader with a minimalistic kernel refer to my github repo https://github.com/RohitRTdev/RTOS