64GB microSDXC カードを FAT32 でフォーマットし直した覚書 (FreeBSD)

2019-01-13

64GB の microSDXC カードが、認識できない機器があったりトラブルが多いと思っていたら、exFAT というやつでフォーマットされていることを知った。
Microsoft の proprietary らしい。 しかも ID が NTFS と同じらしい。 迷惑な奴だ。

より互換性問題の少ない FAT32 では、64GB のメディアが扱えないのかというと、そんなことはなく、通常は 2TB まで対応しており、64GB ならフォーマットできるはずである。
しかしこれも Microsoft の嫌がらせにより、Windows 8.1 では、フォーマット時に exFAT か NTFS しか選べなかった。
まあ FAT32 は、1つのファイルが 4GB までしか対応していないという悩ましい制限もあるが。

以下によれば、FAT32 でフォーマットし直すのに、FreeBSD で行う方法があるらしい。

SDXCメモリカードをFAT32でフォーマットする - CORY's twilight zone

そこで、これを参考にさせてもらい、FreeBSD での FAT32 でのフォーマットにチャレンジしてみる。

SD カードスロットを備えた PC で、FreeBSD 12.0 (i386) を用いて実施した。

現状の確認

以下のように ntfs と表示されるが、exFAT であることは Windows 8.1 で確認してある。

nsmrtks@dark:~ % gpart show
〜

=>       63  122240961  mmcsd0  MBR  (58G)
         63      32705          - free -  (16M)
      32768  122208256       1  ntfs  (58G)

〜

あるいは以下のように。

nsmrtks@dark:~ % sudo fdisk mmcsd0
〜
******* Working on device /dev/mmcsd0 *******
parameters extracted from in-core disklabel are:
cylinders=7609 heads=255 sectors/track=63 (16065 blks/cyl)

Figures below won't work with BIOS for partitions not in cyl 1
parameters to be used for BIOS calculations are:
cylinders=7609 heads=255 sectors/track=63 (16065 blks/cyl)

Media sector size is 512
Warning: BIOS sector numbering starts with sector 1
Information from DOS bootblock is:
The data for partition 1 is:
sysid 7 (0x07),(NTFS, OS/2 HPFS, QNX-2 (16 bit) or Advanced UNIX)
    start 32768, size 122208256 (59672 Meg), flag 0
	beg: cyl 2/ head 10/ sector 9;
	end: cyl 1023/ head 254/ sector 63
The data for partition 2 is:
<UNUSED>
The data for partition 3 is:
<UNUSED>
The data for partition 4 is:
<UNUSED>

とりあえずやってみる..間違えた

注: 以下は途中で手順に失敗しているため、正しい手順を知りたい読者は、ほぼ読み飛ばしてかまわないです。

まず、gpart modify で ID を 12 (FAT32(LBA)) にする。

nsmrtks@dark:~ % sudo gpart modify -i 1 -t \!12 mmcsd0
〜
mmcsd0s1 modified

nsmrtks@dark:~ % gpart show
〜

=>       63  122240961  mmcsd0  MBR  (58G)
         63      32705          - free -  (16M)
      32768  122208256       1  fat32lba  (58G)

〜

「ntfs」だったものが「fat32lba」になった。

続いて、newfs_msdos を実行する.. (注: 以下の手順はパラメータが間違っている)

nsmrtks@dark:~ % sudo newfs_msdos -L FAT32LBA64G /dev/mmcsd0
newfs_msdos: cannot get number of sectors per track: No such file or directory
newfs_msdos: cannot get number of heads: No such file or directory
/dev/mmcsd0: 122211136 sectors in 1909549 FAT32 clusters (32768 bytes/cluster)
BytesPerSec=512 SecPerClust=64 ResSectors=32 FATs=2 Media=0xf0 SecPerTrack=63 Heads=255 HiddenSecs=0 HugeSectors=122241024 FATsecs=14919 RootCluster=2
 FSInfo=1 Backup=2

