The El Torito Bootable CD Specification was introduced in the 90's to make it possible to boot a system from a CD. This specification is used till today for bootable ISO images. There are different ways to embed disk images into El Torito ISO images. One way is called hard disk emulation. With this the bootable disk image comes with a DOS/MBR boot record and can be booted by the BIOS/UEFI directly. Unfortunately if you want to boot such an ISO from an USB stick, that won't work out of the box, you need to extract the disk image from the ISO first. This article is about how you can do that easily under Linux.
What again is this good for?
A typical use case are BIOS/UEFI updates under Linux. Such updates often come either packed in Windows executables (which you can't use because you run Linux) or as an ISO image. You could now burn a CD and boot your machine from that in order to update the BIOS. But we don't want to waste resources and use a USB drive instead. That's there the following comes into play. You need to extract the embedded disk image from the ISO image and then flash it to a USB drive in order to boot from it.
Only dd and isoinfo are needed...
There is actually a tool called
geteltorito to extract such images from El Torito ISO images, but you can do the same with
dd. All we need to do is to find out where the bootable disk image actually sits at the ISO. For this we can use the tool
isoinfo which comes with the package
cdrtools (ArchLinux) or
genisoimage (Debian derivates).
Once you have
isoinfo installed, is it as easy as running the following command to get some info regarding the ISO image:
$ isoinfo -i my.iso -dThe output should look similar to that:
Setting input-charset to 'UTF-8' from locale. CD-ROM is in ISO 9660 format System id: Volume id: R0DET96U Volume set id: Publisher id: Data preparer id: Application id: NERO BURNING ROM VER 12,5,5,0 Copyright File id: Abstract File id: Bibliographic File id: Volume set size is: 1 Volume set sequence number is: 1 Logical block size is: 2048 Volume size is: 8374 El Torito VD version 1 found, boot catalog is in sector 20 Joliet with UCS level 3 found. No SUSP/Rock Ridge present Eltorito validation header: Hid 1 Arch 0 (x86) ID 'NERO BURNING ROM VER 12' Cksum D3 22 OK Key 55 AA Eltorito defaultboot header: Bootid 88 (bootable) Boot media 4 (Hard Disk Emulation) Load segment 7C0 Sys type 6 Nsect 1 Bootoff 1B 27
Note the last 7 lines. In this case the ISO embeds one bootable disk image which is located at offset
27 decimal). Now it is important to know that this is not the offset in bytes, but the sector offset. Since the sector size of CD ISO images is 2048 bytes (see also this article), one actually needs to multiply 27 * 2048 to get the right byte offset where the bootable disk image actually resides.
Now we can just use
dd to extract the image by just skipping the first 27 2048 byte sectors.
# dd if=my.iso of=out.img skip=27 bs=2048 8347+0 records in 8347+0 records out 17094656 bytes (17 MB, 16 MiB) copied, 0.0984178 s, 174 MB/s
That's it, the image is now stored in
out.img. You can actually use the
file command in order to verify that this is really a bootable disk image. The
file command should tell us that the image starts with a boot sector:
$ file out.img out.img: DOS/MBR boot sector; partition 1 : ID=0x1, active, start-CHS (0x0,1,1), end-CHS (0xf,63,32), startsector 32, 32736 sectors
...and final flashing.
You can now write the image to your USB flash device and boot from it. Just replace
/dev/sdX with the right block device. Be warned that dd won't ask again when you overwrite the wrong block device! We run
sync after that to make sure any I/O buffers are flushed.
# dd if=test.img of=/dev/sdX bs=2048 # sync