EMBR: The FYS OS: code named 'Konan'

History:
16 July 2008:
- I created this spec before I found the way Intel's EFI partition table is. I may decide to drop
  this spec and go with the GPT outlined at: http://en.wikipedia.org/wiki/GUID_Partition_Table.
15 June 2008:
- updated the source code (17k) with comments and other modifications.
- added and fixed a few things in the code.
- added a few more items at the last of the boot sector.
10 June 2008:
- error in the jump far instruction. Needed +5 instead of +4. Wonder why no one said anything :-)
- The example code and image here will work on a floppy or a hard drive. Since placing this EMBR on a
    floppy would be an oxymoron, the EMBR code is not required to work on a floppy.
31 July 2007:
- added the first release of the source code.
29 July 2007:
- Deleted the last_booted field from the end of the eMBR's first sector, offset 0x1F6.
  The last booted entry can be found by reading the dates in the entries themselves.
- Added information about the base LBA field.
28 July 2007: Initial release

This is my small attempt at a thing I call, "extended master boot record". This is not a specification, this is just an attempt at something I thought of a while back and have started to implement it to see if it will work to my specifications and desires. Your comments are welcome at fys [pigtail] frontiernet [dot] net

Since the traditional style of a partition entry in the Master Boot Record (MBR) allowed for only eight bits of identification, this soon became unusable due to many different File Systems and uses. When multiboot programs started to appear, there was little or no way of displaying what kind of filesystem and Operating System was on that partition.

I thought I would try something that would give a lot more information about the FS and OS occupied by the partition. I call it the Enhanced MBR.

To allow compatibility with other software, there should still be a traditional MBR, further specified as just MBR, on the first sector of the disk, with one of the partition entries pointing to a sector that contains our EMBR, with the other three entries typically marked empty, but not required to. This traditional MBR is not required, though if you want to be able to boot OS's that don't know about the EMBR, they will need the initial MBR.

Then our EMBR will start with code that would load the remaining sectors needed from the sector just after the one pointed to by the MBR, move itself away from 0x07C00, parse the EMBR entries, display their information, ask for an entry to boot, then boot it. If the user did not enter a value after so many seconds, the code should boot the last booted entry or the first entry if none marked as last booted.

To be able to know how many more sectors to load, we need a field in the first sector of our EMBR code to define the remaining count of sectors to load. Since this is a boot partition pointed to be a MBR partition entry, we should also set the last word in the first sector to 0xAA55. With this in mind, use the few bytes before the 0xAA55 signature to store this remaining sectors to load count along with a few other items as described here:

  offset 0x1EA 8 bytes - 'FYSOSMBR'    // signature for identifying this MBR as a EMBR
         0x1F2    word - sector offset to first entry sector
         0x1F4   qword - base LBA of this EMBR first sector on disk
         0x1FC    word - count of remaining sectors to load into memory following this sector
         0x1FE    word - 0xAA55
There are numerous ways to figure the base address. One could hard code the value when the eMBR was written to the drive. However, this may cause problems if you ever decide to move the eMBR. I have decided that since the main MBR, whether it be this eMBR or not, will *always* reside on LBA 0, and will read the base LBA from the partition entry(s), we will let it pass this value in the bx:ax:di:si register set. To verify that the value in this pair is correct, the newly loaded eMBR can check the value in the cx register. If it contains 0x2222, then it can assume the 32-bit value in the bx:ax:di:si register pair is the base lba of this eMBR. For a FYSOS bootable partition, I also send the base address of the newly loaded partition to itself in the same way.
Note: Why use 16-bit registers and not 32-bit? All my boot code, as well as many others, don't assume a 32-bit machine until the loader or kernel. I guess it is probably time to assume that your code will never be run on a machine less than a 386, but who is going to make that judgement call?

All in all, this is actually the same thing that a Traditional MBR does, minus the display and user prompt. However, now the user has quite a bit more information about the partitions occupant, both FS and OS, through a human readable description string and a software usable id value.

Where is this information stored? The code can take as much space as needed, while the EMBR entries fall on the next sector-aligned address after the code. Each of these sectors contains a 32 byte header followed by up to four EMBR entries.

Now for the description of the sectors after our code, please note that I am using NBASM struct syntax:
The Header (32 bytes):

