MBR Relocation

Programming, for all ages and all languages.
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

MBR Relocation

Post by mark3094 »

I'm developing an MBR on x86, and I'm having some trouble getting it to successfully relocate itself in memory. I'm using NASM as the assembler
So far, I have this:

Code: Select all

	mov si, Code		;set SI to code area
	mov di, 0x0600		;set DI to some location (destination)
	push word 0x0000		;segment
	push word 0x0600		;offset
	cld
	mov cx, 0x0200		
	rep movsb
	retf

Code:
	[i]More code here - print to screen and hang[/i]
There is also an 'ORG 0x7c00' and some stack setup preceeding this.

This seems to work fine, as it prints to screen and hangs as expected.

The problem comes with my next phase. I am using int13 and ah=42h to read a sector into memory. This is just a 'garbage' sector for now (I don't jump to it), as I'm just testing. Whenever I read a sector to 0x7c00, it doesn't print to screen, or prints garbage. Reading to other locations is fine.

I think I'm not relocating my boot sector correctly, and int13 is overwriting running code in memory. Does this sound right? Any pointers to get me in the right direction?



For reference, here is the DAP:

Code: Select all

		DAPSize db 0x10			;byte - size of packet (16 bytes)
		DAPNULL db 0x00			;byte - NULL
		DAPSectors dw 0x0001			;word - number of sectors to transfer
		DAPOffset dw 0x7e00			;dword - buffer (segment:offset) - remember little-endian, and align to word boundary
		DAPSegment dw 0x0000
		DAPLBA dd 0x0000003f			;dword - starting LBA
		DAPLBA48 dd 0x00000000			;dword - used for 48-bit LBA
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: MBR Relocation

Post by bluemoon »

Let's say your Code offset is somewhere at 0x7C00 + N (N as there is code to handle movsb)
After you jump to 0x0600:0000 (which is the new Code), the CPU then disagree the offsets and thus you start accessing bogus memory - it may still be fine to output single char on screen:

So,
- The assembler assume Code: offset is 7C00+N, Data is located at 7C00+(data_label-$$)
- In reality it is 0000 + (data_label-$$-N)
User avatar
Yoda
Member
Member
Posts: 255
Joined: Tue Mar 09, 2010 8:57 am
Location: Moscow, Russia

Re: MBR Relocation

Post by Yoda »

In other words, for that pushes and retf you typed in, you must ORG 600h your code.
Yet Other Developer of Architecture.
OS Boot Tools.
Russian national OSDev forum.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: MBR Relocation

Post by bluemoon »

There is more issues beside the ORG problem, but I would leave the debugging fun for the OP, hints are given.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: MBR Relocation

Post by turdus »

Here's one solution for relocation (can be found on wiki...)

Code: Select all

		ORG		0600h
		USE16
master_boot_record:
		cli
		xor		ax, ax
		mov		ss, ax
		mov		sp, 600h
		push		ax
		pop		es
		push		cs
		pop		ds
		;find our position in memory.
		call		.getaddress
.getaddress:
		pop		si
		sub		si, .getaddress-master_boot_record
		cld
		mov		di, sp
		mov		cx, 100h
		repnz		movsw
		jmp		0:.start
.start:
Also sets the stack (before your code) and segment registers correctly.
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: MBR Relocation

Post by mark3094 »

Thank you everyone.
Your suggestions help a lot. I will try some debugging based on your advice.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: MBR Relocation

Post by Brendan »

Hi,
turdus wrote:

Code: Select all

		xor		ax, ax
		mov		ss, ax
		mov		sp, 600h
Probably a bad idea to have SS:SP set to 0x0000:0x0600. If more than 256 bytes of stack space is used (including "used by BIOS IRQ handlers and BIOS functions") you trash the BIOS data area that ends at 0x00000500.

I'd have a least 1 KiB of stack space reserved for BIOS (just in case); which means the lowest SS:SP I'd consider using for an MBR is 0x0000:0x0900.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Yoda
Member
Member
Posts: 255
Joined: Tue Mar 09, 2010 8:57 am
Location: Moscow, Russia

Re: MBR Relocation

Post by Yoda »

True.
The best location for MBR stack is 0000:7C00h, right below an old code location.
Yet Other Developer of Architecture.
OS Boot Tools.
Russian national OSDev forum.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: MBR Relocation

Post by turdus »

Brendan wrote:Probably a bad idea to have SS:SP set to 0x0000:0x0600. If more than 256 bytes of stack space is used (including "used by BIOS IRQ handlers and BIOS functions")
That was the homework part... I've mentioned that it sets the stack before the code...

Anyway, 256 bytes could be more than enough if you know what you're doing. I do not use local variables in stack, I keep track of what I push (max 6 bytes at a time), also I have interrupts disabled in my MBR code (using stack above 800h would causes problems in my code as I load the 2nd loader and GPT there).

But you're right some BIOS functions (namely VBE) require more space on stack. As soon as my 2nd stage loader starts, it sets up it's own bigger stack (it's not an accident that in the wiki example one of the first thing my 2nd stage do is expanding the stack size to 512 bytes. I think if it's still not enough that's the reader's duty to find a new bigger place for it).
invalid
Member
Member
Posts: 60
Joined: Thu Feb 23, 2012 8:39 am

Re: MBR Relocation

Post by invalid »

turdus wrote:256 bytes could be more than enough (...) expanding the stack size to 512 bytes
I'm trying to get rid of 8-bit habits of "make all you can to save one byte/one clock cycle". Unless you develop for some embedded device, just take a full page for the stack, come on, it's 2012, there are still gigabytes left.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: MBR Relocation

Post by turdus »

ydoom wrote:I'm trying to get rid of 8-bit habits of "make all you can to save one byte/one clock cycle".
That's you, not me. I think an OS must use as little of resources as possible and leave the rest for user programs. Imho.
Unless you develop for some embedded device, just take a full page for the stack, come on, it's 2012,
2012 or not, PC still boots in real mode, maximum addressable memory 64k per segments.
there are still gigabytes left.
Very bad and dangerous attitude imho. That creates huge, terribly slow bloated software like Nero (~500Mb as opposite to cdrtools which does exactly the same in 2,5Mb).

Lastly, if you think you cannot deal with 512 bytes of stack during boot, you're the reader who has to do his homework. Good luck with wasting resources.

Cheers
invalid
Member
Member
Posts: 60
Joined: Thu Feb 23, 2012 8:39 am

Re: MBR Relocation

Post by invalid »

turdus wrote:PC still boots in real mode, maximum addressable memory 64k per segments.
Good point. And that is the reasoning I respect, sir! Emotional part of your post was ignored ;)
linguofreak
Member
Member
Posts: 510
Joined: Wed Mar 09, 2011 3:55 am

Re: MBR Relocation

Post by linguofreak »

turdus wrote:2012 or not, PC still boots in real mode, maximum addressable memory 64k per segments.
At the same time, since real mode code nowadays tends to just bootstrap to protected mode and get discarded, you should have plenty of room in the 1st MB to just give your stack a full 64k (not that it's likely to use anywhere near that much).
User avatar
Yoda
Member
Member
Posts: 255
Joined: Tue Mar 09, 2010 8:57 am
Location: Moscow, Russia

Re: MBR Relocation

Post by Yoda »

linguofreak wrote:since real mode code nowadays tends to just bootstrap to protected mode and get discarded, you should have plenty of room in the 1st MB
Since there are many things to do and there is a plenty of complicated file systems, devices and kernel formats, even second stage loader may become too big to fit in 1Mb. So it is not really plenty of room.
Yet Other Developer of Architecture.
OS Boot Tools.
Russian national OSDev forum.
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: MBR Relocation

Post by mark3094 »

Well, I have adjusted my code, and it seems to be working.

I just wanted to drop a line to thank everyone for their input. It is much appreciated.

(PS sorry for the late reply - I flew to Melbourne to spend a few days at Cisco Live)
Post Reply