Making a PXE-bootable 10MB or larger DOS image

bootfreedosms-dospxe

I would like to make a "massive" DOS floppy disk image, say 10MB or more, containing all the firmware updates I need for any system, hard drive or BIOS.

I do not need the DOS image to be network-able as everything will be on the PXE-booted image, but networking would be nice. Since Zip Disks were attached to the floppy disk controller and were over 100MB, this should be possible.

I tried a long time ago to do this and spent too much time on it only to have it fail to boot. So if someone has reliable instructions on how to create such a nightmarish beast and edit it, please let me know. An image that can be used for PXE and copied to a USB stick would be a plus.

Too bad manufacturers don't supply a single bootable Linux ISO containing all their firmware updates that would be easy to boot over-the-LAN and have networking. HP servers do this and it is awesome.

Best Answer

You can make a FreeDOS bootable image (any size you need) for your purposes and then add any software or any DOS utility like BIOS update tools, etc.

From your question it seems you have access to Linux and might be familiar with using the terminal/command line. So for this answer I will focus on creating the bootable image in Linux. On a Windows machine you could use a tool like Rufus to do do this.

You can then boot of this FreeDOS image using PXE boot or write it to a USB drive with dd to create a FreeDOS boot drive. Ofcourse you can extend the steps used here to create any FreeDOS media you'd like including adding the full suite of software that comes with the FreeDOS Full edition.

Below are the steps for creating a bootable FreeDOS image in Linux:


WARNING / DISCLAIMER!!! Some commands used below have the potential to wipe data from your disk drives if used incorrectly. Read the man page for each program to understand the command usage before proceeding. You might want to try these commands on a secondary/virtual machine that doesn't have your valuable data on it.


Step 1: Install Prerequites (ms-sys):

  • Install ms-sys from source if its not available with your package manager:

    $ wget https://sourceforge.net/projects/ms-sys/files/ms-sys%20stable/2.6.0/ms-sys-2.6.0.tar.gz
    $ tar -xzvf ms-sys-2.6.0.tar.gz
    $ cd ms-sys-2.6.0
    
  • Compiling ms-sys requires msgfmt from the gettext package which can be installed on Debian/Ubuntu using:

    $ sudo apt install gettext
    
  • Compile and Install:

    $ make
    $ sudo make install
    

Step 2: Create a blank disk image and create a msdos partition:

  • Create an empty file for the disk image:

    $ truncate -s 50M disk.img
    

    Note: Here a 50 MiB size disk image is created but you can make this any size you need

  • Partition the disk image:

    $ fdisk disk.img
    Command (m for help): o
        Created a new DOS disklabel with disk identifier 0x1234abcd.
    
    Command (m for help): n
        Partition type
           p   primary (0 primary, 0 extended, 4 free)
           e   extended (container for logical partitions)
        Select (default p): p
        Partition number (1-4, default 1): <ENTER>
        First sector (2048-102399, default 2048): 2048
        Last sector, +sectors or +size{K,M,G,T,P} (2048-102399, default 102399): <ENTER>
    
    Command (m for help): t
        Selected partition 1
        Partition type (type L to list all types): c
    
    Command (m for help): a
        Selected partition 1
        The bootable flag on partition 1 is enabled now.
    
    Command (m for help): w
    

    Note: The fdisk commands above assume you want a FAT32 file-system. If you want to use a FAT16 file-system then for the question above Partition type (type L to list all types): enter e instead of c

Step 3: Confirm location of the starting sector of the first partition:

  • Use fdisk to determine the starting sector:

    $ fdisk -l disk.img
    Disk disk.img: 50 MiB, 52428800 bytes, 102400 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
    Disklabel type: dos
    Disk identifier: 0x1234abcd
    
    Device     Boot Start    End Sectors Size Id Type
    disk.img1  *     2048 102399  100352  49M  c W95 FAT32 (LBA)
    

    Note: From the above fdisk output we can see that the starting sector offset is 2048 sectors or 2048 x sector_size bytes = 2048 x 512 bytes = 1048576 bytes. Actually we explicitly specified the starting sector in Step 2 but I included this step as it might be useful when the partition was already created. These numbers: 2048 and 1048576 are used in the commands that follow.

