file system driver その2
fragment 関連のテストがかなり雑な状態で、メモリーカード(SDC)を SPI でつなぐところまでできた。
MBR が入っている
実機で動かして気づいたんだが、つないだメモリーカードの先頭セクタは fat のパラメータではなくてパーティションテーブルが入っていた。イメージファイルではそれが含まれていない状態だったのでテストが出来ていなかった。
パーティションテーブルのイメージは linux の fdisk コマンド作ることが出来る。0x200 byte を 0 fill したファイルを $ /sbin/fdisk imagefile とすれば動く(root権限不要)。パーティションテーブルがついた状態のイメージを mkfs でフォーマットすることはどうやらできないみたい。パーティションテーブルとフォーマット済みの fat イメージと連結することでそういうイメージを作ることが出来る。 (おそらく /dev/sda がパーティションテーブル付きのデバイスで、これを fdisk で操作するものの、各パーティションは /dev/sda1 などで操作して mkfs をするからと思われる)
実デバイスなら得られる物理ヘッド数、セクタ数などをイメージファイルの場合は自分で計算して矛盾無く設定することが求められる。面倒くさいので、メモリーカードの先頭8M を dd でイメージつくって、ルートディレクトリのエントリが読めることを確認して終わった。
その後対応済みのソースでメモリーカードを直接見に行ったらファイルもとれたのでよしとする。
native mode
SPI はとりあえず確認のためだけで、本質は native mode だったりする。MMC だと stream 転送というのができるらしいが、 SDC ではない。残念。たまに検索されている CRC7 のソースを書いたのでみんな使うといいさ。
=begin CRC7 shift register input --v-------v | +---+ | +---+ @>|0:2|>@>|3:6|----> output | +---+ | +---+ | @ is xor^-------^-------/ output = old[6]; new[0] = input ^ output; new[1:2] = old[0:1]; new[3] = old[2] ^ input ^ output; new[4:6] = old[3:5]; =end def shift(crc, d) carry = crc >> 6 carry &= 1 crc <<= 1 crc &= 0x7f crc |= d ^ carry #bit0 crc ^= (d ^ carry) << 3 #bit3 return crc end def calc40_shift(v) crc = 0 40.times{ d = v >> 39 crc = shift(crc, d) v <<= 1 v &= 0xff_ffff_ffff } crc <<= 1 #MMC command packet crc7 field to bit7:1 crc |= 1 #bit 0 is stop bit (1) printf("%02x ", crc) return crc end
多項式の説明は実は理解できてないし、C で書いたようなソースはいろいろ処理をはしょっていて意味がわからない。結局はシフトレジスタの図をみてハードウェア都合で実装するんだが、シフトレジスタの図がすごくみづらくて時間をかけてしまった。
あとは、シフトレジスタというのは msb, lsb の順番はわりとどうでもよいので実装するときにそれが逆になってたりする。ソフトでの値の表記から MSB を順番に入れていったが 無駄な bitshift 多いので、 bit reverse して LSB からいれたいなーと思った。やらんけど。