How to make multiboot CD-ROM easily under Unix/Linux

You'll need mkisofs and cdrecord from cdrtools package, hex editor (I use hexedit from FreeBSD ports collection) and maybe DOS utility makebt. I suggest you'll burn CD-RW disk for first time you make multiboot CD.

I wouldn't describe technical information about bootable ISO structure, I'll just tell you what you should do to make CD multibootable.

First you should make single-boot ISO image with mkisofs - for example

mkisofs -b boot/boot.img -c boot/boot.cat -o cdrom.iso /tmp/mycd.

But don't forget to put other boot images in cd directory somewhere. For better convinience, with -b flag use boot image you want to make default. This command tells mkisofs:

So you got an ISO-image, which can be bootable on ATAPI drives. It wouldn't boot on SCSI drives and I don't know why. I'll solve this problem in near future I hope. By the way you can place boot catalog and boot images whereever you like, it doesn't matter where they are. But avoid files having similar names in other directories for better success.

Now you have two ways: use DOS program makebt and let it to make CD multibootable, it can be run even under dos-emulation in unix/linux or you can do it by yourself. Makebt work is not completely correct but it let you burn multiboot CDs however. As for me I use makebt usually, because have two computers: windows and FreeBSD, but I always edit iso-image after it, to make the result correct. Read next chapters accordingly to the way you choose.

Adding boot images manually

So, you choosed to make things manually. From this point I assume you use hexedit as hex-editor, of course you can use anything you like. So, open your iso-image in hex-editor and go directly (F4 in hexedit) at position 0x8800 (sector 17), you'll see Boot Record Volume, it looks something like that:

00008800   00 43 44 30  30 31 01 45  4C 20 54 4F  52 49 54 4F  .CD001.EL TORITO
00008810   20 53 50 45  43 49 46 49  43 41 54 49  4F 4E 00 00   SPECIFICATION..
00008820   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................
00008830   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................
00008840   00 00 00 00  00 00 00 2C  96 01 00 00  00 00 00 00  ................

If you do not see it, something got wrong and CD wouldn't boot anyway ;-). Note Dword at position 0x8847 - here it is 0x01962C (byte order are reversed of course). It is absolute pointer to boot.cat file. boot.cat is everything you need to edit to make CD multibootable. But before you begin to edit it - let's find out where your boot images are located. To do it search forward for name of it in uppercase. For example I have four images: boot.img as default, sys622.img, netbsd.img and freedos.img. So, do not search for image boot.img, because it was used in -b switch of mkisofs and was written in boot catalog already.

