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 からいれたいなーと思った。やらんけど。