There is little to no actual documentation on the requirements or restrictions of extended partitions in a Legacy BIOS type MBR partitioning system. For example, the MBR at LBA 0 has up to four (4) partition entries, all four of them could be used.
When disks started to get a little larger, manufacturers started adding a partition type of 05, and then later 15, indicating an extended partition entry. This entry simply pointed to a sector, relative to the parent sector the entry is contained in, to another sector holding four (4) more entries.
Since we all know how this works, I won't get in to it too much. However, my concern is, what are the restrictions on how many of these entries can be used?
For example, a well known name-brand software company states that if an extended partition is used, there should only be two entries used in the MBR, one for a standard partition, and one as an extended partition type. Then one or more of the paritition entries of the extended partition may be used. However, if one of these new entries is an extended partition entry, it must again be one of the only two entries including a standard partition type. Also, any extended partition is actually embedded within a parent extended partition.
Is this a requirement, a restriction, or simply the way some guy chose to do it, and all the rest of us followed?
The only reasoning I can see to do it this way is that each extended partition's base LBA is relative to the partition table sector it resides in. Since all LBA's are 32-bits in these partition tables, with this technique of relativity, you can have disks larger than 32-bit sector counts as long as the software parsing them can handle more than 32 bits. As for extended partitions being embedded within their parent, this could be to protect them from code that doesn't recognize extended partitions.
However, what about all the rest of the entries? Can any entry be used, and if so, can any entry point to any number of extended partitions, nested as deep as you wish?
I say, yes. Absolutely. Therefore, my MBR code is able to parse up to 127 nested partition tables, and only the limit of 127 due to the fact that 128 * 512 = 65536, the 16-bit segment barrier.
So how do you test your MBR code and nested partition table entries? Well, you make an image with numerous tables and run it and see.
I created a small app that will create numerous partitions, each a single sector in size, and allow extended partitions, each also a single sector in size. Then I placed some code at each normal partition to print which partition is was when booted. Then I can easily add and removed partition entries, extended partition entries, and nested extended partition entries, marking any entry as active.
Here is a small image, again only about 10 sectors in size, with numerous entries and up to three (3) total nested extended partitions, and the source code to create the image. The partitions are hard coded in the source code itself, but with a little studying of the code, you can add and/or change the partitions as you see fit. I only have each partition a single sector in size because there is no need to have anything more when simply testing a MBR code.
The app will place your given mbr.bin file at the first of the image, then add specified regular and then extended partitions. If you run the app as is with your MBR.BIN file, then boot it, you should have "Loaded VBR at lba 7" printed to the screen. LBA 7 is actually in the MBR entry table, but your code might parse any extended partitions first. If your code prints any other LBA, prints anything else, or doesn't print anything at all, you might want to check your code.
Which reminds me, who says which entries should be checked for active first? Any in the MBR table first, then extended partitions, or should you take the first partition nest and go until you finally come back to the MBR without finding any active partitions until now?
One more thing, the code doesn't create valid partition table entries other than the BI, SI, and Base Sector fields, the only three fields needed by a MBR to parse them. However, if your code needs the other entries, Starting/Ending CHS entries, etc., you can easily add them.