Format Portable Drives as exFat to use them under Linux, Windows and MacOS
A tutorial about how to format a portable drive as exFat on Ubuntu.
Currently, I mainly use Ubuntu and MacOS. Furthermore, I also get in contact with Windows from time to time. To transfer data between machines running these different operating systems I use a USB flash drive. Unfortunately, many USB flash drives don't work under Linux, Windows and MacOS at the same time out of the box. For instance, a while ago I experienced that my USB flash drive works normally under Linux and Windows, but under MacOS I only had read access but no write access. This behavior is caused by the fact that many USB flash drives are formatted using the NTFS file system.
NTFS is the file system Windows likes to use by default nowadays. However, NTFS doesn't work properly under MacOS. There are a few alternatives to NTFS. You can read more about them here. I was looking for a file system that works under Linux, Windows and MacOS. The exFat file system meets this requirement. In the following I want to describe how I formatted my USB flash drive as exFat on Ubuntu 18.04 LTS. To do so I actually followed a great tutorial written by Kevin Arrows. In the following I will summarize it in my own words. However, if you prefer to read the original tutorial, you can find it here.
ExFat on Windows
(see below) later, that describes a way to format the drive as exFat which also works under Windows. If this is what you are looking for, you may want to scroll down to this section already and skip my first solution that only works on Linux and MacOS. If you only want to use the drive on Linux and MacOS on the other hand or if you want to get some additional information, you can keep reading from here.
First of all, we need to install the exFat drivers on Ubuntu.
sudo apt-get install exfat-fuse exfat-utils
Then, we can plug in the USB flash drive into our machine. It should be automatically recognized and mounted by Ubuntu. You should see an icon on your desktop that represents your USB flash drive. Alternatively, you should also be able to find your mounted USB flash drive under /media
using your terminal (other Linux distributions usually mount it under /mnt
).
Next, we need to find out the name of our drive. We can use fdisk
for this.
sudo fdisk -l
The command above should print a list of devices that are attached to our system. Pay very close attention to find the right drive name, since we are going to erase all data of that drive later.
/dev/sda
(or something similar) in the device list, you must not choose this one! The drive /dev/sda
is usually the drive that is used to boot GNU/Linux from. It is not your USB flash drive. You don’t want to format it!
Often times our USB flash drive will show up as /dev/sdb
in the device list. When I ran fdisk -l
, the /dev/sdb
entry showed up like this in the device list.
Disk /dev/sdb: 14,5 GiB, 15518924800 bytes, 30310400 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: 0x7dffaefd
Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 30310399 30308352 14,5G 86 NTFS volume set
You can also check if the total memory that is displayed for /dev/sdb
matches your USB flash drive's memory. On my USB flash drive it is written that it has 16 GB of storage. In the device list /dev/sdb
shows 14.5 GB which is not exactly 16 GB, but it comes closest among all devices in the device list. Hence, /dev/sdb
must be our USB flash drive (here you can read more about why it doesn't show up as exactly 16 GB). But wait! We actually see /dev/sdb
and /dev/sdb1
here. What do both mean? Well, /dev/sdb
is the name of our drive, whereas /dev/sdb1
is the name of the partition on our drive.
sudo fdisk -l
on Ubuntu, all devices attached to our machine get listed. Usually our USB flash drive has the name /dev/sdb
here. Each of its partitions is listed with a number attached to that name, e.g. /dev/sdb1
, /dev/sdb2
etc. If our USB flash drive has just one partition, we will only find /dev/sdb1
in the device list.
In the following I'm going to assume that /dev/sdb
is the correct name of our drive. However, you should still double-check, if this is also the correct name of your drive on your system! Furthermore, make sure there isn't any data on the drive that you still need, since we are going to format the drive now.
Next, we want to delete the current filesystem of our USB flash drive to start with a fresh file system. To do that we need to unmount our drive first.
sudo umount /dev/sdb*
We should either get no output or the following output. No error should appear.
umount: /dev/sdb: not mounted.
umount: /dev/sdb1: not mounted.
The icon on the desktop representing our USB flash drive should disappear and also under /media
it shouldn't be mounted anymore (or /mnt
on other Linux distributions). Now we can delete the file system. To do this we can use a tool called wipefs
.
sudo wipefs -a /dev/sdb
We should get the following (or similar) output.
/dev/sdb: 2 bytes were erased at offset 0x000001fe (dos): 55 aa
/dev/sdb: calling ioctl to re-read partition table: Success
wipefs
actually doesn’t remove the filesystem itself or any other data on the drive but the filesystem’s signature. However, this is enough to be able to set up a new file system on the drive. You can read more about wipefs
here. If you also want to immediately erase all data on your drive, check out this article.
Next, we need to create a new partition table. We can use fdisk
for this.
sudo fdisk /dev/sdb
We should get the following output.
Welcome to fdisk (util-linux 2.31.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0xa8df2b81.
Command (m for help):
As we can see, a command prompt appeared. We need to type n
and then Enter
to create our partition. Then, we are asked to specify a few parameters that are needed to create the partition on our drive: a) what partition type we want, b) how many partitions should be created and c) from which to which sector on the drive should each partition go. Since we simply want a single partition on our USB flash drive that encompasses the whole drive space, we can use the default values that are provided to us here.
Welcome to fdisk (util-linux 2.31.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0xa8df2b81.
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): 1
First sector (2048-30310399, default 2048): 2048
Last sector, +sectors or +size{K,M,G,T,P} (2048-30310399, default 30310399): 30310399
Created a new partition 1 of type 'Linux' and of size 14,5 GiB.
Command (m for help):
However, as you can see there is still one problem here. The type of the created partition is Linux
, which will make it difficult to use our USB flash drive on Windows and MacOS. We need to change the type! We can change the partition type with the fdisk
command t
. After hitting Enter
we are asked to provide the hex code of the desired partition type. We can list all available types by typing L
. In the upcoming list we should look for HPFS/NTFS/exFAT
and take its hex code. Usually it will have the number 7
. So, let's type 7
to change the type of our partition from Linux
to HPFS/NTFS/exFAT
.
Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): 7
Changed type of partition 'Linux' to 'HPFS/NTFS/exFAT'.
Command (m for help):
fdisk
also asks you to remove a signature from the drive. Unfortunately, I haven’t really understood yet what this signature is used for. Is it the file system’s signature that should already been removed by wipefs
? Well, I simply agreed to remove this signature as well. My USB flash drive still worked as expected after formatting. However, if your USB flash drive is extremely important to you, you might want to further investigate about this signature before you proceed.
Finally, we can execute all of our commands by typing w
and Enter
. Depending on how large your drive is, it might take a few seconds. We should see the following output.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
After creating the partition and the partition table, we can finally create the file system. We can do this with the following command.
sudo mkfs.exfat -n bam098 /dev/sdb1
bam098
is just the name that I decided to give my USB flash drive. You can use any name you like here. After running the command we should see the following or a similar output (the mkexfatfs version might differ on your system).
mkexfatfs 1.2.8
Creating... done.
Flushing... done.
File system created successfully.
To check if there are any errors we can also run the following.
sudo fsck.exfat /dev/sdb1
We should see the following or a similar output.
exfatfsck 1.2.8
Checking file system on /dev/sdb1.
File system version 1.0
Sector size 512 bytes
Cluster size 32 KB
Volume size 14 GB
Used space 2 MB
Available space 14 GB
Totally 0 directories and 0 files.
File system checking finished. No errors found.
We should make sure that it says No errors found
. Finally, I tested my USB flash drive, formatted with exFat as described above, on my Ubuntu 18.04 LTS and a machine running MacOS Catalina. It worked on both systems.
After I wrote this blog post I was able to test my USB flash drive, formatted with exFat as described above, also on a machine running Windows 10. Unfortunately, I didn't work to my surprise. I'm not really sure why it doesn't work, but on askubuntu.com I found another solution to format a USB flash drive as exFat, which does also work under Windows 10. In the following I want to describe the whole process again (on my Ubuntu 18.04 LTS) using this new solution.
If you haven't done so, you should install the exFat drivers on your Ubuntu.
sudo apt-get install exfat-fuse exfat-utils
Then, we need to plug our USB flash drive into our machine. It should be automatically recognized and mounted by Ubuntu. Again, an icon representing our USB flash drive should appear on the desktop. Alternatively, we should also find it under /media
using the terminal (usually under /mnt
on other Linux distributions).
Next, we need to find out the name of our drive. We can use fdisk for this as before.
sudo fdisk -l
As described above, the command should print a list of devices that are attached to our system. Pay very close attention to find the right drive name, since we are going to erase all data of that drive later. In the following let's assume again that our USB flash drive shows up as /dev/sdb
in the device list and /dev/sdb1
indicates its first (and usually only) partition. When I ran the command, it showed up as follows.
Disk /dev/sdb: 14,4 GiB, 15476981760 bytes, 30228480 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: 0x36345114
Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 30228479 30226432 14,4G 7 HPFS/NTFS/exFAT
Again, you can check if the total memory that is displayed for /dev/sdb
matches your USB flash drive's memory. As described above it will most likely be a little less as advertised on your USB flash drive. If you want to read again why that is, please see above.
Besides fdisk there are also other tools to find out the device name. One of them is lsblk for instance.
lsblk
It should also print a device list and our USB flash drive should appear as /dev/sdb
in the following way.
sdb 8:16 1 14,4G 0 disk
└─sdb1 8:17 1 14,4G 0 part
/dev/sda
(or something similar) in the device list, you must not choose this one! The drive /dev/sda
is usually the drive that is used to boot GNU/Linux from. It is not your USB flash drive. You don’t want to format it! The correct drive could be /dev/sdb
as in my example here but it doesn’t have to be the correct one on your system.
Next, we need to unmount our drive.
sudo umount /dev/sdb*
We should either get no output or the following output. No error should appear.
umount: /dev/sdb: not mounted.
umount: /dev/sdb1: not mounted.
The icon on the desktop representing our USB flash drive should disappear and it should also not be mounted under /media
(or /mnt
on other Linux distributions) anymore. Additionally, we can also check with df
whether /dev/sdb
is still mounted.
df
df
prints a list of mounted devices which shouldn't contain /dev/sdb*
anymore.
Now we can delete the filesystem of our USB flash drive. To do this we can use wipefs
for this again.
sudo wipefs -a /dev/sdb
Next, we need to create the new partition table. However, the partition table needs to be of the GPT
type. fdisk
that we used before to create the partition table seems to support it. However, I have only been able to create the correct partition table using a tool called parted
(read more about it here). Maybe I will find out how to do the same thing using fdisk
in the future but for now let's use parted
. So, let's create the partition table and specify that it should be of type GPT
.
sudo parted /dev/sdb mklabel gpt
After running the above command it could happen that you get the following message.
Information: You may need to update /etc/fstab.
In this thread on reddit.com someone says that this message is displayed by several partition editors when creating a new partition to indicate that you need to add it to /etc/fstab
if you want to have it mounted on boot. Since we don't want to have it mounted when booting our machine (it is portable device and not our internal hard drive!), we can ignore this message I think.
Next, let's create our partition that encompasses the whole space of our USB flash drive.
sudo parted -a optimal /dev/sdb mkpart primary '0%' '100%'
The message regarding /etc/fstab
could appear again but as mentioned above I think we can ignore it. Finally, we need to add a Microsoft related flag called msftdata
(read more about it here) on our newly created partition in the following way.
sudo parted <DEVICE> set <PARTITION_NUMBER> msftdata on
In my case the command was as follows.
sudo parted /dev/sdb set 1 msftdata on
Again, the message regarding /etc/fstab
can appear but as before you can probably ignore it. Now we can finally create the file system.
sudo mkfs.exfat -n bam098 /dev/sdb1
Again, bam098
is the name that I decided to give my USB flash drive. You can use any name you like here. After running the command we should see the following or a similar output.
mkexfatfs 1.2.8
Creating... done.
Flushing... done.
File system created successfully.
Let's also make sure again that there are no errors.
sudo fsck.exfat /dev/sdb1
We should see the following or a similar output.
exfatfsck 1.2.8
Checking file system on /dev/sdb1.
File system version 1.0
Sector size 512 bytes
Cluster size 32 KB
Volume size 14 GB
Used space 2 MB
Available space 14 GB
Totally 0 directories and 0 files.
File system checking finished. No errors found.
We should make sure that it says No errors found
. Additionally, we can also unplug the USB flash drive from our machine and plug it in again. When running df
it should now appear in the list of mounted devices.
/dev/sdb1 15112192 2048 15110144 1% /media/bam/bam098
Finally, I tested my USB flash drive, formatted as exFat, on Ubuntu 18.04 LTS, MacOS Catalina and Windows 10. It worked on all three operating systems this time. So, we are done!