26

A lot of web sites describe how to create a bootable floppy disk using an existing image (via dd). But what about the image makes it bootable?

I'm interested in making my own bootable floppy images for an IBM PC and want to understand the details.

chicks
  • 397
  • 1
  • 4
  • 15
Sydius
  • 2,604
  • 18
  • 37

5 Answers5

50

The notion of a bootable-vs-non-bootable floppy is a little odd. It's worth noting that almost all floppies you're likely to have are actually bootable: it's just that they boot a program that isn't especially useful (it either displays a message saying to insert a system disk, or they execute INT 18h - which runs BASIC if it's installed in ROM, or displays a boot error if it isn't).

In any case, the key to writing a useful bootable disk is to understand what the BIOS does when it boots from floppy (booting from a hard disk is subtly different, and adds a little extra complexity), which is this:

  • First, it loads the first sector (512 bytes) of the first track of the first side (if the disk is double sided) of the disk into memory at 0000:7c00h.
  • In some BIOSs, there may be a check that the last two bytes of the sector are 55h AAh (my tests on compatible machines show that this isn't necessarily true there, but I suspect IBM BIOSs do perform this test based on documents I've read about it), and the BIOS will ignore the disk if this signature isn't present.
  • The BIOS then jumps to 0000:7c00h, which is expected to contain a jump instruction to the actual code (again, some BIOSs may check whether this is present or not before booting it).

In addition to this, most useful boot programs will also include the data structures that are necessary for some file system or other, typically a FAT12 header which occupies the space between bytes 3 and 30.

The rest of the sector is available for the boot program. The DOS boot program simply loads a bunch of sectors from the start of the disk, performs some basic checks to make sure they were loaded correctly, and jumps into them to start the actual OS. Some other boot sectors are smarter; I wrote one back in the 90s that:

  • Checked if the processor in the system was a 386 or higher, giving useful error messages if it wasn't
  • Located and loaded a file by name in the FAT filesystem, thus allowing an OS kernel to be installed without the disk having any special space allocated as is required for DOS.

Writing a boot sector is fun. Good luck. :)

