Burning an image on a USB flash drive from a Windows machine using Git Bash
Published: 2021-02-13 18:07:25

## tl;dr (for the pros)

Remove all drive letters of the device before burning (using Windows' Disk Management tool, `WinKey+X, K` to open).

### Burning the image:
```bash
# Run this in an elevated (admin) Git Bash
dd bs=4M if=<path-to-image-file> of=<path-to-device-file> 
conv=fdatasync status=progress
```

### Validating the copying using a hash algorithm:
1. Check the hash of the original image:
    ```bash
    md5sum.exe <path-to-image-file>
    ```
2. Check the hash of the burned image on the device:
    ```bash
    # Run this in an elevated (admin) Git Bash
    head -c $(stat --printf="%s" <path-to-image-file>) <path-to-device-file> | md5sum.exe
    ```

**Tip:** You can burn an OS image even on something like a microSD card, but those tend to malfunction much more often, especially cheap/old ones, probably because they weren't designed for the intensive read/write operations of burning a large image file and installing an OS from it.


## The Full Explanation

You want to burn an image (.img/.iso file) to a flash drive from your Windows machine. You are looking for a legit tool for the job, but you can't find one from a well trusted source. What do you do?

Git Bash to the rescue!

Git Bash comes with a tool called `dd` which allows you to copy the contents of a file directly onto a storage device.
To do that, we first need to find the right device.

### Step 1 - Finding the right device

Git Bash allows us to access our storage devices in a convenient way - as if they were files. (like Linux)
The files that represent devices are available (via Git Bash) in the folder `/dev`. This folder contains many files, we are interested in the files whose name starts with "sd".

You can list those by running this command after you plug in your flash drive:

```bash
ll /dev/sd*
```

You'll get something like the following files:
```
/dev/sda
/dev/sda1
/dev/sda2
/dev/sda3
/dev/sda4
/dev/sda5
/dev/sdb
/dev/sdb1
/dev/sdc
/dev/sdc1
/dev/sdc2
/dev/sdc3
```

Filenames ending with a number represent a partition, and those without numbers represent the device. So, in the above list of files, the device `/dev/sda` contains 5 partitions, represented by `/dev/sda1` to `/dev/sda5`. Remember, we need the file that represents the device, not a partition.

So, which file represents our flash drive?
That's a tricky one. The way I solved it is by looking at Windows' Disk Management tool (which you can open by hitting `WinKey+X, K`).

![image](https://dev-to-uploads.s3.amazonaws.com/i/935xwx9ngv04c0mv1w10.png)
 

In there you can find a list of your storage devices. I'd skip the table of volumes and go to the section below (the second section), it's easier to detect which device (== disk) represents your flash drive over there, either by size, number of partitions or sometimes, by label.

Now, this usually goes like this: Disk 0 is `/dev/sda`, Disk 1 is `/dev/sdb` and so on, but make sure you got the right device by checking the size, number of partitions or label.

(note: the number of partition-representing files seems to be greater than the number of partitions, by 1. So, in the example above, `/dev/sda` has 4 partitions, even though there are `/dev/sda1`-`/dev/sda5`)

### Step 2 - Removing the drive letters

It's important that no process will be accessing the device while we burn an image on it, so we remove the drive letter to avoid any issues.  
When I tried burning an image without removing the drive letter first, the copying was corrupted - not all the bytes were successfully written to the device.

To remove the drive letter, open Windows' Disk Management tool.
Usually, a USB flash drive will only have one partition, so to remove the drive letter you need to right-click the Disk block in the second section and select `Change Drive Letter and Paths`. In there, you can remove the drive letter.
If you have more than one partition on the device, you'll need to remove all the drive letters of all partitions that were assigned a drive letter. Do this like you would with a single-partition device, but instead of the Disk block, by right-clicking each partition block.

## Step 3 - Burning the image

Now, the copying part! Running the following command will start the copying. Replace `/c/Users/User/Downloads/ubuntu-20.04.2.0-desktop-amd64.iso` with the path to your desired image and `/dev/sdb` with the path to the correct device file.

```bash
# Run this in an elevated (admin) Git Bash
dd bs=4M if=/c/Users/User/Downloads/ubuntu-20.04.2.0-desktop-amd64.iso of=/dev/sdb conv=fdatasync status=progress
```

I'm burning the latest version of Ubuntu, but that works with pretty much any image.

The output will look like this and will update along the copying process:
```
226492416 bytes (226 MB, 216 MiB) copied, 19 s, 11.9 MB/s
```

### Step 4 - Checking the hashes

It's worth mentioning that the dd command won't report any write errors that occurred during the copying process, so you might want to make sure that the image was properly written to the flash drive.

I do this by comparing the hash of the first N bytes of the device with the hash of the image file, where N is the size of the image we burned: (Hashing the entire device might give the wrong result because the device is probably not the same size as your image file)

```bash
# Run this in an elevated (admin) Git Bash
 head -c $(stat --printf="%s" ~/Downloads/ubuntu-20.04.2.0-desktop-amd64.iso) /dev/sdb | md5sum.exe
```

The resulting hash should be the same as the hash of the image file:

```bash
md5sum.exe ~/Downloads/ubuntu-20.04.2.0-desktop-amd64.iso
```

Notes:
1. Tilda (~) is a short for your home (user) directory.
2. I used the MD5 hashing algorithm because it's fast, you can use any other hash algorithm (SHA1, SHA256...) if you want.

### Step 5 - Safely ejecting the flash drive

To safely eject the flash drive, you can open Windows' Disk Management tool, right click the flash drive's Disk block in the second section and click eject.

### That's it.

I hope you found this tutorial helpful.
Feedback is welcome :)