alt.os.development: Boot Sector Size Competition

Recently, in conversation with a fellow aod group user, I caught interest in a subject
he was discussing, Boot Sector size optimization.

For those of you who remember a few years ago, the Hugi Compo competition was in full swing.  The task was to create, with the least amount of x86 instruction bytes, a program that would accomplish a given task.

It always amazed me of the techniques used to create a task in much smaller sized code as I could ever imagine using.

Now, with this aod's users help, (Hi Rod), I have come up with a new competition to see if it will bring interest back to the idea.

This time, and due to the fact that it came from the alt.os.development news group, is to create a boot sector in the least amount of bytes to find and load a 2nd stage loader file.

Please see the following rules for more.

02 November 2014: At this time, it is in the rough draft stage.  If you have any comments, changes, or additions, please post them at alt.os.development.  If you do not have access to this newsgroup, you may either go to Google Groups or send those comment to me at the email address listed below, and I will post them for everyone else to see.

03 November 2014: Here(181k) is the source code to a test suite.  It includes a 15Meg image file, 4 partitions files, source code, Windows Executable (though the source is in C), directions, a readme.txt file, etc.  If there is never any interest in this compo, this utility is still a good test for your boot code.

20 November 2014: Added a few more rules, starting with BH.

31 December 2014: Compo is over.  Here are the results.

Final Results:

Place Handle, name or group Country Size in bytes Last update
1 wolfgang 281 28 Dec 2014
N/A Sniper USA 296* 22 Nov 2014
* Entry does not count since I host the compo and can "cheat" by seeing others' entries, even though I don't :-)


                      alt.os.development -- compo

Release version 1.0 (20 Nov 2014)

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Overview:

To create a boot sector, occupying no more than the first 512 bytes of
the disk, to find, load, then execute  a specified loader  file, while
completing specified  tasks within this code, as well as following the
rules given.

There are tasks required or specific formats used that  may or may not
be a necessary part of an accomplished first stage boot loader, though
for this compo  these are tasks or formats  that are included  to make
for a more excitable optimizing opportunity.

To make the task of testing your entry more feasible for the host, the
"media" used will  be a 15 megabyte hard drive image.  This image will 
be available for download via this web-site (see below).   Within this
image there will be four occupied partitions, each containing multiple
files with one of these files a loader file, in which you must extract
from the file system, place  at a set memory position and then jump to
this position with specified values already loaded into the processors
registers.

The four partitions will have either a FAT12 or a FAT16 formatted file
system already formatted and filled with these files.  It will be your
job to write a boot sector that will check  to see which  partition is
set as  the active partition, then using that partition, find and load
the loader file.


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
The Task:

Using only  the first 446 bytes of  the first sector of a ten megabyte
hard disk image, following the rules listed below,  your entry must do
the following:

0) Using the partition table entries located at offset 446 within this
   first sector, find the active partition.
1) Using the information in this  active partition entry, load as many
   or as few  sectors as you wish to successfully find the loader file
   from this partition's file system.
2) Once found, load this loader file to physical offset 0x30000.
3) Set the systems registers to the following values:
     eax: LBA of partition's base
     ebx: 01020304h
     ecx: DEADBEEFh
     edx: 000000xxh  ; the DL value given at time of boot
     esi: 00000000h
     edi: 00000000h
      cs: 00003000h
      ip: xxxx0000h
      ds: xxxx3000h
      ss: xxxx3000h
      sp: xxxxFFFEh
   all other registers are undefined
4) Since in the above  task, you must set  the cs:ip register  pair to 
   physical address 0x30000, you may do this with a  far jump or a far
   ret, in doing so executing the loader file.
5) That is all.  There is no more to do  than to simply  find and load
   the loader file  from the disk and 'execute' it, i.e.: pass control
   to it.  However, you must follow the rules specified below.
6) I will copy your boot sector, the first 446 bytes, to the first LBA
   of the 15 megabyte image.  Therefore, you  have only 446  bytes  to
   accomplish this task.
7) You may send an entry file size of more than 446 bytes, though only
   the first 446 bytes will be copied.
