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

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

当我运行时,arm-none-eabi-objcopy -O binary add.elf add.bin一切似乎都正常。但是,稍后当我运行时,ls -lh add.bin add.elf这是我收到的输出:

-rw-r--r-- 1 大卫 大卫 2,6G 11 月 23 日 22:49 add.bin
-rwxr-xr-x 1 大卫 大卫 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

节大小地址
.文本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起始地址 */
        。数据 :{
                * (。数据);
        }
}

上面的代码从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;
}

然后在源代码中我添加了一段将数据从闪存复制到 RAM 的内容。像这样的东西:

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

复制:
        ldrb r4,[r0],#1
        strb r4,[r1],#1
        子 r2,r2,#1
        复制品

如果我的英语不是太精确的话,这就是关联这有助于我解决问题。 (也是学习 ARM 嵌入式编程的好网站)。

答案1

我认为这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

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

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

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

相关内容