Step 4: Format the partition with a FAT file-system

  • Search for a free loop device:

    $ losetup -f
    /dev/loop0
    
  • Create a loop device of the partition (which is at offset=1048576 of the disk image):

    $ sudo losetup -o1048576 /dev/loop0 disk.img
    
  • Create FAT File System:

    • To create a FAT16 file system:

      $ sudo mkfs.vfat -F16 -R8 -h2048 /dev/loop0
      
    • To create a FAT32 file system:

      $ sudo mkfs.vfat -F32 -h2048 /dev/loop0
      

      Note: In the mkfs.vfat parameter -h2048 is required. mkfs.vfat doesn't write the hidden sectors before the partition to the boot record unless you specify this parameter and it is required for booting the image). Again here 2048 is the partition 1 offset in sectors as determined in Step 3. The parameter -R8 is optional but recommended.

Step 5: Use ms-sys to write to the Master Boot Record (MBR) and Volume Boot Record (VBR):

  • First write the VBR while the partition is still loaded as a loop device:

    • To create a FAT16 file system:

      $ sudo ms-sys --fat16free /dev/loop0
      
    • To create a FAT32 file system:

      $ sudo ms-sys --fat32free /dev/loop0
      

      Notes:

      • Don't use this command: ms-sys --partition /dev/loop0 even thought it is discussed in some of the ms-sys documentation as being required in some cases. It will overwrite the hidden sectors field already correctly written by mkfs.vfat
      • ms-sys only writes to the first boot record. ms-sys unlike Rufus does not write to FAT32's backup boot record but this shouldn't prevent the image from being bootable.
  • Next unload/detach the disk image file from the loop device:

    $ sudo losetup -d /dev/loop0
    
  • And finally write a Windows 7 MBR to the disk image:

    $ ms-sys --mbr7 --force disk.img
    

    Note: ms-sys requires the --force argument when writing to regular (non-device) files.

Step 6: Write Basic FreeDos files and any other programs you need to the partition on the disk image:

  • Mount partition:

    $ mkdir mnt
    $ sudo mount -o loop,offset=1048576 disk.img mnt/
    
  • Download and extract required FreeDOS files:

    $ wget https://github.com/pbatard/rufus/archive/v3.6.tar.gz
    $ tar -xvf v3.6.tar.gz rufus-3.6/res/freedos/
    

    Note: These files are downloaded from the Rufus github repository but are extracted from the official FreeDOS website. See the readme.txt on https://github.com/pbatard/rufus/tree/master/res/freedos/ for detail on were Rufus gets the binaries from the official FreeDOS sources.

  • Copy files to partition:

    $ sudo mkdir mnt/LOCALE
    $ sudo cp rufus-3.6/res/freedos/!(COMMAND.COM|KERNEL.SYS) mnt/LOCALE/
    $ sudo cp rufus-3.6/res/freedos/{COMMAND.COM,KERNEL.SYS} mnt/
    $ printf '@echo off\r\nset PATH=.;\\;\\LOCALE\r\necho Using US-English keyboard with US-English codepage [437]\r\n' | sudo tee mnt/AUTOEXEC.BAT
    $ sudo fatattr +h +s mnt/COMMAND.COM
    $ sudo fatattr +h +s mnt/KERNEL.SYS
    

    Notes:

    • The only files that are really required to make the disk image bootable are COMMAND.COM and KERNEL.SYS. The rest of the files are optional
    • You can now also copy any other files you have to the disk image as well before unmounting it (eg: BIOS firmware updates).
    • The fatattr commands are optional but add hidden and system attributes to the files COMMAND.COM and KERNEL.SYS as is customary. On a Debian/Ubuntu system you can install the fatattr program using sudo apt-get install fatattr

Step 7: You are Done!

  • Unmount the disk image:

    $ sudo umount mnt/