当我运行时,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 嵌入式编程的好网站)。
我想这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
) 而不会产生未使用块的成本。