ここで gpart show を実行してみたら..

nsmrtks@dark:~ % gpart show mmcsd0
gpart: No such geom: mmcsd0.

..ん!?

nsmrtks@dark:~ % gpart show
=>       63  312581745  ada0  MBR  (149G)
         63          1        - free -  (512B)
         64  312475648     1  freebsd  [active]  (149G)
  312475712     106096        - free -  (52M)

=>       63  156301425  ada1  MBR  (75G)
         63      16002        - free -  (7.8M)
      16065  156280320     1  ebr  (75G)
  156296385       5103        - free -  (2.5M)

=>        0  312475648  ada0s1  BSD  (149G)
          0   14680064       1  freebsd-ufs  (7.0G)
   14680064   10485760       2  freebsd-swap  (5.0G)
   25165824   25165824       4  freebsd-ufs  (12G)
   50331648  262143999       5  freebsd-ufs  (125G)
  312475647          1          - free -  (512B)

=>        0  156280320  ada1s1  EBR  (75G)
          0  156280320       1  ntfs  (75G)

=>       63  156301425  diskid/DISK-665Y0000S  MBR  (75G)
         63      16002                         - free -  (7.8M)
      16065  156280320                      1  ebr  (75G)
  156296385       5103                         - free -  (2.5M)

=>        0  156280320  diskid/DISK-665Y0000Ss1  EBR  (75G)
          0  156280320                        1  ntfs  (75G)

.. gpart show の mmcsd0 は何処へ行った!?

nsmrtks@dark:~ % ls /dev/mmcsd0*
/dev/mmcsd0

.. /dev/mmcsd0s1 が存在すべきだと思うが存在してないし、

nsmrtks@dark:~ % sudo fdisk mmcsd0
〜
******* Working on device /dev/mmcsd0 *******
parameters extracted from in-core disklabel are:
cylinders=7609 heads=255 sectors/track=63 (16065 blks/cyl)

Figures below won't work with BIOS for partitions not in cyl 1
parameters to be used for BIOS calculations are:
cylinders=7609 heads=255 sectors/track=63 (16065 blks/cyl)

Media sector size is 512
Warning: BIOS sector numbering starts with sector 1
Information from DOS bootblock is:
The data for partition 1 is:
<UNUSED>
The data for partition 2 is:
<UNUSED>
The data for partition 3 is:
<UNUSED>
The data for partition 4 is:
<UNUSED>

.. fdisk で見ても、MBR のパーティションが 4つとも無くなってしまった。

意味あるか分からないがその microSDXC カードを FreeBSD 機から抜いて NetBSD 機に挿してみると以下のような感じ。

この NetBSD 機ではカードが以下のように認識され、

$ dmesg
〜
umass0 at uhub4 port 1 configuration 1 interface 0
umass0: Generic (0x5e3) USB3.0 Card Reader (0x749), rev 2.10/15.32, addr 2
umass0: using SCSI over Bulk-Only
scsibus0 at umass0: 2 targets, 1 lun per target
sd0 at scsibus0 target 0 lun 0: <Generic, STORAGE DEVICE, 1532> disk removable
sd0: fabricating a geometry
sd0: 59688 MB, 59688 cyl, 64 head, 32 sec, 512 bytes/sect x 122241024 sectors
sd0: fabricating a geometry

disklabel を見てもそれらしきパーティションが無く..

green$ disklabel sd0
# /dev/rsd0:
type: SCSI
disk: STORAGE DEVICE  
label: fictitious
flags: removable
bytes/sector: 512
sectors/track: 32
tracks/cylinder: 64
sectors/cylinder: 2048
cylinders: 59688
total sectors: 122241024
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0		# microseconds
track-to-track seek: 0	# microseconds
drivedata: 0 

4 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a: 122241024         0     4.2BSD      0     0     0  # (Cyl.      0 -  59687)
 d: 122241024         0     unused      0     0        # (Cyl.      0 -  59687)
