はじめに
最近、FAT16パーティションしか読めない特殊な環境を使う必要があり、16GBのSDカードの先頭にパーティションを切ってFAT16フォーマットしました。しかし、これをmacOSでやろうとすると意外と手こずったので、記事としてまとめておきます。
事前知識
普通に考えると diskutil
コマンドでサラッと実行できそうですが、できませんでした。
macOS では既存のパーティションを newfs_msdos -F 16
で FAT16 フォーマットすることができます。ネットで検索すると、単純にこのコマンドを実行するだけで良い、という記事がいくつか見つかります。
しかしnewfs_msdos
コマンドはパーティションタイプを FAT16 に変更してくれません。なので、例えば FAT32 でパーティションが切られているディスクを newfs_msdos -F 16
でフォーマットすると、パーティションタイプは FAT32 なのに中身は FAT16 という不整合な状態となります。これでも macOS からは見えるのですが、環境によっては読めないディスクになってしまいます。
では、新規に diskutil partitionDisk
で FAT16 パーティションを作ればよいのですが、これはエラーが出てしまいます。
以下は /dev/disk2 の先頭 2GB だけ FAT16 パーティションに、残りを空き領域にしようとした例ですが、パーティションサイズのエラーで、失敗します。
% diskutil partitionDisk /dev/disk2 2 MBR "MS-DOS FAT16" NONAME 2G "Free Space" UNTITLED 0B
Started partitioning on disk2
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Formatting disk2s1 as MS-DOS (FAT16) with name NONAME
Error: -69850: The chosen size is not valid for the chosen file system
diskutil eraseVolume
や diskutil eraseDisk
でも同様のエラーで失敗します。 diskutil
コマンドは FAT16 パーティションのサイズ指定が動作しないようです。
試行錯誤の末、一度 FAT32 でパーティションを作った後、 fdisk
でコマンドでパーティション種別を FAT16 に変更することで対処できましたので、以下に方法をまとめておきます。
FAT16パーティションを作ってフォーマットする手順
この手順は以下の前提で書きます。
- SDカードのマウント先が /dev/disk2
- ディスクの先頭 2GB だけを FAT16 パーティション、残りは空き容量にする
- パーティション形式は MBR
動作確認した環境は、 macOS Big Sur (11.3) です。
ステップ1. FAT32 でパーティションを作る
まず、diskutil を使って FAT32 パーティションを切ります。
% diskutil partitionDisk /dev/disk2 2 MBR "MS-DOS FAT32" NONAME 2G "Free Space" UNTITLED 0B
パーティションの作成後、ディスクが自動でマウントされてしまうので、/dev/disk2 のマウントを解除します。
% diskutil unmountDisk /dev/disk2
ステップ2. fdisk でパーティションの種類を FAT16 に変更する
fdisk /dev/disk2 を実行して、 パーティションテーブルを表示します。テーブルの最初の行に表示された start と size の値をメモっておきます。
% sudo fdisk /dev/disk2
Disk: /dev/disk2 geometry: 1890/255/63 [30375936 sectors]
Signature: 0xAA55
Starting Ending
#: id cyl hd sec - cyl hd sec [ start - size]
------------------------------------------------------------------------
1: 0B 1023 254 63 - 1023 254 63 [ 2048 - 3906256] Win95 FAT-32
2: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
3: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
4: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
fdisk を起動して、/dev/disk2 のエディットモードに入ります。
% sudo fdisk -e /dev/disk2
fdisk: 1>
対話型プロンプトに、edit 1
と入力すると、編集モードに入るので、
- Partition id に 6
- 前の手順でパーティションのサイズを32MB以下にしていた場合は 4 にします。
- CHS mode は n
- Partition Offset は 前の手順でメモった start の値
- Partition Size は 前の手順でメモした size の値
をそれぞれ入力します。以下が入力例です。
fdisk: 1> edit 1
Starting Ending
#: id cyl hd sec - cyl hd sec [ start - size]
------------------------------------------------------------------------
1: 0B 1023 254 63 - 1023 254 63 [ 2048 - 7812504] Win95 FAT-32
Partition id ('0' to disable) [0 - FF]: [B] (? for help) 6
Do you wish to edit in CHS mode? [n] n
Partition offset [0 - 30375936]: [63] 2048
Partition size [1 - 30373888]: [30373888] 7812504
fdisk: *1>
入力が終わると上記のようにプロンプトに戻ってきます。write
で変更結果を書き込み、quit
します。
fdisk:*1> write
Writing MBR at offset 0.
fdisk: 1> quit
%
ディスクが自動でマウントされてしまうので、再度 /dev/disk2 のマウントを解除します。
% diskutil unmountDisk /dev/disk2
ステップ3. パーティションを FAT16 フォーマットする
newfs_msdos -F 16
コマンドを実行します。対象デバイスはディスク(/dev/disk2)ではなくボリューム(この記事の例では /dev/disk2s1)ですので注意してください。誤ってディスクを指定するとパーティションが破壊されます。
% sudo newfs_msdos -F 16 /dev/disk2s1
newfs_msdos: warning: /dev/disk2s1 is not a character device
512 bytes per physical sector
/dev/disk2s1: 3905728 sectors in 61027 FAT16 clusters (32768 bytes/cluster)
bps=512 spc=64 res=1 nft=2 rde=512 mid=0xf8 spf=239 spt=32 hds=255 hid=2048 drv=0x80 bsec=3906256
以上で、完了です。 diskutil mountDisk /dev/disk2
するとパーティションがマウントされ、操作可能になります。
補足
newfs_msdos
コマンドはデフォルトでは2GB以上のパーティションをフォーマットしても、フォーマット後の容量は2GBになってしまいます。
2GBを超えるパーティションをフォーマットする場合は、 -c オプションでクラスターに含まれるセクタ数を指定する必要があります。例えば パーティションサイズ4GBでセクタ長がデフォルトの 512bytes の場合 newfs_msdos -F 16 -c 128
でフォーマットします。
おわりに
もしかするともっと簡単なやり方があるかもしれせん。もしご存知の方がおられましたら教えて下さい。
手元ではSDカードでのみ確認しましたが、他のストレージデバイスでもこの方法でできそうに思います。