Jules
  • 12,898
  • 2
  • 42
  • 65
  • VBR isn't realy necessary. Only if you want to add some (not only FAT) standard file system. Also, I wouldn't assume the load address. – Raffzahn Dec 27 '17 at 01:38
  • 1
    You were able to write code to navigate a FAT filesystem and load a file... In 512 bytes? – Harper - Reinstate Monica Dec 27 '17 at 19:23
  • 1
    @Harper: It's not that hard. – Joshua Dec 27 '17 at 21:03
  • 9
    @Joshua It's a little hard. Credit where due. You know, the backside of the Dunning-Kruger effect is highly skilled people don't realise how good they are. – Harper - Reinstate Monica Dec 27 '17 at 22:26
  • 1
    @Harper it's not that hard because the BIOS has FAT Disk IO built in, so reading a kernel from the root directory is just a case of making a BIOS call with the name of the file as a parameter. – JeremyP Dec 28 '17 at 08:59
  • @Harper when did what happen? – JeremyP Dec 28 '17 at 09:12
  • 3
    @JeremyP When did they add FAT disk IO to the BIOS? I am quite sure it wasn't there when the XT shipped, it would have made the BIOS fairly large... OP's XT-286 shipped in 1986, would it have been by then? – Harper - Reinstate Monica Dec 28 '17 at 09:18
  • I faintly remember that for a 486, all I had to do was to copy two sys or ini files (don't remember which) from my win95 system folder, and create an autoexec.bat on an empty floppy disk, and it was good to go. I'm absolutely sure I didn't have to care about any sectors or memory spaces. – vsz Dec 28 '17 at 09:20
  • @Harper Apologies, you are right. But reading a FAT file system is really not that difficult. – JeremyP Dec 28 '17 at 09:40
  • 3
    @Harper It's not possible to write code to navigate a FAT filesystem in 512 bytes. That's why there are certain requirements on the layout of the files used to boot. The S attribute on those files tells defragmentation tools not to move those sectors around. – kasperd Dec 28 '17 at 11:11
  • 3
    @JeremyP A modern BIOS might have some FAT code built in, but it would only be used by the BIOS itself not by DOS or other operating systems. When DOS was introduced the BIOS only provided the code for reading and writing disk blocks, the file system driver had to be provided by DOS itself. – kasperd Dec 28 '17 at 11:14
  • @kasperd - Yes, it is. The only requirement I had in my implementation was the file be stored in the root directory: but I also had a machine type check and some reasonably verbose error messages; if I'd removed those requirements I'm pretty sure I could have handled subdirectories too. (Unfortunately, I tried to find my code for this yesterday, but I seem to have lost it since then. Maybe I'll try again at some point). – Jules Dec 28 '17 at 16:25
  • 3
    @Jules I am pretty sure the DOS boot record doesn't parse the FAT. It finds the file in the root directory and assumes the blocks are contiguous such that it can just take the start location from the directory entry and read sequentially from there. – kasperd Dec 28 '17 at 16:32
  • 1
    @kasperd I was under the impression that the first file it loads was actually magical, in the sense of being placed in a fixed location, and the boot sector knew the location rather than having to parse the FAT. The FAT fileentry was just a placeholder to protect that space, as it were. – Harper - Reinstate Monica Dec 28 '17 at 17:22
  • @Harper It's been many years since I looked at the code. As far as I recall it did use the starting position from the directory entry. However I think that having to be contiguous was not the only limitation. I vaguely recall some requirement about those two system files having to not just be in the root directory but having to be the first two directory entries in the root. And maybe the files themselves also needed to be located close to the start of the file system. But those are details I don't recall exactly. – kasperd Dec 28 '17 at 17:43
  • 5
    @Harper I found the code. The code from 7CD7 to 7CEB verifies that the first two entries in the root directory are IO.SYS and MSDOS.SYS so I was right about those having to be the first two entries. The code from 7D05 to 7D10 takes the starting cluster of IO.SYS (from the directory entry) and multiplies by SECTORS_PER_CLUSTER. So it does indeed use the starting location of the IO.SYS file. – kasperd Dec 28 '17 at 18:10
  • 3
    @Harper Looking at the code from 7D32 to 7D35 we see that it simply advances the location on disk before reading the next sector. The iteration counter is initialized to 3 at 7D1D and it is zero based so there will be 4 sectors. So the first 4 sectors of IO.SYS are assumed to be contiguous on disk. Finally at 7D4D it jumps to the sectors it loaded. So if IO.SYS was not contiguous on disk it would end up executing random data as code. – kasperd Dec 28 '17 at 18:15
  • 1
    @kasperd ok, so it's doing a simplified analysis of FAT. IIRC the "must be near the beginning of the filesystem" is applicable to media large enough for the cluster number to overflow the boot sector's code, e.g. Must be in first 252 clusters or something like that. – Harper - Reinstate Monica Dec 28 '17 at 18:40
  • 1
    @Harper It is indeed using some of the FAT file system structures in a very limited way. It does however never load the FAT tables from disk and just assumes the file is contiguous. And it does sound plausible that it could overflow on large file systems if the file is not close to the start. – kasperd Dec 28 '17 at 19:02
  • 2
    I used to have the technical Official Guides with the BIOS source code of the Commodore XT and IBM AT, and indeed they both checked for the 55 AA signature. If you use your google foo, you will find the BIOS source code in a digitised PC Jr Technical manual floating around. – Rui F Ribeiro Jan 05 '18 at 11:28
  • 1
    @RuiFRibeiro IBM was pretty much distributing the BIOS source code left right and center, relying on their copyright to prevent infringement. (That worked out okay, until it was clean-room reverse-engineered.) For example, you can grab the #6025005 August 1981 IBM 5150 Technical Reference which has the assembly source code for the BIOS, complete with comments, in the 82 pages long Appendix A; a PDF copy is available at e.g. https://ibm.retropc.se/manuals.html#IBM and Appendix A starts at that PDF's page 194. I would be surprised if there aren't OCR'd copies floating around, too. – user Jan 07 '18 at 09:44
  • @MichaelKjörling Thanks for the pointers. I used to be very proficient in Z80 and Intel asm and such docs are still useful once in a while. – Rui F Ribeiro Jan 07 '18 at 10:25
  • @MichaelKjörling - "That worked out okay, until it was clean-room reverse-engineered" -- from what I understand, it almost worked out OK despite attempts at clean-room reverse engineering: when the first clone manufacturers started looking for people qualified to write their BIOS implementations, they found it very hard to find anyone who hadn't already read the IBM code... – Jules Jan 07 '18 at 11:35
  • @Harper-ReinstateMonica there are still so many devices in the world that have their complete firmware in a 512, 1024 or 2048 byte ROM.... – rackandboneman Dec 07 '20 at 19:50
  • The 8-Bit Guy's Boot Sector Games video shows a comparison between the "not bootable" messages on DOS and Win95-formatted floppies, if anyone wants to see that. – ssokolow Feb 27 '22 at 13:01
9

what about the image makes it bootable?

The program(s loader) starts at Track 0 Sector 0 of a device

I'm interested in making my own bootable floppy images for an IBM PC

Write the program to be executed (like this minimal one) to Sector 0 Track 0 and press reset.

[I] want to understand the details.

It's that simple. The BIOS looks for a floppy in drive 0, reads the first block and starts whatever is located there.

Wikibooks offers a real nice and easy to follow writeup about how to build a boot sector / bootable program, including an analysis how Linux does it.


Now, if you want to make floppies that also adhere to other standards - for example the FAT file system or the like, then you have to format it according to those specs. Like using a Volume Boot Record and squeezing your program in there. Plus adding a FAT structure and packing further boot stages into files according to that structure - or at least reserved by dummy entries.

But strictly nothing of that is needed when your goal is a bootable disk to do your own stuff. BIOS doesn't care for directories, clusters or assignment. Just Sector 0 on Track 0 and from there on Track/Sector numbers for reading, but that's already the domain of your program.

Toby Speight
  • 1,611
  • 14
  • 31
Raffzahn
  • 222,541
  • 22
  • 631
  • 918
2

Addon, answering an aspect explicitly asked about in the question.

A "dd image" of a complete floppy disk, unless dd is used with special (skip/count) parameters, will always carry the parts that make a floppy disk bootable or not bootable along with it - dd if=/dev/fd0 of=temp ; change floppy to empty one; dd if=temp of=/dev/fd0 will create a bootable copy of a bootable original, unless special techniques (copy protection that works by (mis)using normally non-addressable parts of the media) were used in the original.

rackandboneman
  • 5,710
  • 18
  • 23
1

what about the image makes it bootable?

An operating system "kernel" sitting at track 0 sector 0.

EDIT: if "data", or a program that doesn't have the necessary code to finish booting the system, is at track 0 sector 0, then the BIOS' bootstrap code will throw an error saying that an operating system is not found.

EDIT 2: if it's a fresh or unformatted disk, the BIOS is still going to try and look where it thinks track 0 sector 0 is, not find anything and then throw an error.

RonJohn
  • 708
  • 5
  • 11
  • Welcome to Retrocomputing Stack Exchange. This answer is technically correct but it's a bit minimal. What are the implications of this. Is it possible to omit a Track 0 or even just a Track 0 Sector 0? How can a floppy not be bootable? – wizzwizz4 Dec 27 '17 at 13:38
  • @wizzwizz4 how do you omit track 0? You can not write anything to it, but the magnetic "stuff" will still be there, and the BIOS will still try to read it, even though it's random junk. – RonJohn Dec 27 '17 at 13:46
  • 1
    It's true that the BIOS won't boot a floppy disk that hasn't been formatted yet or otherwise doesn't have a readable first sector (track 0 sector 0). However if that first sector is readable then most BIOSes will execute whatever is there, regardless of whether it contains code or random data. If what it executes isn't code then the computer will likely just crash, freezing up without printing any sort of error message. –  Dec 27 '17 at 16:15
  • @RossRidge and that's why, as part of the "Format A:" process, the format software writes a boot record with some correct code which handles that situation gracefully... – Harper - Reinstate Monica Dec 27 '17 at 19:36
  • @Harper Sure, if you format the disk on an IBM PC or compatible using MS-DOS. If you format it on another kind of computer you might get some code for an entirely different CPU or just some "random" data if it uses the first sector for some other purpose. –  Dec 27 '17 at 19:52
  • @RossRidge Circa 1982, every disk encoding scheme was different, so other platforms couldn't even find a sector start or read the data. Apple, Atari, Commodore, IBM floppy formats were mutually unintelligible even if you had custom software trying to read a cross-format. – Harper - Reinstate Monica Dec 27 '17 at 22:41
  • @Harper: The Apple and Commodore used encodings that were designed to be decoded by a microprocessor, and thus traded off complexity for data rate, rather than a standard MFM encoding that was used twice the data rate but was designed for easy decoding by purpose-designed chips. I'm not sure about the Atari. I'd expect that any machine that used the same off-the-shelf MFM chip as the PC and opted to use a 512-byte sectors size would produce disks whose sectors could be read by the PC BIOS. – supercat Apr 08 '19 at 18:27
1

Short answer: A magic number (0xAA55) being at the end of the first sector on the floppy.

Slightly longer answer: "Booting" means that the first 512 bytes of the floppy are copied to memory (usually at real mode segment 0x0000:0x7C00 or physical address 0x7C00). This is the first sector of the floppy, sector 0. It's also known as the bootsector. The processor then jumps here and starts execution. Some older BIOSes will check that the last 2 bytes of the segment are 0xAA55. This is a magic number.

DD is a tool that is used to write to specific sectors on the disk. It is one of the more preferable tools for accessing raw disks on *nix systems.

EDIT: This is for IBM-PC & compatibles. See this article.

user3840170
  • 23,072
  • 4
  • 91
  • 150
adrian
  • 111
  • 4
  • 1
    BIOSes don't actually check for the AA55 magic number on floppies, especially not old ones. Original PC-DOS 1.x boot discs don't have this signature nor do the Xenix boot floppies I have. –  Dec 28 '17 at 03:47
  • This seems to be an answer about a specific type of bootable floppy. Could you clarify what specific machine this information is from? – wizzwizz4 Dec 28 '17 at 15:26
  • 1
    I had the Commodore XT technical manual with the official BIOS listing, and I can swear the AA55 magic number was there to test for boot validity. – Rui F Ribeiro Jan 05 '18 at 11:34