S_EMBR     struct
  sig0                dword  ; 'EMBR'
  entry_count          word  ; total entries in EMBR (reserved in all but first sector)
  crc                  word  ; crc of this sector
  boot_delay           byte  ; seconds to delay before booting last booted (reserved in all but first sector)
  resv1               dup 19 ;
  sig1                dword  ; 'RBME'
S_EMBR      ends
The two sig dwords are to make sure that this actually is a valid header. Sig0 should be written as 'EMBR' with the 'E' at offset zero, the 'M' at offset one, the 'B' at offset two, and the 'R' at offset three. If you write it as a dword, as specified above, make sure that the 'E' is the low order byte and the 'R' is the high order byte. The sig1 field is just the opposite.

The entry_count field is the count of total entries in this sector and any remaining sectors read previously. The crc field is the 2's compliment of the word sum of all 16-bit words in this sector only. i.e.: when the crc value is calculated correctly, and included in the 16-bit sum off all words in this 512 byte sector, the sum will be zero. The resv1 field should contain zeros. The boot_delay field is how many seconds to wait before booting the last booted entry if no user intervention is seen.

Please note that each sector has this 32-byte header with up to four EMBR entries after it. Therefore, the first sector of the EMBR entries has a valid entry_count field, while any remaining sectors should have this field set to zero.

Now the EMBR entries:
S_EMBR_ENTRY struct
  valid                byte  ;
  starting_sector     qword  ;
  sector_count        qword  ;
  description         dup 64 ;
  date_created        qword  ;
  date_last_booted    qword  ;
  OS_signature        qword  ;
  reserved            dup 15 ;
S_EMBR_ENTRY ends
The valid field is simply a TRUE (1) or FALSE (0) value to denote if this field should be included in the menu for booting. If this value is FALSE, this doesn't mean that the data stored in the entry is invalid. It just states that this entry should not be included in the boot menu. Since this entry could still be valid, you should not overwrite it if you add a partition to this table unless you can validate all available space on the drive. The starting_sector field is the zero based LBA sector of the first sector of this partition from the absolute start of the disk. The sector_count is the count in sectors of this partition. i.e.: The count of sectors this partition occupies. This value may not necessarily include any sectors before the next partition. Do not rely on the assumption that starting_sector + sector_count points to the next partition on the disk.
The description field is a 64 byte null terminated 8 bit char human readable string describing the OS and/or FS on this partition and its use. This string must be null terminated, which leaves 63 bytes for characters. I think that I may change this to UTF8 in the near future. The date_created and date_last_booted fields contain the seconds since 1 Jan 1980 when this partition was created and last booted respectively. Please note that the date_last_booted field should be updated just before you pass control to its' partition boot sector you have already loaded.
The OS_signature field is a 64-bit value designed to specify what OS and FS is on this partition. This field is not required but is recommended and has the following recommended format:
  bits 63:48  - OS signature  (FYSOS = 0x2B2B)
  bits 47:32  - FS signature  (FYSFS = 0xB2B2)
  bits 31:16  - partition usage.  OS/FS specific/defined
  bits 15: 0  - 16-bit OS specified value pertaining to partition order/cleanup
This field, along with all other fields in these descriptions, are in little-endian format. LSB written first. The remaining field should be written as zeros.

Remember that there can be up to four entries per sector and the last sector does not require each entry to be occupied. The first sectors headers' entry_count specifies how many entries there are with the last sector containing entry_count % 4 entries if entry_count % 4 is greater than zero.

It is recommended that you set the remaining field in the first sectors data block to a few more sectors than needed. i.e.: set the remaining to a number of sectors more than the S_EMBR->entry_count field needs. This way one can add a partition or two with out having to worry about a partition being in the way just after the EMBR.

Again, this is just something that I was thinking of a while back. I may implement it in fysos, I may not.

I have written some code and created a 1.44meg image to try it on. There are 10 dummy entries in the list with different values for each. It needs some more work for sure, but if you would like to try it out you may get the image from here (only 17k).

Again, this code is for a 1.44meg floppy image for the ease of testing. You will need to add your own code to drop the floppy access and add the hard drive access.

If you have any questions or comments, please let me know at fys [pigtail] frontiernet [dot] net

Thanks,
Ben




All rights reserved
Legal Notice
Copyright © 1984-2008 Forever Young Software
Forever Young Software for Hire
Return to My Home Page