Page 1 of 1
Chainloading MBR->partition bootstrap question
Posted: Fri Nov 08, 2013 8:08 pm
by mrstobbe
I've been playing with my own bootloader (yes, I know grub exists, but it's an excellent exercise). Everything is clear to me (and I have a couple perfectly working bootstraps at this point) except I had a thought today and couldn't find an answer to it searching the interwebs.
Imaging this is all an extremely generic process... the MBR is written by someone different than whatever bootstrap is in the partition and they never agreed on a standard of passing information. When the first sector is loaded via the bios from the MBR, it has DL to work with and figure out which disk to start poking at. Maybe even stage2's itself. All simple. Now what if that bootsector reallocates and chainloads to another partition? That partition bootstrap still has DL to work with, but how does it know which partition it is. Worse yet, what if it's, by convention, limited to 1 sector for code (think FAT16 or something). It has very precious little space to find the stage2/kernel in the file system. Is there actually a standard in place for this that all major players have agreed upon, or is there a bunch of hacky stuff in the MBR (possibly stage2) that says something like, "if we're chainloading a 'blind' partition bootstrap, take over int 13 and re-calc disk geometries/offsets"?
Thanks.
Re: Chainloading MBR->partition bootstrap question
Posted: Fri Nov 08, 2013 8:19 pm
by tom9876543
MSDOS and Windows9x solved this by putting a "Count of hidden sectors preceding the partition that contains this FAT volume" in the "BIOS Parameter Block".
Re: Chainloading MBR->partition bootstrap question
Posted: Fri Nov 08, 2013 8:27 pm
by mrstobbe
I was wondering what that field was for. What a hack but what are you to do with limited options. Thanks.
Re: Chainloading MBR->partition bootstrap question
Posted: Sat Nov 09, 2013 12:46 am
by egos
Additionally you can use such MBR boot loader that provides extended interface to stage 1. Look
here for example. If stage 1 gets ax=0AA55h then ds(0):si points to traditional partition table entry of boot partition, i.e. you can find start LBA at offset 8.
Re: Chainloading MBR->partition bootstrap question
Posted: Sat Nov 09, 2013 3:11 am
by tom9876543
egos, you missed the entire point of this topic.
What happens if someone installs GRUB or WindowsXP?
Your "Extended interface MBR" gets overwritten and is now completely irrelevant.
A partition can only assume dl = drive number and it is loaded at 0x7C00. Assuming anything else makes it prone to failure whenever another operating system is installed.
Re: Chainloading MBR->partition bootstrap question
Posted: Sat Nov 09, 2013 4:00 am
by egos
tom9876543 wrote:egos, you missed the entire point of this topic.
What happens if someone installs GRUB or WindowsXP?
You answered this question before. Yes, it is used HiddenSectors field of BPB+ (or some similar field). I meant that it's possible to use both approaches in same stage 1.
Re: Chainloading MBR->partition bootstrap question
Posted: Sat Nov 09, 2013 9:13 am
by Owen
If you ignore egos' AX=AA55h extension, every chainloader will invoke the VBR with DS:SI pointing to the MBR entry (or a constructed MBR entry) for the partiton being booted, because every VBR ever written has expected this. The first HDD supporting DOS did this; therefore everybody ever since has done so for compatibility.
A draft of EDD 4.0 (Never published) explains extending this to support GPT. N.B. I recommend ignoring what they say and "faking" an MBR entry for any GPT partition which can be addressed within the limits of the MBR.
Re: Chainloading MBR->partition bootstrap question
Posted: Sat Nov 09, 2013 10:07 am
by tom9876543
Owen,
The link you provided is very interesting. It does specify that DS:SI will point to a partition table for the VBR.
Unfortunately, there is the correct standard, and there is the Microsoft standard.
According to Wikipedia, newer MS operating systems fail to provide the DS:SI information:
http://en.wikipedia.org/wiki/Volume_boot_record
The MBR code of OS/2, MS-DOS (prior to 7.0), PC DOS (up to 7.10), and Windows NT (up to ca. 2007) happens to provide this same interface as well, although these systems do not make use of it. The MBR installed by Windows NT 6.0 (and higher) uses other registers, and is therefore no longer compatible with these extensions.
As Microsoft doesn't properly follow the DS:SI convention, unfortunately it can't be relied on.
Re: Chainloading MBR->partition bootstrap question
Posted: Sat Nov 09, 2013 11:06 am
by egos
Owen wrote:If you ignore egos' AX=AA55h extension, every chainloader will invoke the VBR with DS:SI pointing to the MBR entry (or a constructed MBR entry) for the partiton being booted, because every VBR ever written has expected this. The first HDD supporting DOS did this; therefore everybody ever since has done so for compatibility.
You are right. But it's very unreliable parameter anyway (e.g. ntldr/bootmgr does not pass this parameter when it loads "boot sector" image, BIOS does not pass this parameter when it loads boot sector).
A draft of EDD 4.0 (Never published) explains extending this to support GPT. N.B. I recommend ignoring what they say and "faking" an MBR entry for any GPT partition which can be addressed within the limits of the MBR.
I do not provide "!GPT" extension in my MBR/GPT boot loaders. I use own 64-bit extension instead: dx, ds:si as described
here, ax=0x8855, ds(0):si points to 64-bit descriptor that has two 64-bit fields (start LBA, length).
By the way we should expand HiddenSectors field to use 64-bit addressing.
Re: Chainloading MBR->partition bootstrap question
Posted: Sun Nov 10, 2013 7:49 pm
by mrstobbe
Well, I definitely think that answered my question. Thanks for all the info. Worst case (DS:SI begin invalid) an elegant fatal is still possible after a quick sanity check by the VBR (does DS:SI even make sense? is 0xAA55 within 1 sector of that memory?). Not the best of all worlds, but some assumptions have to be made.
Thanks again.
Re: Chainloading MBR->partition bootstrap question
Posted: Tue Nov 12, 2013 5:28 am
by tom9876543
Hi,
You can design the VBR so that it reads the first 64KB of the partition, no matter where the partition is located (on MBR formatted disk).
The steps are:
1) Read first sector. does it match vbr? If so, VBR Start LBA found ( == 0).
2) Now assume first sector must be a MBR. Read each partition entry and see if it matches the VBR. If so, VBR Start LBA found.
3) Then check all the Extended Partitions. If it matches VBR, VBR Start LBA found.
If VBR Start LBA is not 0xFFFFFFFF, read the sectors into memory.
Otherwise print short error message.
This can be done in 510 bytes.
I would require INT13h extensions are available (if not print short error msg).
Maybe old BIOS call can be added, but I'm not sure if there's enough room.