Armadilloフォーラム

イメージファイル書き込み時のデータ化け対策について

yanagihara

2014年9月11日 15時44分

こんにちは、柳原と申します。

フラッシュ書き換えにまつわるデータ化け対策の現状について教えて下さい。

データ化けの発生タイミングとしては
 (a) 記録メディア異常や誤操作によるイメージファイルのデータ化け
 (b) 伝送中のデータ化け
 (c) Armadillo側のフラッシュ書き込み処理異常によるデータ化け
 (d) Armadillo側のフラッシュ寿命等によるデータ化け
などがあると思います。

データ化け検出方法として、
(1) イメージファイルのチェックサム検査 → (a)
 (2) 通信プロトコルの誤り検出機能 → (b)
 (3) フラッシュROM読み出し値のチェックサム検査 → (c)・(d)
などが考えられます。

このうち(2)と(3)について教えて下さい。

質問その1:
(2)についてですが、tftpdlやnetflashの様なLAN経由の方法ではTFTPやTCPの
プロトコルによる伝送誤り検出が機能すると思います。

一方、RS-232Cを経由するhermit-at-win32によるDownloadではどういう
対策になっているのでしょうか?
(一応、ソースコードを見ましたが理解するには至りませんでした。)

質問その2:
(3)についてですが、Atmark-Distでは何か対策をしていますか?

/atmark-dist/vendors/AtmarkTechno/Armadillo-440/Makefileのimageターゲッ
トの末尾で以下の様にチェックサムが付加されますが、試しにチェックサムを
書き換えてhermit-at-win32でのDownloadやブートローダのtftpdlを実行して
みましたが、特にエラーは発生せず、そのままフラッシュに書き込まれました。

    $(CKSUM) -b -o 2 $(ROMFSIMG)  >> $(ROMFSIMG)
    $(CKSUM) -b -o 2 $(ZROMFSIMG) >> $(ZROMFSIMG)
    $(CKSUM) -b -o 2 $(LINUXBIN)  >> $(LINUXBIN)
    $(CKSUM) -b -o 2 $(ZLINUXBIN) >> $(ZLINUXBIN)

また、OSも起動いつも通り起動しました。

従って、イメージファイル末尾のチェックサムが利用されているわけでもなく、
また他にデータ化けを検出する処理が行われているようにも感じませんで
した。

コメント

at_makoto.harada

2014年9月11日 21時45分

原田です。

>質問その1:
>(2)についてですが、tftpdlやnetflashの様なLAN経由の方法ではTFTPやTCPの
>プロトコルによる伝送誤り検出が機能すると思います。

通信プロトコルによる誤り検出機能に関してですが、
1. Hermit-At ブートローダのtftpdl機能はUDP通信で行っております。
2. Hermit-At ブートローダのdownload機能はRS-232C通信です。
3. linux上で実行するnetflashはTCP通信です。

従って#1, #2は誤り検出機能は有しておりません。
#3はTCPのプロトコルにより誤りが検出された場合再送処理が実施されます。

>質問その2:
>(3)についてですが、Atmark-Distでは何か対策をしていますか?

書き込んだフラッシュROMの内容は以下のようにして確認することができます。

1. ブートローダ起動時
hermit-at では書き込んだイメージの確認にmd5sumコマンドが利用できます。
http://manual.atmark-techno.com/armadillo-4x0/armadillo-400_series_soft…

以下のFAQを参考にしてみてください。
"FAQ : フラッシュメモリに正しく書き込めたことを確認するには?"
http://armadillo.atmark-techno.com/faq/hermit_md5

2. linux起動時
netflash には、書き込まれたイメージのチェックを行う機能があります。
以下のスレッドが参考になるかと思います。
http://lists.atmark-techno.com/pipermail/armadillo/2013-October/009244…

柳原です。

>>質問その1:
>>(2)についてですが、tftpdlやnetflashの様なLAN経由の方法ではTFTPやTCPの
>>プロトコルによる伝送誤り検出が機能すると思います。
>
>通信プロトコルによる誤り検出機能に関してですが、
>1. Hermit-At ブートローダのtftpdl機能はUDP通信で行っております。
>2. Hermit-At ブートローダのdownload機能はRS-232C通信です。
>3. linux上で実行するnetflashはTCP通信です。
>
>従って#1, #2は誤り検出機能は有しておりません。
>#3はTCPのプロトコルにより誤りが検出された場合再送処理が実施されます。

