为什么 ls 报告一个大文件而 du 没有?

Dav*_*nez 7 ls disk-usage

当我运行时,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 add.bin

这里发生了什么事?

编辑:输出arm-none-eabi -A -t -x add.bin

警告:找不到“add.bin”。原因:对于定义的数据类型,值太大

的输出arm-none-eabi -A -t -x add.elf

节大小地址
.text 0x2c 0x0
.data 0xc 0xa0000000
.ARM.attributes 0x14 0x0
总计 0x4c

的输出du -bh add.bin

2,6G add.bin

这是我修复它的方式:

最初,当我将程序与命令链接时arm-none-eabi-ld -Tld_script.lds -o add.elf add.o,ld 脚本文件ld_script.lds包含以下内容:

部分{
        . = 0x00000000;
        。文本 : { 
                * (。文本); 
        }

        . = 0xA0000000; /* RAM 起始地址 */
        。数据 :{ 
                * (。数据); 
        }
}

上面的代码从 0x00000000 到 0xA0000000 用 0 填充。可以通过以下方式解决此错误:

部分{
        . = 0x00000000;
        。文本 : { 
                * (。文本); 
        }
        flash_sdata = .; /* 在文本之后立即开始闪存中的数据 */

        . = 0xA0000000; /* RAM 起始地址 */
        ram_sdata = .;

        /* AT 指定加载地址。.data 部分 */
        .data : AT (flash_sdata) { 
                * (。数据); 
        }
        ram_edata = .; /* RAM 中数据结束的地址 */
        data_size = ram_edata - ram_sdata;
}

然后在源代码中我添加了一个片段来将数据从 Flash 复制到 RAM。像这样的东西:

        @ 将数据复制到 RAM。
开始:
        ldr r0, = flash_sdata
        ldr r1,=ram_sdata
        ldr r2, = 数据大小

复制:
        ldrb r4, [r0], #1
        strb r4, [r1], #1
        潜艇 r2, r2, #1
        复制

如果我的英语不太准确,这是帮助我解决问题的链接。(也是学习 ARM 嵌入式编程的好网站)。

ric*_*ici 9

我想这add.bin是一个稀疏文件。

大多数 unix 文件系统支持稀疏文件(几乎任意大小)。基本上,您可以在开始写入之前寻找任意偏移量,并且您跳过的块实际上不会映射到磁盘。如果您尝试阅读它们,它们将充满 0。如果你给他们写信,他们会神奇地出现(但只有你写信的人)。

下面是一个例子:

$ 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
Run Code Online (Sandbox Code Playgroud)

我创建的文件在磁盘上有一个 4 KB 的块,其中只使用了前四个字符。但是,如果您以正常方式(从头开始按顺序)读取文件,则必须在遇到foo.

在 Linux 上,du通常能够报告稀疏文件的实际磁盘使用情况。您可以ls -l通过将-b选项传递给它来告诉它报告“表观大小”(这将更类似于报告的内容)。那是一个 Gnu 扩展;Posixdu在报告稀疏文件大小时不需要准确。(“由实现来定义其方法的准确程度。”)

据推测,arm-none-eabi-objcopy它执行的操作与dd上面的示例非常相似,因为它将 ELF 格式exe的图像扩展为 RAM 图像,并通过查找而不是用零填充文件来填充图像。事实上,这是稀疏文件的经典用例,可以进行内存映射 ( mmap) 而不会产生未使用块的成本。