8) If you wish for any remaining bytes, within these 446, to be set to
   zero, you must set them yourself by padding your entry to 446 bytes.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Rules:
 A) You MAY assume  that the first 446 bytes of  the image file given,
    starting at offset zero, is filled with zeros, though they will be
    over written by your 446 byte entry.
 B) You MAY assume that the image  file given, starting at byte offset 
    446 is formatted correctly.
 C) You MAY NOT assume that one particular partition entry will be the
    active partition each time your entry is tested.
 D) You MAY assume that at least one partition entry  will be  active,
    and that that entry will be completely valid in format and use.
 E) You MAY assume that the partition  entries start at offset 446 and
    there are four entries within the table.
 F) You MAY assume there is a Boot Sector Signature at offset 510, and
    that signature is two bytes of 55h and AAh, with the 55h at offset
    510 and the AAh at offset 511.
 G) You MAY assume the file system on each partition is valid.
 H) You MAY assume that the loader file is within the root directory.
 I) You MAY NOT assume  the loader file will be in  the same position,
    root directory sequence or LBA, each time your entry is tested.
 J) You MAY assume that the file  system occupying the four partitions
    is either FAT12 or FAT16, but must check for one or the other.
 K) You MAY NOT assume that each partition will  contain the same file
    system each time your entry is ran.
 L) You MAY assume  the loader file has the  file name of 'loader.sys'
    specified in the file system as 'LOADER  SYS'.
 M) You MAY assume there are no LFN entries used on the file system.
 N) You MUST assume that the  partitions are out of  range for the CHS
    services of the BIOS, therefore using  BIOS interrupt 13h, service
    42h.  You MUST NOT assume any specific CHS values in the partition
    entry(s), even though they may be correct, you MUST NOT assume so.
 O) You MAY NOT assume the Extended BIOS  Disk Services are available,
    and MUST check  for them.   If they  are not available, your entry
    must print exactly (without quotes):
       "No Disk Services Available."
    and freeze by jumping to the same jump indefinately.  i.e.: 
       here: jmp short here
    You MUST check both the carry  flag and the  BX register on return
    from service 41h.  You do not have to check the version returned.
    You MUST use  BIOS service 0x0E to send a character to the screen,
    and you MUST set the BX register to zero when calling this servce.
 P) You MAY assume that the base LBA for each partition is  within the
    15 megabyte image.
 Q) You MAY NOT assume where each partition will be other than it will
    not be LBA 0, and that each will be large enough to  hold the file
    system given.
 R) You MAY NOT assume specific sizes of each partition each time your
    entry is tested.
 S) You MAY assume there is a  valid BPB in the  first sector  of each
    partition.
 T) You MAY NOT assume there are two FATs in a partition's file system,
    though you MAY assume there will be at least one and  no more than
    two. You MAY assume that the first FAT is valid.
 U) You MAY NOT assume a set cluster size. The Cluster size may be one
    of the following sectors per cluster size: 1, 2, 4, or 8.
 V) You MAY NOT assume that the BPB:Resv_Sectors field is one (1).
 W) You MAY assume there are no directories within each partition.
 X) You MUST NOT assume the count of files  within each partition, nor
    the value of BPB:Root_entries to be the same for each partition.
 Y) You MAY NOT modify any value within the BPB.
 Z) You MUST NOT assume the image file will be set to exactly 15-megs.
    This image file may be larger due  to cylinder boundaries, but you
    MAY assume it will be at least (15 x 1024 x 1024) bytes in size.
AA) You MAY assume the processor is a 386 using 32-bit registers.  You
    are not required to  use 32-bit registers, an MAY assume the high-
    order 16-bits of each register is not used, OTHER than the setting
    of these registers in 3) above.
AB) You MAY assume the processor is running in true real mode.
AC) You MAY assume the register values at initial boot time are:
    edx = xxxxxxDL = drive number
    all other registers MUST NOT be assumed as any specific value.
AD) You MAY assume there is a valid stack at SS:(E)SP.
AE) You MUST create a new stack location before you use a stack with a
    size of more than (four) 4 bytes. (This allows for an initial push
    of at most two 16-bit registers or one 32-bit register.)
AF) You MUST create this new stack before you call a BIOS service.
AG) You MAY NOT assume the cs:(e)ip register pair is 07C0:0000, though
    you MAY assume  the pair when combined, point to  physical address
    0x07C00.
