os-tutorial
os-tutorial copied to clipboard
[org 0x7c00] fails in VMWare Player
on 03-bootsector-memory
, both examples fail to run when using VMWare Player, compiling with NASM to a BIN file, and loading via a virtual floppy disk.
When I add:
[org 0x7C00]
mov ax, 0x0000
mov ds, ax
...
Attempt 2 works fine, but attempt 4 still fails.
I failed to recount offsets for attempt 4. I recounted and updated the value (mov al, [0x7c3a]
in my case or mov al, [0x7c32]
if you just add the above code) and it worked.
The stack is not setup correctly. Thought i honestly don't know why did it work in some VMs, and not im some others. I guess virtual BIOSes already setup the stack before jumping to 0000:7C00... To make sure, always put the stack in segment 0000 (to avoid segmentation problems, but also because the BIOS might have put stuff in other segments), and put the stack pointer just above or bellow the bootsector code. I might research a little bit more on that with different emulators...
I've since switched to the below code and it works great. I'm guessing this is what you meant by "...make sure, always put the stack in segment 0000"
[org 0x7c00]
mov ax, 0x0000
mov ds, ax
DS
is not the stack segment but the data segment.
Here there is some x86_16 common segment registers:
Segment | Description |
---|---|
CS | Code segment |
DS | Data segment |
ES | Extra segment |
SS | Stack segment |
There's more. these are just the most important.
When the CPU executes an instruction it executes it at CS:IP
. At the end of the day a JMP <x>
is a MOV IP, <x>
. But when you move an address to a register, or just do any operation with RAM, for example with a MOV
, it should do the operation at DS:<address>
. If you have DS badly setup, then it might be trying to access a place of memory where you are not expecting it to.
Maybe the data segment wasnt setup correcly 🤔? To be honest I have no idea, and if that fixes it, then stack shouldn't have anything to do with it. Do you mess with segmentation somewhere else, which could be the cause of the issue? Are you using any weird BIOS in the emulators you use to test it? Have you tested it in a real machine?
Also shorten the code in bytes by doing this:
push 0
pop ds
instead of what you were doing. It will shorten by 3 bytes. Trust me, when you can only work with 512 bytes optimizations like this one are critical. WARNING: For this to work you must previously setup the stack!
I've since switched to the below code and it works great. I'm guessing this is what you meant by "...make sure, always put the stack in segment 0000"
[org 0x7c00] mov ax, 0x0000 mov ds, ax
Thanks very much for this! I spent a whole day trying to figure out why my image wasn't running on actually hardware while it successfully ran in QEMU. I added the code as you mentioned and it works perfectly now. Thanks!
No problem :)
But if it wasn't running on actual hardware, I imagine it has nothing to do with this, but with the fact that the magic number 0xAA55 runs on old BIOSes, which are probably deprecated in your modern UEFI motherboard. I recommend switching to GRUB to boot your operating system, as GRUB already takes care for you of booting. This way, if something gets deprected or anything, you are going to be sure that GRUB is up-to-date with the changes and your OS will still run nicely without having to change any code.
If that code worked thought, I assume that you have access to some old-school computer don't you?
Also, by seeing this: https://github.com/arashfotouhi/MiniOS/blob/master/Makefile, (totally unrelated to what I said above), i think it would be a good practice to use a crosscompiler to be honest.