How to read MBR on QEMU

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
ljtpetersen
Posts: 5
Joined: Thu May 06, 2021 6:49 am
Location: New Brunswick, Canada

How to read MBR on QEMU

Post by ljtpetersen »

When I try to read the MBR from the loaded boot sector using QEMU, I only find zeroes. I put my bootloader onto a USB stick and booted from it on my PC, and it managed to read the MBR just fine. When I hexdump the image, I find the MBR in the first sector (offset 446, length 64). Is it ok to read the MBR from the boot sector that is loaded by the BIOS at 0x7c00, or is there a better method to read the MBR. Also, I already tried reloading the MBR into some other address. It also didn't work (on QEMU). How should I read the MBR on QEMU. Is the way I'm reading it currently considered bad?

Here is how I read the MBR:

Code: Select all

Disk_basic:
.loadSecondStage:
	pusha

	mov dl, [BOOT_DRIVE]				; Put boot drive into DL. It should not leave
										; for the duration of this function, for convenience.


	mov si, 0x1be + 0x7c00				; Address for start of MBR (which does not
										; overwrite any part of the boot sector,
										; I made sure of it).

.loadSecondStage.nextMBR:
	mov al, [si + 4]					; Get the system ID from the MBR.

	mov bl, al
	call Print.byte

	cmp al, 0xee						; Check if the id is 0xee.
	je .loadSecondStage.efiMBR

	cmp al, 0xef						; Otherwise, check if it is 0xef.
	je .loadSecondStage.efiGPT

	cmp si, 0x1fe + 0x7e00				; Check if we are past the last MBR entry.
	jge .loadSecondStage.errMBR

	add si, 0x40						; Otherwise, check the next entry.
	jmp .loadSecondStage.nextMBR

Here is what I get if I dump the memory of the QEMU session:

Code: Select all

0x7dbe: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7dc6: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7dce: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7dd6: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7dde: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7de6: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7dee: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7df6: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
Here is the dump of the image:

Code: Select all

000001be: 0000 0200 eeff ffff 0100 0000 ffff 0300
000001ce: 0000 0000 0000 0000 0000 0000 0000 0000
000001de: 0000 0000 0000 0000 0000 0000 0000 0000
000001ee: 0000 0000 0000 0000 0000 0000 0000 0000
All of my code can be found on my github:
https://github.com/ljtpetersen/jpos
ljtpetersen
Posts: 5
Joined: Thu May 06, 2021 6:49 am
Location: New Brunswick, Canada

Re: How to read MBR on QEMU

Post by ljtpetersen »

Just checked. I can read the MBR using Bochs. I'll be using that from now on. Could anyone inform me of a better way to access and read the MBR than to read it from the boot sector, or if my current method is fine, and QEMU is just weird.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to read MBR on QEMU

Post by Octocontrabass »

Your current method is fine, and the problem is almost certainly a bug elsewhere in your code. Here are some bugs in your code:

This instruction relies on the DS register before you've set it to a known value.

An interrupt could happen between the instruction that sets SS and the instruction that sets SP. Since SP has an unknown value at that point, the interrupt could end up overwriting something you're using.

The function number goes in a different register.

This is not the correct instruction for calling interrupts.
ljtpetersen
Posts: 5
Joined: Thu May 06, 2021 6:49 am
Location: New Brunswick, Canada

Re: How to read MBR on QEMU

Post by ljtpetersen »

Thanks, I can't imagine how much debugging it would've taken me to find these.
Post Reply