AH) You MAY NOT call any BIOS service other than  service Int 10h/0Eh,
    Int13h/41h, and Int13h/42h. (Character write, check  for BIOS Disk
    Extensions, and Disk Read)
AI) You MAY use any other memory after 0x07DFF until a physical offset 
    of 0x9FC00. You MAY NOT use any memory before a physical offset of
    0x07C00, including reading any of this lower memory.
BA) You MAY NOT assume that each partition's start will align on a cyl
    boundry. A partition may start at any sector within the disk image.
    A partition will not overlap another partition.
BB) The four partition files, PART?.IMG, MUST remain unmodified within
    all tests.  These unmodified partition files will be used for each
    test by the host, possibly ran numerous times through the BOOTTEST
    app.
BC) You MAY NOT assume the size of the loader.sys file.
BD) You MAY NOT assume that the  next partition starts right after the 
    previous partition.  You MAY NOT assume anything about the sectors
    in-between partitions.
BE) You MAY NOT assume the 'loader.sys' file is not fragmented or that
    it only takes one cluster. You MUST check for the 'end of cluster'
    flag.
BF) You MAY use the 5th byte of the FS_TYPE field in the BS/BPB to see
    what file system to mount.  Check for a '2' or a '6'.
BG) You MUST check for the EOF flag in the FAT to see if the there are
    any more FAT entries.  You MAY NOT assume the 'loader.sys' file is 
    cluster_size bytes or less.
BH) You MUST NOT assume BIOS drive number will be 0x80, though you may
    assume it will be greater than or equal to 0x80.
BI) You MAY NOT assume anything about the register values on  entry to
    your code, INCLUDING the  direction bit.  i.e.: 'cld' must be used
    if you use a 'movs' or similar instruction.


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Comments:
As you may have noticed, there are many constraints  and oddities with
 these rules as it would pertain to an actual boot sector.  This is by
 design.  This  task is not to simply write a  boot sector, but to see
 if a boot sector can be written to accomplish all of the tasks above,
 with the rules listed, within a 446-byte block of code.

There may be rules that just seem to be  unnecessary, such as the last
 part of IA), where you may not access any memory below 0x07C00.  This
 is to help keep the playing ground clean.  Someone may  find a way to
 "cheat" and read or write to BIOS memory, or make a call from the IVT.

The process I will use to test your entry will be to execute a utility
 to randomly create the four partitions, placing the file systems with-
 in these partitions, and randomly marking an active partition. Then I
 will copy the first 446 bytes of your entry file to the first part of
 this 15meg image. I will then emulate the booting of this image using
 an emulator of my choice.  The choice of emulator MUST NOT be assumed.
 I will include this utility with this compo so that you may test your
 entry as I will test it.

The 2nd stage boot loader code, 'loader.sys', will simply write a char
string to  the screen indicating which  test partition it was actually
loaded from.  This will give  you a visual  indication of whether your
entry passes the initial tests.

Send your entry.bin file along with its source code to me at:

          ------->> fys [at] fysnet [dot] net <<-------

Please do not include your 15 megabyte image file. I only want the 446-
byte binary file and any source files needed to create this boot image.

To score each entry's size, you send me your smallest entry, hopefully
less  than 446 bytes.  I will pad it  to 446 bytes with a random value.
As mentioned before, if you need your entry end padded with null bytes, 
you must do it yourself, and this must be included as the size of your
entry.  In other words, I will take the size of your 'entry.bin' file,
pad it to 446 bytes, then when it passes the tests I will then use the
initial size of the 'entry.bin' file as the size to post as a score.

The deadline is the 31 of December 2014 at the  stroke of midnight MST.
You may submit entries as often as you  like up until the deadline. In 
fact you're encouraged to do so to add excitement to the compo.

Please note: Even if your entry passes the automatic tests, it doesn't
necessarily mean that it is completely valid. It is up to  you to make
sure that it meets all of the rules.

After the deadline, each entry will be released to the  group to allow
for them to be looked over to check their validity. Five bytes will be
added to any entry's score for each violation found plus the number of
bytes needed to correct it.

If you have any questions or comments, please feel free to post them at:
 alt.os.development

Have fun!
Ben