disklabel: boot block size 0
disklabel: super block size 0

通常は /dev/sd0e でマウントできるのだがそれもできない。

green$ sudo mount -t msdos /dev/sd0e /mnt
Password: 
mount_msdos: /dev/sd0e on /mnt: Device not configured

ここまで来て、さっきの newfs_msdos コマンドで、/dev/mmcsd0s1 とすべきだったのを、/dev/mmcsd0 としていたことに気づいた。
それでパーティションが吹き飛んでしまった..

パーティションから作り直す

気を取り直して、MBR パーティションの作成も、gpart コマンドで行うことが出来るようだ。
自分は今まで gpart create -s gpt 〜 しかやった経験がなかったが、この「gpt」を「mbr」 にすればよい。

nsmrtks@dark:~ % sudo gpart create -s mbr mmcsd0
mmcsd0 created

nsmrtks@dark:~ % gpart show
〜
=>       63  122240961  mmcsd0  MBR  (58G)
         63  122240961          - free -  (58G)
〜

.. gpart show に mmcsd0 が帰ってきた。

そして、最大サイズのパーティションを 1つ、fat32lba で作成 (add) する..

nsmrtks@dark:~ % sudo gpart add -t \!12 mmcsd0
mmcsd0s1 added

nsmrtks@dark:~ % gpart show
〜
=>       63  122240961  mmcsd0  MBR  (58G)
         63     131009          - free -  (64M)
     131072  122028032       1  fat32lba  (58G)
  122159104      81920          - free -  (40M)
〜

..んっ!? fat32lba の前後の free スペースが、合計 104M もあって、やけに大きいような..

どうせなら、当初のように、もう少し使い切ってほしいものである。 (再掲)

nsmrtks@dark:~ % gpart show
〜
=>       63  122240961  mmcsd0  MBR  (58G)
         63      32705          - free -  (16M)
      32768  122208256       1  ntfs  (58G)
〜

そこで、パーティションをいまいちど削除し、

nsmrtks@dark:~ % sudo gpart delete -i 1 mmcsd0
〜
mmcsd0s1 deleted

nsmrtks@dark:~ % gpart show mmcsd0
=>       63  122240961  mmcsd0  MBR  (58G)
         63  122240961          - free -  (58G)

今度は -b オプションで開始ブロックを 32768 に指定して add してみる。

nsmrtks@dark:~ % sudo gpart add -t \!12 -b 32768 mmcsd0
mmcsd0s1 added

nsmrtks@dark:~ % gpart show mmcsd0
=>       63  122240961  mmcsd0  MBR  (58G)
         63     131009          - free -  (64M)
     131072  122028032       1  fat32lba  (58G)
  122159104      81920          - free -  (40M)

..さっきと変わっていない。

-b オプションの使い方が間違っているのだろうか。
しかし、値を大きめにすると、正しく効くようだ..

nsmrtks@dark:~ % sudo gpart delete -i 1 mmcsd0
mmcsd0s1 deleted

nsmrtks@dark:~ % sudo gpart add -t \!12 -b 1048576 mmcsd0
mmcsd0s1 added

nsmrtks@dark:~ % gpart show mmcsd0
=>       63  122240961  mmcsd0  MBR  (58G)
         63    1048513          - free -  (512M)
    1048576  121110528       1  fat32lba  (58G)
  122159104      81920          - free -  (40M)

そこで、man gpart をさらに調べて、-a オプションも指定してみる。

nsmrtks@dark:~ % sudo gpart delete -i 1 mmcsd0
mmcsd0s1 deleted

nsmrtks@dark:~ % sudo gpart add -t \!12 -b 32768 -a 32768 mmcsd0
mmcsd0s1 added, but partition is not aligned on 67108864 bytes

nsmrtks@dark:~ % gpart show mmcsd0
=>       63  122240961  mmcsd0  MBR  (58G)
         63      32705          - free -  (16M)
      32768  122191872       1  fat32lba  (58G)
  122224640      16384          - free -  (8.0M)