So... We search forward for SYS622.IMG first (Tab to go in ASCII mode; Ctrl-S to search). Location of file is Dword beginning 30 bytes before its name (two lines above second letter of file's name):

0001F8C0   42 53 44 31  36 31 2E 49  4D 47 3B 31  2E 00 9D 9E  BSD161.IMG;1....
0001F8D0   01 00 00 01  9E 9D 00 80  16 00 00 16  80 00 67 07  ..............g.
0001F8E0   12 11 34 22  10 00 00 00  01 00 00 01  0C 53 59 53  ..4".........SYS
0001F8F0   36 32 32 2E  49 4D 47 3B  31 00 2E 00  6D A1 01 00  622.IMG;1...m...

So, we read SYS622.IMG location (9D 9E 01 00) and write it down exactly in the form we see it here. Do the same for other boot images you want to be bootable. After it we need to locate boot catalog and edit it accordingly. To do it - you need to compute address where it resides. Earlier we got position 0x01962C - this stands for LBA sector number, sectors in ISO-image are 2048 (2048 = 800 in hex) bytes long, so you need to multiple this numbers. To do it run bc at command prompt and pass these commands:

ibase=16
obase=10
1962C*800

The result you'll get (Note - bc want letters be capital) is number of bytes from ISO-image beginning, in hex (if you want result in decimal omit "obase=10"), so move to this sector and you'll see something like that:

0CB16000   01 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................
0CB16010   00 00 00 00  00 00 00 00  00 00 00 00  AA 55 55 AA  .............UU.
0CB16020   88 02 00 00  00 00 01 00  6D A1 01 00  00 00 00 00  ........m.......
0CB16030   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................

Let me make an little intro in boot catalog. Boot catalog is 2 Kb size file (one sector) containing 32-byte records (two lines in hexedit). First entry you see is Validation entry. It shouldn't be touched. Second entry is Initial/default Entry. It describes boot-image, which would be booted by default, if there are no more entries it is last entry in boot catalog. I assume it is last in your ISO-image boot catalog, because mkisofs can't create multiboot CDs yet :-(. Anyway, if you need to make multibootable CD you should add some entries. First entry you should add is Section Header. It contains a name of disk, but this name would be seen only when booting from SCSI CD-ROM. Example section header is:

0CB16040   91 00 04 00  53 79 73 74  65 6D 20 44  69 73 6B 00  ....System Disk.
0CB16050   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................

First byte - 0x91 tell us it is Section Header and it is last header in catalog, second byte 0x00 means 0x86 architecture, third and forth byte (word) you should fill - it means how many entries follow this header, so if you have 4 boot images it would be 0x03. Rest of entry is name of header - you can either fill it or not.

Last thing - fill boot entries, one by one, after section header. They are similar to Initial/Default Entry.

0CB16020   88 02 00 00  00 00 01 00  9D 9E 01 00  00 00 00 00  ........m.......
0CB16030   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................

First byte should 0x88 - it stands for boot entry, second byte is size of image you want to boot. 0x00 - No Emulation, 0x01 - 1.2 Mb floppy, 0x02 - 1.44 diskette, 0x03 - 2.88 diskette, 0x04 - Hard disk emulation. I would write about "No emulation" and "Hard disk emulation" topics some days. And, also you need to write 4-byte address of image in bytes 8-11 of added entry, you wrote these adresses down before. Look at example.

And you can skip last chapter and burn CD now. Someone can say it is hard way to make multiboot CD, but I know it takes not so much time, when you know what you do, and I beleive there is many situations it is needed very and very much. Feel free to send me comments.

Using makebt

Using makebt is quite simple. Run it and you'd be asked about ISO image you want to edit. After you'll get a screen with 11 strings to fill. Write name of boot catalog (you supplied it in -c option to mkisofs) without path in the line named BC, then fill other lines with names of images to boot (without path) and their appropriate size, mark default boot image and press F1 (if it does nothing press it several times). Makebt would find all of these files inside ISO-image and ask you about name of CD, after that press enter to process ISO-image.

What's wrong with it you'd ask. Makebt understands Boot catalog improperly, it cause CD have one additional boot record. Anyone can live with that, but if you want or need to have explicit number of entries you need to remove one entry from boot catalog. Look at previous chapter to know, how to find Boot catalog, find it in hex-editor and you'll see:

0CB16000   01 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................
0CB16010   00 00 00 00  00 00 00 00  00 00 00 00  AA 55 55 AA  .............UU.
0CB16020   88 02 00 00  00 00 01 00  6D A1 01 00  00 00 00 00  ........m.......
0CB16030   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................
0CB16040   91 00 04 00  53 79 73 74  65 6D 20 44  69 73 6B 00  ....System Disk.
0CB16050   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................
0CB16060   88 02 00 00  00 00 01 00  9D 9E 01 00  00 00 00 00  ................
0CB16070   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................
0CB16080   88 03 00 00  00 00 01 00  FD 98 01 00  00 00 00 00  ................
0CB16090   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................
0CB160A0   88 02 00 00  00 00 01 00  2D 96 01 00  00 00 00 00  ........-.......
0CB160B0   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................
0CB160C0   88 02 00 00  00 00 01 00  6D A1 01 00  00 00 00 00  ........m.......
0CB160D0   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................

Very simple. Boot catalog filled by 32-byte entries (two lines), entries starting with 0x88 is boot entries, you can see LBA address of each boot entry in bold here. First record is default, as you can notice it is duplicated later, so you should remove (fill by zeros) it's duplicate. But if it is not last make sure sections go one by one. One more thing you should do - 0x04 marked bold means four entries after section header, as you deleted one entry after it decrement it. If you want to know more about this, read previous chapter or El Torito specification. And you can burn ISO-image you got after it all.

Postscriptum

Actually, ISO image we got - is not El Torito compliant and it would work improperly on SCSI CD-ROM drives. But on IDE drives it would work as we want it.

Files and links

El Torito Specification by IBM and Phoenix
Makebt utility

© Dima Veselov, 2003.