lsは大容量ファイルを報告しますが、duは報告しないのはなぜですか?

lsは大容量ファイルを報告しますが、duは報告しないのはなぜですか?

走るとarm-none-eabi-objcopy -O binary add.elf add.bin、すべてが大丈夫だと思います。ただし、後で実行すると、ls -lh add.bin add.elf次の結果が表示されます。

-rw-r--r-- 1 David David 2,6G 11月23日、22:49 add.bin
-rwxr-xr-x 1 David David 65K 11月23日、22:40 add.elf

これは巨大なファイルです。しかし、実行すると、du -h add.bin出力は次のようになります。

8,0K追加

ここで何が起こっているのでしょうか?

編集:出力arm-none-eabi -A -t -x add.bin

警告: 'add.bin'が見つかりません。原因:定義されたデータ型と比較して値が大きすぎます。

出力arm-none-eabi -A -t -x add.elf

セクションサイズアドレス
.テキスト0x2c 0x0
.data 0xc 0xa0000000
.ARM.プロパティ 0x14 0x0
合計0x4c

出力du -bh add.bin

2,6G追加.bin

これが私が直した方法です。

最初にコマンドを使用してプログラムをリンクしたとき、arm-none-eabi-ld -Tld_script.lds -o add.elf add.oldスクリプトファイルにはld_script.lds次のものが含まれていました。

章{
        。 = 0x00000000;
        。テキスト:{
                *(.テキスト);
        }

        。 = 0xA0000000; /* RAMスタートアドレス*/
        。データ:{
                *(.data);
        }
}

上記のコードは0x00000000から0xA0000000まで0で埋められます。このエラーは次の方法で解決できます。

章{
        。 = 0x00000000;
        。テキスト:{
                *(.テキスト);
        }
        flash_sdata=.; /* Flash のテキストの直後にデータを開始 */

        。 = 0xA0000000; /* RAMスタートアドレス*/
        ram_sdata=.;

        / * ATはロードアドレスを指定します。 .data セクション*/
        .data:AT(flash_sdata){
                *(.data);
        }
        ram_edata=.; /* RAMのデータの終了アドレス*/
        data_size = ram_edata - ram_sdata;
}

次に、ソースコードにフラッシュからRAMにデータをコピーするセクションを追加しました。このような:

        @RAMにデータをコピーします。
スタート:
        ldr r0,=flash_sdata
        ldr r1、=ram_sdata
        ldr r2、=データサイズ

コピー:
        ldrb r4,[r0],#1
        strb r4,[r1],#1
        サブ2、r2、#1
        レプリカ

私の英語があまりにも正確ではない場合、これは協会これは問題を解決するのに役立ちます。 (ARM組み込みプログラミングを学ぶのに最適なウェブサイトです。)

答え1

私の考えでは、これがadd.bin希薄なファイルのようです。

ほとんどのUNIXファイルシステムは、スパースファイル(ほぼすべてのサイズ)をサポートしています。デフォルトでは、書き込みを開始する前に任意のオフセットを見つけることができ、スキップされたブロックは実際にディスクにマップされません。読もうとするとゼロで埋められます。あなたがその人に手紙を書くと、その人は魔法のように見えます(ただし、あなたが書いた人にのみ当てはまります)。

例は次のとおりです。

$ dd of=sparse obs=1K seek=1M if=<(echo foo)
0+1 records in
0+1 records out
4 bytes (4 B) copied, 0.000411909 s, 9.7 kB/s
$ ls -lh sparse
-rw-r--r-- 1 rici rici 1.1G Nov 23 17:22 sparse
$ du -h sparse
4.0K    sparse

私が作成したファイルのディスクには、最初の4文字しか使用されていない4KBブロックがあります。しかし、通常の方法で(最初から順番に)ファイルを読むとfoo

Linuxでは、du通常、スパースファイルの実際のディスク使用量を報告することができます。ls -loptionsを渡して、「見かけのサイズ」(報告されたものと似ている)を報告するように指示できます-b。これはGnu拡張です。 Posixは、du希少ファイルサイズの正確な報告を必要としません。 (「メソッドがどれだけ正確かを定義するのは実装に依存します。」)

おそらく、ELF形式をRAMイメージに拡張し、ファイルをゼロで埋めるのではなく、それを見つけてイメージを埋めるという点で、上記arm-none-eabi-objcopyの例と非常によく似た作業を実行します。実際、これは未使用のブロックコストを発生させることなくメモリマッピング()が可能なスパースファイルの典型的なユースケースです。ddexemmap

関連情報