#1についてですが、UDPパケットにもチェックサムはありますし、Wiresharkで
tftpdlの経過を観察したところ妥当なチェックサム値が入っていました。
また、UDPはストリーム指向ではありますが、TFTPプロトコル側で肯定応答と
タイムアウトによる再送制御が行われますので、誤り検出機能が全く無いという
わけではないと思います。

一方、#2についてですが、hermitのソースコードの中にCRCという文字が散見
されたので、もしや誤り検出機能を持っているのではと期待していたのですが、
「hermitのRS-232C転送には誤り検出機能は無い」が正解ということでしょうか?

>>質問その2:
>>(3)についてですが、Atmark-Distでは何か対策をしていますか?
>
>書き込んだフラッシュROMの内容は以下のようにして確認することができます。
>
>1. ブートローダ起動時
> hermit-at では書き込んだイメージの確認にmd5sumコマンドが利用できます。

md5sumコマンドについては存じておりますが、自動的にベリファイする機能は
無いということでしょうか。

>2. linux起動時
> netflash には、書き込まれたイメージのチェックを行う機能があります。

ありがとうございます、調べてみます。
netflashは使う予定が無いので、あまり調べていませんでした。

柳原です。

すみません、一部、書き間違えました。

> また、UDPはストリーム指向ではありますが、TFTPプロトコル側で肯定応答と

「UDPはストリーム指向」は変ですね。
「UDPはコネクションレス」とすべきでした。

at_makoto.harada

2014年9月16日 13時31分

原田です。

>#1についてですが、UDPパケットにもチェックサムはありますし、Wiresharkで
>tftpdlの経過を観察したところ妥当なチェックサム値が入っていました。
>また、UDPはストリーム指向ではありますが、TFTPプロトコル側で肯定応答と
>タイムアウトによる再送制御が行われますので、誤り検出機能が全く無いという
>わけではないと思います。

ご指摘の通り、下位レイヤーでCRCエラー等を検知しフレームが破棄された場合、
TFTPレイヤーにて再送処理が実施されますね。失礼いたしました。

>一方、#2についてですが、hermitのソースコードの中にCRCという文字が散見
>されたので、もしや誤り検出機能を持っているのではと期待していたのですが、
>「hermitのRS-232C転送には誤り検出機能は無い」が正解ということでしょうか?

hermitのソースを確認したところ、以下に示す通り32bit CRC値を用いた誤り検出を実施してます。

#hermit-at/src/host/common/download.c
 
static void do_download(target_context_t *tc,
            const void *data, tsize_t count,
            download_dest_t dest, taddr_t addr)
{
    ...
 
    crc = crc32(data, count);
    ...
        snprintf(cmdbuf, sizeof cmdbuf,
            "download buf %ld 0x%08x",
            (unsigned long) count, crc);
    ...
    target_retry_command_and_data(tc, cmdbuf, data, count);
}
 
int target_retry_command_and_data(target_context_t *tc,
                   const char *command,
                   const void *data, size_t count)
{
    int retries = 3;
 
    while (retries--) {
        msgf("trying command/data (retries = %d)\n", retries);
        target_write_command(tc, command);
        if (target_get_response(tc))
            continue;
        target_write_data(tc, data, count);
        if (target_get_response(tc) == 0)
            return 0;
    }
    panic("command/data write retry count exceeded.");
    return -1;
}

>/atmark-dist/vendors/AtmarkTechno/Armadillo-440/Makefileのimageターゲッ
>トの末尾で以下の様にチェックサムが付加されますが、試しにチェックサムを
>書き換えてhermit-at-win32でのDownloadやブートローダのtftpdlを実行して
>みましたが、特にエラーは発生せず、そのままフラッシュに書き込まれました。

atmark-dist環境で付加されたチェックサム値は、netflash で使用できます。
netflashのデフォルト設定ではチェックサム値を計算し、データの整合性を確認します。
エラーの場合は以下のようなメッセージが表示され、書き込みは実施されません。
(-n オプションを付与すると、チェックサムは行いません。)

[armadillo]# /tmp/netflash -b -k -u -s -r /dev/mtd4
....
....
netflash: got "http://172.16.42.5/linux2.bin.gz", length=2824045
netflash: bad image checksum=0xcaf9, expected checksum=0xcaf8

柳原です。

ご回答有難うございました。

ホスト/ターゲット間のdownloadコマンドのシリアル通信でCRCで誤り
検出が行われている旨、了解しました。

ちなみにターゲット側の処理は/src/target/command/download.cの
download_cmdfunc関数なんですね。