2019/03/30

sdcard.pyで正しく読めないSDカードを調査

ESP32でSDカードを読ませたいのだが、一部のSDカードを除き、普通にWindowsでフォーマットしたSDは正しく読めない。sdcard.pyではブロック単位でリードが可能なので(RAWデバイスとしてブロック単位で直書きができる)、SDの先頭ブロックを読んでみた。以下は正しく読めるSDの先頭ブロック(512バイト分)(マウントできるSDカード、micropython のファイルシステムで、FATファイルシステムとして認識できるSD)



fa b8 00 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0 . . . . . . . . . . . . . . . .
fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00 . . . | . . . . . . . . . ! . .
00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75 . . . . 8 . u . . . . . . . . u
f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 01 8b . . . . . . . . . | . . . t . .
4c 02 cd 13 ea 00 7c 00 00 eb fe 00 00 00 00 00 L . . . . . | . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 48 f7 0b 00 00 00 80 01 . . . . . . . . H . . . . . . .
01 00 0e f7 3e 09 3e 00 00 00 62 58 02 00 00 00 . . . . > . > . . . b X . . . .
01 0a 83 a6 cc fc a0 58 02 00 60 1f ed 00 00 00 . . . . . . . X . . ` . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa . . . . . . . . . . . . . . U .
以下は正しく読めない場合の先頭ブロック(マウント時にエラーになるSDカード、micropython のファイルシステムで、FATファイルシステムとして認識できないSD))

fa 33 c0 8e d0 bc 00 7c 8b f4 50 07 50 1f fb fc . 3 . . . . . | . . P . P . . .
bf 00 06 b9 00 01 f2 a5 ea 1d 06 00 00 be be 07 . . . . . . . . . . . . . . . .
b3 04 80 3c 80 74 0e 80 3c 00 75 1c 83 c6 10 fe . . . < . t . . < . u . . . . .
cb 75 ef cd 18 8b 14 8b 4c 02 8b ee 83 c6 10 fe . u . . . . . . L . . . . . . .
cb 74 1a 80 3c 00 74 f4 be 8b 06 ac 3c 00 74 0b . t . . < . t . . . . . < . t .
56 bb 07 00 b4 0e cd 10 5e eb f0 eb fe bf 05 00 V . . . . . . . ^ . . . . . . .
bb 00 7c b8 01 02 57 cd 13 5f 73 0c 33 c0 cd 13 . . | . . . W . . _ s . 3 . . .
4f 75 ed be a3 06 eb d3 be c2 06 bf fe 7d 81 3d O u . . . . . . . . . . . } . =
55 aa 75 c7 8b f5 ea 00 7c 00 00 49 6e 76 61 6c U . u . . . . . | . . I n v a l
69 64 20 70 61 72 74 69 74 69 6f 6e 20 74 61 62 i d   p a r t i t i o n   t a b
6c 65 00 45 72 72 6f 72 20 6c 6f 61 64 69 6e 67 l e . E r r o r   l o a d i n g
20 6f 70 65 72 61 74 69 6e 67 20 73 79 73 74 65   o p e r a t i n g   s y s t e
6d 00 4d 69 73 73 69 6e 67 20 6f 70 65 72 61 74 m . M i s s i n g   o p e r a t
69 6e 67 20 73 79 73 74 65 6d 00 00 00 00 00 00 i n g   s y s t e m . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 . . . . . . . . . . . . . . . .
04 00 06 05 e5 cb 81 00 00 00 7f df 1d 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa . . . . . . . . . . . . . . U .

sdcard.pyで、sd.readblocks(sector,buffer)の関数は正常に動作するので、SDのメディア自体は正しく認識されている。FATファイルシステムが解釈できない問題。どう違うのか、FATの仕様書と読み比べると原因が分かりそうだけど、、そこまで時間が取れない。 SD カードフォーマッターという、SDコンソーシアム?の公式フォーマットツールを使ってフォーマットしたところ、MBR領域は綺麗になったが、やはりマウント時にエラーになった。なぜだろうか。。

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 df dd 21 e5 00 00 00 02 . . . . . . . . . . ! . . . . .
04 00 06 1f ff ca 81 00 00 00 1f de 1d 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . . . . . . . . . . . . . . . .
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa . . . . . . . . . . . . . . U .

調べ切れていないが、これはフォーマットの違いではなく、SDカードの仕様に対応しきれていないのが原因ではないかと考えている。SDカードに対してReadBlocks/WriteBlocks要求を出す時、読み書きする対象の領域を指定するのに2つの方式があり、バイトアドレス指定か、ブロックアドレス指定か?に分かれている。
本来は、OCR中のCCS[30]を見てどっちかを決めないといけないそうなのだが(ElmChan氏解説記事より)、どうもこの部分が正しく実装されていないのでは?と思える(今はまだ推測)。sdcard.pyではブロックアドレス方式のSDカードしか扱えないのではないか。。 
以下は仮説含みでの自分なりの解釈

  • mountでエラーになってアクセスできないSDは1G程度の比較的容量の少ないやつ
  • エラー発生は、SDカードに対するwriteblocksコマンド実行時で、エラー内容はアドレス指定に対するアライメントエラー。1ブロックが512Bなので、512の倍数でアドレスを指定しないといけないのだが指定時はそうなっていない(これは確認済み)
  • エラーを起こしているSDはバイトアドレス指定方式のタイプと思われる
  •  sdcard.pyではブロックアドレス指定のみで実装されており、バイトアドレス指定方式の場合、上記の アライメントエラーが発生する。 
  • 一方、エラーが発生しないSDは4Gタイプでこれらはブロックアドレス方式のタイプと思われる(OCRの値を確認できていないので推測、だけど指定アドレスが小さい値なのでブロックアドレスを指定していると思われる)。だから、正常に読める。
  最初はSDカードのフォーマットの違い(MBRの配置あたり)かと思っていたけど、多分SD容量に起因する、アドレス指定方式の違いによってマウントできるSD,できないSDに分かれたと推測。 
参考にしたElmChan氏のSDカード解説
 http://elm-chan.org/docs/mmc/mmc.html
KingstonのSDアクセス手引き
https://docsplayer.net/41452623-Kingston-technology.html

1 comment:

  1. whoami3/31/2019

    お久しぶりですが。
    「マウントできません」的なエラーでしょうか...。

    MBRのダンプを見ると、FATとして読めるというSDは、
    ・アクティブフラグがセットされている(bootable)
    ・ファイルシステムは、FAT16 の LBA(Logical Block Access)
    になってますね。
    読めないという 2つのSDは、共に
    ・アクティブフラグがリセットされている(bootableではない)
    ・ファイルシステムは、普通のFAT16 (CHS形式?~昔のCylinder/Head/Sector)
    になっています。

    sdcard.py の仕様を知らないので何とも言えませんが、FAT32でフォーマット/
    exFATでフォーマットしてみては如何でしょう?

    見当違いでしたら、すみません。それでは。

    ReplyDelete