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