In the following procedure we will create a Microsoft Windows bootable USB flash drive in Linux, from scratch with command line. I’m using Debian 9 but you can use any GNU/Linux distribution as long as you have installed dosfstools and syslinux. Requires root privileges.
Test environment: Debian 9 with syslinux 6.03 and mkfs.vfat 4.1
Requirements: apt-get install syslinux dosfstools
Warning: All the data on the USB flash drive will be destroyed without warning! Make sure you selected the correct drive or you will destroy a wrong disk!
1. Identify the USB flash drive, in my example the device is /dev/sdx (Kingston DT microDuo 3.0 / 16G).
lsblk -S
NAME HCTL TYPE VENDOR MODEL REV TRAN
sda 0:0:0:0 disk ATA Samsung SSD 850 1B6Q sata
sdx 6:0:0:0 disk Kingston DT microDuo 3.0 PMAP usb
fdisk -l /dev/sdx
Disk /dev/sdx: 14.4 GiB, 15502147584 bytes, 30277632 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: 0x28853db5
Device Boot Start End Sectors Size Id Type
/dev/sdx1 * 2048 30277631 30275584 14.4G c W95 FAT32 (LBA)
2. Delete partitions by clearing the Master Boot Record, the following command will write 0x00 to the first 512 bytes. All data on /dev/sdx will be destroyed!
dd if=/dev/zero of=/dev/sdx bs=512 count=1
1+0 records in
1+0 records out
512 bytes copied, 0.103547 s, 4.9 kB/s
3. Create one big partition with boot flag on.
echo ',,c;*' | sfdisk /dev/sdx
New situation:
Device Boot Start End Sectors Size Id Type
/dev/sdx1 * 2048 30277631 30275584 14.4G c W95 FAT32 (LBA)
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
4. Format the created partition /dev/sdx1 as FAT32 with the label “WINDOWS”.
mkfs.vfat -F32 /dev/sdx1 -n "WINDOWS"
mkfs.fat 4.1 (2017-01-24)
5. Write the bootstrap code (syslinux/mbr.bin) to the MBR of /dev/sdx. In Debian 9 the file is found in /usr/lib/syslinux/mbr/, if you are using an other distribution run find / -name mbr.bin.
dd if=/usr/lib/syslinux/mbr/mbr.bin of=/dev/sdx bs=440 count=1
1+0 records in
1+0 records out
440 bytes copied, 0.00309581 s, 142 kB/s
6. Install syslinux, this will alter the boot sector and copy ldlinux.sys into the root directory.
syslinux -i /dev/sdx1
7. Mount the USB flash drive, copy syslinux BIOS modules and create syslinux.cfg. In Debian 9 the modules are found in /usr/lib/syslinux/modules/bios/, if you are using an other distribution run find / -name syslinux.c32.
mkdir /mnt/usb
mount /dev/sdx1 /mnt/usb
mkdir /mnt/usb/syslinux
cp /usr/lib/syslinux/modules/bios/* /mnt/usb/syslinux
echo -e "default boot\nLABEL boot\nMENU LABEL boot\nCOM32 chain.c32\nAPPEND fs ntldr=/bootmgr" > /mnt/usb/syslinux/syslinux.cfg
8. Mount the Microsoft Windows ISO image.
mkdir /mnt/iso
mount /example/windows.iso /mnt/iso
9. Copy the Windows installation files to the USB flash drive, it might take a few minutes.
cp -rTv /mnt/iso/ /mnt/usb/
10. Unmount the USB flash drive. Don’t skip this step! Is needed to complete all pending writes.
umount /dev/sdx1