開始位置が狙い通り 32768 になった。 この警告メッセージといい、どうやらデフォルトではアラインが 64M (67108864 bytes) 単位になるようだ。

まだ末尾に free が 8.0M 残っている。
これはやはり、gpart が自動的に割り当てたパーティションのサイズ (ブロック数) 122191872 が 32768 で割り切れている通り、32768 ブロック単位になっているようだ。

そこで、さらに -a オプションを 16384 まで細かくする。

nsmrtks@dark:~ % sudo gpart delete -i 1 mmcsd0
〜
mmcsd0s1 deleted

nsmrtks@dark:~ % sudo gpart add -t \!12 -b 32768 -a 16384 mmcsd0
mmcsd0s1 added, but partition is not aligned on 67108864 bytes

nsmrtks@dark:~ % gpart show mmcsd0
=>       63  122240961  mmcsd0  MBR  (58G)
         63      32705          - free -  (16M)
      32768  122208256       1  fat32lba  (58G)

これで当初と同じサイズになった!

ところで、-b の値が -a より大きくなっているので、この -b オプションを省略してみると..

nsmrtks@dark:~ % sudo gpart delete -i 1 mmcsd0
〜
mmcsd0s1 deleted

nsmrtks@dark:~ % sudo gpart add -t \!12 -a 16384 mmcsd0
mmcsd0s1 added, but partition is not aligned on 67108864 bytes

nsmrtks@dark:~ % gpart show mmcsd0
=>       63  122240961  mmcsd0  MBR  (58G)
         63      16321          - free -  (8.0M)
      16384  122224640       1  fat32lba  (58G)

パーティション開始位置が 32768 → 16384 になり、パーティションサイズをさらに 8M 大きくすることができた。
しかし正常に使えるか自信がないので、元に戻しておこう..

nsmrtks@dark:~ % sudo gpart delete -i 1 mmcsd0
mmcsd0s1 deleted

nsmrtks@dark:~ % sudo gpart add -t \!12 -b 32768 -a 16384 mmcsd0
mmcsd0s1 added, but partition is not aligned on 67108864 bytes

nsmrtks@dark:~ % gpart show mmcsd0
=>       63  122240961  mmcsd0  MBR  (58G)
         63      32705          - free -  (16M)
      32768  122208256       1  fat32lba  (58G)

フォーマットする

newfs_msdos を実行する (今度はパラメータを間違えないようにする)。
ところで SDXCメモリカードをFAT32でフォーマットする - CORY's twilight zone の手順では、ここで -u オプションも指定しているが、その方が良いのだろうか.. よく分からない。

nsmrtks@dark:~ % sudo newfs_msdos -L FAT32LBA58G /dev/mmcsd0s1 
〜
/dev/mmcsd0s1: 122178368 sectors in 1909037 FAT32 clusters (32768 bytes/cluster)
BytesPerSec=512 SecPerClust=64 ResSectors=32 FATs=2 Media=0xf0 SecPerTrack=63 Heads=255 HiddenSecs=0 HugeSectors=122208256 FATsecs=14915 RootCluster=2
 FSInfo=1 Backup=2

マウントしてみる。

nsmrtks@dark:~ % sudo mount -t msdos /dev/mmcsd0s1 /mnt

nsmrtks@dark:~ % df -k
Filesystem    1024-blocks     Used     Avail Capacity  Mounted on
〜
/dev/mmcsd0s1    61089248       96  61089152     0%    /mnt

FreeBSD から見ることが出来た。

newfs_msdos に -u を指定したらどうなるのだろうか? さっきのように無指定だと SecPerTrack=63 になっていたようだ。

nsmrtks@dark:~ % sudo newfs_msdos -L FAT32LBA58G -u 16 /dev/mmcsd0s1
/dev/mmcsd0s1: 122178368 sectors in 1909037 FAT32 clusters (32768 bytes/cluster)
BytesPerSec=512 SecPerClust=64 ResSectors=32 FATs=2 Media=0xf0 SecPerTrack=16 Heads=255 HiddenSecs=0 HugeSectors=122208256 FATsecs=14915 RootCluster=2
 FSInfo=1 Backup=2

