当我运行时,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.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; }
然后在源代码中我添加了一段将数据从闪存复制到 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
),而不会产生未使用块的成本。