Hi,
For fun; here's an analysis of my floppy boot loader's first sector. Note that my floppy boot loader is many sectors (currently about 20 KiB).
First, a hexdump:
Code: Select all
00000000 eb 22 00 00 00 00 00 00 00 00 00 00 02 01 40 0b |."............@.|
00000010 00 00 00 40 0b 00 00 00 12 00 02 00 40 0b 00 00 |...@........@...|
00000020 40 0b 00 00 31 c0 8e c0 8e d8 fa 8e d0 bc 00 20 |@...1.......... |
00000030 fb fc be 00 7c 89 e7 b9 00 01 f3 a5 ea 41 20 00 |....|........A .|
00000040 00 88 16 12 20 b4 1a f9 cd 10 3c 1a 75 34 c6 06 |.... .....<.u4..|
00000050 10 20 01 b8 00 1b 31 db bf 00 22 cd 10 3c 1b 75 |. ....1..."..<.u|
00000060 12 81 7d 04 03 50 75 0b 8a 45 22 3c 19 74 09 3c |..}..Pu..E"<.t.<|
00000070 18 74 05 b8 03 00 cd 10 30 ff b4 0f cd 10 88 3e |.t......0......>|
00000080 11 20 be c2 21 e8 c8 00 b9 02 00 30 f6 bb 00 22 |. ..!......0..."|
00000090 e8 fd 00 73 0d 38 36 0a 20 74 4b fe c6 e8 f0 00 |...s.86. tK.....|
000000a0 72 44 b8 00 bb cd 1a 85 c0 74 03 e9 ba 02 81 fb |rD.......t......|
000000b0 54 43 74 03 e9 b1 02 81 f9 02 01 73 03 e9 a8 02 |TCt........s....|
000000c0 66 31 c3 66 81 fb 54 43 50 41 0f 85 9a 02 bf 68 |f1.f..TCPA.....h|
000000d0 23 66 31 c9 66 31 d2 66 31 f6 b5 02 b2 09 b8 07 |#f1.f1.f1.......|
000000e0 bb cd 1a e9 88 02 be f0 21 eb 7d 3c 01 74 55 3c |........!.}<.tU<|
000000f0 03 74 57 50 53 51 52 56 57 55 8a 3e 11 20 3c 0a |.tWPSQRVWU.>. <.|
00000100 74 2c 3c 20 74 2e 3c 09 74 2a b4 09 b9 01 00 8a |t,< t.<.t*......|
00000110 1e fd 21 cd 10 b4 03 8a 3e 11 20 cd 10 fe c2 80 |..!.....>. .....|
00000120 fa 50 74 0a b4 02 8a 3e 11 20 cd 10 eb 0e b4 0e |.Pt....>. ......|
00000130 cd 10 b0 0d b4 0e 8a 3e 11 20 cd 10 5d 5f 5e 5a |.......>. ..]_^Z|
00000140 59 5b 58 c3 c6 06 fd 21 0f c3 c6 06 fd 21 07 c3 |Y[X....!.....!..|
00000150 80 3e 10 20 00 75 01 c3 50 56 fc eb 03 e8 8b ff |.>. .u..PV......|
00000160 ac 84 c0 75 f8 5e 58 c3 e8 e5 ff be df 21 e8 df |...u.^X......!..|
00000170 ff b0 b6 fa e6 43 eb 00 eb 00 b0 d1 e6 42 eb 00 |.....C.......B..|
00000180 eb 00 b0 11 e6 42 fb e4 61 0c 03 e6 61 f4 eb fd |.....B..a...a...|
00000190 31 c0 a2 13 20 8e c0 8a 16 12 20 53 51 52 b8 01 |1... ..... SQR..|
000001a0 02 fe 06 13 20 cd 13 73 15 80 3e 13 20 03 73 0d |.... ..s..>. .s.|
000001b0 30 e4 8a 16 12 20 cd 13 5a 59 5b eb de f9 5a 59 |0.... ..ZY[...ZY|
000001c0 5b c3 0a 01 42 43 4f 53 20 46 6c 6f 70 70 79 20 |[...BCOS Floppy |
000001d0 42 6f 6f 74 20 4c 6f 61 64 65 72 03 0a 0a 00 0a |Boot Loader.....|
000001e0 0a 01 42 6f 6f 74 20 61 62 6f 72 74 65 64 2e 00 |..Boot aborted..|
000001f0 0a 44 69 73 6b 20 65 72 72 6f 72 2e 00 07 55 aa |.Disk error...U.|
This is just a "JMP" because the BPB is in the way.
Code: Select all
00000000 00 00 00 00 00 00 00 00 00
These are "special" variables (e.g. "starting LBA of Boot Image") that are set by my utility that creates floppy images.
Code: Select all
00000000 00 02 01 40 0b
00000010 00 00 00 40 0b 00 00 00 12 00 02 00 40 0b 00 00
00000020 40 0b 00 00
This is the BPB. I use some fields (e.g. "sectors per track") which are also set by my utility that creates floppy images.
Code: Select all
00000020 31 c0 8e c0 8e d8 fa 8e d0 bc 00 20
00000030 fb fc
Code to setup initial segment registers and stack.
Code: Select all
00000030 be 00 7c 89 e7 b9 00 01 f3 a5 ea 41 20 00
00000040 00
Code to copy the boot sector from 0x7C00 to 0x2000 and jump to the copy.
Code: Select all
00000040 88 16 12 20 b4 1a f9 cd 10 3c 1a 75 34 c6 06
00000050 10 20 01 b8 00 1b 31 db bf 00 22 cd 10 3c 1b 75
00000060 12 81 7d 04 03 50 75 0b 8a 45 22 3c 19 74 09 3c
00000070 18 74 05 b8 03 00 cd 10 30 ff b4 0f cd 10 88 3e
00000080 11 20
Code to check if a video card exists, check if the video mode is 80*25 text mode, and set 80*25 text mode if necessary. This is mostly to ensure that any error messages that are display are actually visible.
Code to print the "BCOS Floppy Boot Loader" string (so that if something goes wrong the user at least knows the boot sector started).
Code: Select all
00000080 b9 02 00 30 f6 bb 00 22
00000090 e8 fd 00 73 0d 38 36 0a 20 74 4b fe c6 e8 f0 00
000000a0 72
Code to load the next sector of the boot loader (which mostly just calls a lower level "load sectors with retries" wrapper). Note that I support "redundant floppies". Essentially, if my "floppy image creator" utility decided there's enough space for redundancy it stores 2 copies of everything on the disk. If this code can't read the next sector, and if the "redundant floppy" flag is set, it tries to get the same data from the alternative copy.
Code: Select all
000000a0 b8 00 bb cd 1a 85 c0 74 03 e9 ba 02 81 fb
000000b0 54 43 74 03 e9 b1 02 81 f9 02 01 73 03 e9 a8 02
000000c0 66 31 c3 66 81 fb 54 43 50 41 0f 85 9a 02 bf 68
000000d0 23 66 31 c9 66 31 d2 66 31 f6 b5 02 b2 09 b8 07
000000e0 bb cd 1a
This code checks if "Trusted Computing Group" functions are present and (if they are) uses it to get TPM chip to extend a platform key with a hash of the sector that was loaded. I do this mostly for "remote attestation" - so that other computers will be able to tell if the computer being booted has been tampered with (which is a little more important for me because the OS is intended for a distributed cluster).
A jump to the code in the second sector.
Code to print "disk error" and abort boot if the second sector couldn't be loaded.
Code: Select all
000000e0 3c 01 74 55 3c
000000f0 03 74 57 50 53 51 52 56 57 55 8a 3e 11 20 3c 0a
00000100 74 2c 3c 20 74 2e 3c 09 74 2a b4 09 b9 01 00 8a
00000110 1e fd 21 cd 10 b4 03 8a 3e 11 20 cd 10 fe c2 80
00000120 fa 50 74 0a b4 02 8a 3e 11 20 cd 10 eb 0e b4 0e
00000130 cd 10 b0 0d b4 0e 8a 3e 11 20 cd 10 5d 5f 5e 5a
00000140 59 5b 58 c3 c6 06 fd 21 0f c3 c6 06 fd 21 07 c3
00000150 80 3e 10 20 00 75 01 c3 50 56 fc eb 03 e8 8b ff
00000160 ac 84 c0 75 f8 5e 58 c3
This is my "print character" routine and "print ASCIIZ string" routine. It's mostly a wrapper around the BIOS "print character" function; except it handles a few special characters (to switch between "highlight" and "normal" mode) and expands "\n" into "\r\n". It also doesn't bother printing anything if earlier code didn't detect that a video card is present. It's a little excessive for the boot sector alone, but this is used by later code too.
Code: Select all
00000160 e8 e5 ff be df 21 e8 df
00000170 ff b0 b6 fa e6 43 eb 00 eb 00 b0 d1 e6 42 eb 00
00000180 eb 00 b0 11 e6 42 fb e4 61 0c 03 e6 61 f4 eb fd
This is code to abort boot. For computers that don't have a video card (e.g. server rooms) my OS uses a "continuous beep" for failures that occur during early boot, and "repeated short beeps" for things that go wrong later in boot. This code mostly displays a "boot aborted" error message and then configures the PC speaker for that "continuous beep" before doing HLT in a loop waiting for user to reset the computer.
Code: Select all
00000190 31 c0 a2 13 20 8e c0 8a 16 12 20 53 51 52 b8 01
000001a0 02 fe 06 13 20 cd 13 73 15 80 3e 13 20 03 73 0d
000001b0 30 e4 8a 16 12 20 cd 13 5a 59 5b eb de f9 5a 59
000001c0 5b c3
This is the low level "read sectors" wrapper. It's a fairly standard "retry several times and reset disk system after each failure" thing.
Code: Select all
000001c0 0a 01 42 43 4f 53 20 46 6c 6f 70 70 79 20 |[...BCOS Floppy |
000001d0 42 6f 6f 74 20 4c 6f 61 64 65 72 03 0a 0a 00 0a |Boot Loader.....|
000001e0 0a 01 42 6f 6f 74 20 61 62 6f 72 74 65 64 2e 00 |..Boot aborted..|
000001f0 0a 44 69 73 6b 20 65 72 72 6f 72 2e 00 07 55 aa |.Disk error...U.|
This is all just data. Note that there's only one pathetic "Disk error" string for read errors (I simply don't have room for anything good unless I sacrifice something else to make room).
The boot loader's second sector contains a better "load sectors" wrapper that handles LBA and redundant floppies properly; and also does much better error messages (literally, a different error string for each possible error the BIOS could return). It relies on routines in the first sector for printing things and aborting boot. It loads the third sector, does the "diddle with TPM for remote attestation" stuff, and jumps to code in the third sector.
The third sector loads the rest of the boot loader and diddles with TPM again (using routines in the first and second sectors for disk, printing and aborting boot). Once that's done the boot loader can start doing useful things.
Basically it's a painful "pull yourself up by your bootstraps" sequence that takes almost 3 carefully planned sectors just to get the boot loader into memory.
Cheers,
Brendan