nsmrtks@dark:~ % sudo mount -t msdos /dev/mmcsd0s1 /mnt

nsmrtks@dark:~ % df -k
Filesystem    1024-blocks     Used     Avail Capacity  Mounted on
〜
/dev/mmcsd0s1    61089248       96  61089152     0%    /mnt

総容量が増えるわけではないようだな..

このカードは、NetBSD でも認識することが出来るかどうか。
まず、忘れずに umount して..

nsmrtks@dark:~ % sudo umount /mnt

NetBSD 機に持って行くと、

green$ disklabel sd0
# /dev/rsd0:
type: SCSI
disk: STORAGE DEVICE  
label: fictitious
flags: removable
bytes/sector: 512
sectors/track: 32
tracks/cylinder: 64
sectors/cylinder: 2048
cylinders: 59688
total sectors: 122241024
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0		# microseconds
track-to-track seek: 0	# microseconds
drivedata: 0 

5 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 d: 122241024         0     unused      0     0        # (Cyl.      0 -  59687)
 e: 122208256     32768      MSDOS                     # (Cyl.     16 -  59687)
disklabel: boot block size 0
disklabel: super block size 0

green$ sudo mount -t msdos /dev/sd0e /mnt
〜

green$ df -k
Filesystem           1K-blocks       Used      Avail %Cap Mounted on
〜
/dev/sd0e             61089184         32   61089152   0% /mnt

認識出来た。

.. df -k の Avail の値は FreeBSD と同じだが、1K-blocks と Used の値がずれているのが気になる..
さっきの newfs_msdos の -u オプションは関係あるのだろうか。 よく分からないので、デフォルトで再フォーマットしておくか..
忘れずに umount し..

green$ sudo umount /mnt

みたび FreeBSD でフォーマット..

nsmrtks@dark:~ % sudo newfs_msdos -L FAT32LBA58G /dev/mmcsd0s1
〜
/dev/mmcsd0s1: 122178368 sectors in 1909037 FAT32 clusters (32768 bytes/cluster)
BytesPerSec=512 SecPerClust=64 ResSectors=32 FATs=2 Media=0xf0 SecPerTrack=63 Heads=255 HiddenSecs=0 HugeSectors=122208256 FATsecs=14915 RootCluster=2
 FSInfo=1 Backup=2

NetBSD 機に持って行くと..

green$ sudo mount -t msdos /dev/sd0e /mnt

green$ df -k
Filesystem           1K-blocks       Used      Avail %Cap Mounted on
〜
/dev/sd0e             61089184         32   61089152   0% /mnt

変化なかった..

ファイルをコピー

実際に Windows 8.1 (正しく認識できた) でファイルを書き込み、FreeBSD (12.0 及び 11.2) で正しく読み込めることを確認した。

このとき、以下のようにマウントすると、日本語のディレクトリ/ファイル名を含んでいても正しく扱えた。

% sudo mount_msdosfs -L ja_JP.UTF-8 -D cp932 /dev/mmcsd0s1 /mnt

しかし.. タイムスタンプが 9時間ずれる..
(FAT32 の タイムスタンプが UTC になっていない Microsoft の頭の悪い仕様が根源なのだが)

これが NetBSD の mount_msdos だと、環境のタイムゾーン設定に合わせてタイムスタンプを解釈したりする機能があるのだ。
しかし今度は日本語のディレクトリ/ファイル名を解釈する機能が見当たらない。 それよりも、全部小文字のファイル(ディレクトリ)名が、全部大文字になってしまうことがあるという現象も見られた。

FreeBSD や NetBSD で、日本語を含むディレクトリ/ファイル名が正しく扱えて、かつタイムスタンプがずれないといいのだが..

以上


index