Bootable USB in linux with freeDOS

Bootable USB stick is very handy and it seems to easy to create using dedicated applications both under Linus or M$ but let’s set the challenge and try to make it manually from the bare Linux command like. This knowledge may become very helpful in Data Centrer scenarios  where servers BIOS need to be updated but no Windows environment is available for the M$ executable to run.

At the end of this tutorial you will see that USB creators tools are quite sophisticated peace of software allowing to create many different systems  with a speed of blink of an eye not necessary telling to the user all magic happening under a hood. Let’s start…

Set bootable flag on USB drive

First you need to create the correct partition on your USB drive using fdisk or modern cfdisk then set a bootable flag:

$ sudo fdisk /dev/sdb             #/dev device needs to be a hard drive(sdb) not a partition(sdb1)
Command (m for help): a
Partition number (1-4): 1
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

$ sudo fdisk -l                                                                   
<--- output omitted ----->
Disk /dev/sdb: 2002 MB, 2002747392 bytes
255 heads, 63 sectors/track, 243 cylinders, total 3911616 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *          63     3911615     1955776+   c  W95 FAT32 (LBA)

Create filesystem on USB stick

You should mark a partition in fdisk as FAT16 (type 0E) if the size is up to 2GB or FAT32 (type 0C) if bigger or needs long filenames support.

df -h                              #find your usb device
lsblk                              #another way to find your device
umount /dev/sdb1
mkfs.vfat /dev/sdb1                     #create fat32
mkfs.ext3 /dev/sdb1                     #create ext3
mkfs.msdos -F 32 -n FREEDOS /dev/sdb1   #format device to fat16, use -F 16 for fat16
mkdosfs -F 32 -n FREEDOS -I /dev/sdb1   #format device to fat32, use -F 16 for fat16, -n partition label

Make bootable USB from .iso image

Copy image to USB

DD can copy a whole image to the desired device but only a hybrid ISOs image will boot.

sudo umount /dev/sdb
sudo dd if=image.iso of=/dev/sdb        #output file of= needs pointing to USB drive not a partition (eg .sdb1)
sync                                          #forces changed blocks to disk, updates the super block and flushes file system buffers

Convert .iso to hybrid image

Starting in version 3.72, ISOLINUX supports a “hybrid mode” which can be booted from either CD-ROM or from a device which BIOS considers a hard disk or ZIP disk, e.g. a USB key or similar. Hybrid images are special as in addition to the normal CD-based ISO9660 filesystem, they also contain a valid-looking DOS-style partition table. The isohybrid contains MBR code which has to match the version of the ISOLINUX file isolinux.bin. Therefore always use the program from the same SYSLINUX installation which .iso has been created by mkisofs, genisoimage, or xorriso and then treat it by:

apt-cache pkgnames syslinux | grep -A 1  Version         #check isolinux version
isohybrid isolinuximage.iso                              #convert to hybrid image

The above operation will append necessary information to the image file thus the file check-sum will change.

Mount .iso

If you have .iso image and want to access its file system you can simply mount it. This is equivalent Windows virtual CD.

sudo mkdir /mnt/isoimage                                        #create mounting point
sudo mount -o loop,ro -t iso9660 image.iso /mnt/isoimage/       #-o options, loop -loop,ro device /dev/loop in read-only mode, -t type eg. ntfs, vfat

Create FreeDOS bootable USB from Linux

This is often required for a server BIOS updates when the patch comes in DOS/Windows format. The following tutorial in essence brings all the above together therefore it will be valuable for you to read a whole article. Let’s start.

Understanding MBR size is 446 + 64 + 2 = 512 bytes, where

  • 446 bytes – Bootstrap
  • 64 bytes – Partition table
  • 2 bytes – Signature

### Step 1. Partition USB drive using parted. The fdisk, cfdisk will not work as they are known for creating a not valid MBR record.

parted /dev/sdb mklabel msdos
parted /dev/sdb mkpart primary fat32 0 2000MB
parted /dev/sdb set 1 boot on
parted /dev/sdb print                                     #show partitions

### Step 2. Create_filesystem_on_USB_stick – you may need to re plug in your USB flash to a laptop

sudo umount /dev/sdb1
sudo mkfs.msdos -F 32 -n FREEDOS /dev/sdb1        #creates fat32 filesystem where USB stick partition is /dev/sda1

### Step 3. Install syslinux bootloader and make USB flash bootable

sudo syslinux -i /dev/sdb1                              #overwrites previous bootloader GRUB like

### Step 4. Download FreeDOS

wget           #FreeDOS 1.1 Base CD+several useful utilities, 40MB

### Step 5. Mount FreeDOS image and copy boot files to USB stick

sudo mount /dev/sdb1 /mnt/usbdrive                                  #mount USB stick
sudo mkdir /mnt/usbdrive/{fdos,img}                                 #create fdos (FreeDOS binaries) and img (other images eg. memtest) directory on USB
sudo mkdir /mnt/isoimage                                            #create create isoimage mount point directory in /mnt
sudo mount -i loop ~/Downloads/fd11src.iso /mnt/isoimage            #mount FreeDOS ISO
df -Th | grep dev/                                                   #show mounted FreeDOS iso (loop0) and USB stick (sdb1)
/dev/sda1      ext4      290G   18G  258G   7% /
/dev/loop0     iso9660    39M   39M     0 100% /mnt/isoimage
/dev/sdb1      vfat      1.9G   36K  1.9G   1% /mnt/usbdrive
sudo unzip /mnt/isoimage/freedos/packages/boot/ -d /mnt/usbdrive/fdos                          #extract boot files from .iso to USB
sudo find /mnt/isoimage/freedos/packages/base/*.zip | sudo xargs -l unzip -d /mnt/usbdrive/fdos           #extract FreeDOS base utilities to USB
cd /mnt/usbdrive                                                      #change current directory to root USB directory (where USB is mounted)
sudo cp fdos/autoexec.txt ./autoexec.bat                              #create autoexec.bat using preconfigured autoexec.txt
sudo cp fdos/config.txt ./config.sys                                  #create config.sys using preconfigured config.txt

### Step 6. Place syslinux.cfg to root USB directory. Paste the below to your favourite text editor and save as syslinux.cfg

sudo vi /mnt/usbdrive/syslinux.cfg
default fdos
prompt 1
timeout 200
say Press ENTER to boot FreeDOS, or choose from these alternatives:
say ---------------------------------------------------------------
say :    fdos :: FreeDOS 1.1
say : memtest :: Run Memtest86+ 4.20 need to upload the image
say ---------------------------------------------------------------
say Example: To boot Memtest86+, type "memtest" and hit Enter
label fdos
    menu label fdos - Load FreeDOS 1.1 from USB flash drive
    com32 /fdos/bin/chain.c32
    append freedos=/fdos/bin/kernel.sys
label memtest
    menu label memtest - Load Memtest86+ 4.20
    linux /img/memtest.bin

### Step 7. Unmount USB drive. Your bootable USB FreeDOS flash drive is ready.

cd ~
sudo umount /mnt/usbdrive

### Troubleshooting

umount /mnt/usbdrive device is busy
fuser -u /mnt/usbdrive/                                        #displays who is currently using /mnt/usbdrive, useful when drive is busy to unmount
/mnt/usbdrive:       16029c(piotr)