Warum meldet er eine riesige Datei und du nicht?

7

Wenn ich arm-none-eabi-objcopy -O binary add.elf add.binrenne, scheint alles in Ordnung zu sein. Aber später, wenn ich es ausführe, ist ls -lh add.bin add.elfdies die Ausgabe, die ich erhalten habe:

-rw-r - r-- 1 David David 2,6G 23. November 22:49 add.bin
-rwxr-xr-x 1 david david 65K 23. November 22:40 add.elf

Dies ist eine riesige Datei. Aber wenn ich du -h add.bindie Ausgabe starte, ist:

8,0K add.bin

Was passiert hier?

Edit: Ausgabe von arm-none-eabi -A -t -x add.bin:

Warnung: 'add.bin' konnte nicht gefunden werden. Grund: Wert zu groß für definierten Datentyp

Ausgabe von arm-none-eabi -A -t -x add.elf:

Abschnittsgröße Adr
.text 0x2c 0x0
.data 0xc 0xa0000000
.ARM.attributes 0x14 0x0
Insgesamt 0x4c

Ausgabe von du -bh add.bin:

2,6G add.bin

So habe ich es behoben:

Wenn ich das Programm mit dem Befehl verknüpfe, enthält arm-none-eabi-ld -Tld_script.lds -o add.elf add.odie ld-Skriptdatei zunächst Folgendes ld_script.lds:

ABSCHNITTE {
        . = 0x00000000;
        .text: { 
                * (.text); 
        }}

        . = 0xA0000000; / * RAM-Startadresse * /
        .Daten :{ 
                * (.Daten); 
        }}
}}

Der obige Code wird von 0x00000000 bis 0xA0000000 mit 0s gefüllt. Dieser Fehler kann folgendermaßen behoben werden:

ABSCHNITTE {
        . = 0x00000000;
        .text: { 
                * (.text); 
        }}
        flash_sdata = .; / * Startet die Daten in Flash direkt nach dem Text * /

        . = 0xA0000000; / * RAM-Startadresse * /
        ram_sdata = .;

        / * AT gibt die Lastadresse an. von .data Abschnitt * /
        .data: AT (flash_sdata) { 
                * (.Daten); 
        }}
        ram_edata = .; / * Adresse des Datenendes im RAM * /
        data_size = ram_edata - ram_sdata;
}}

Und dann habe ich in der Quelle ein Stück hinzugefügt, um die Daten von Flash in den RAM zu kopieren. Etwas wie das:

        @ Daten in RAM kopieren.
Start:
        ldr r0, = flash_sdata
        ldr r1, = ram_sdata
        ldr r2, = data_size

Kopieren:
        ldrb r4, [r0], # 1
        strb r4, [r1], # 1
        subs r2, r2, # 1
        bne Kopie

Wenn mein Englisch nicht zu genau ist, ist dies der Link, der mir hilft, das Problem zu beheben. (Und eine gute Seite zum Erlernen der eingebetteten ARM-Programmierung).

David Martínez
quelle
Dieser Thread klingt wie es mit Ihrem Q zusammenhängt: embdev.net/topic/150574
slm
Auf den ersten Blick sieht es so aus, als würde entweder die resultierende .bin-Datei nicht komprimiert oder sie enthält Speicherabschnitte (.data) in Ihrer .bin-Datei, die dazu führen, dass die Größe unangemessen groß ist.
slm
Was meldet dieser Befehl für die resultierenden Dateien? arm-none-eabi-size.exe -A -t -x <file>.
slm
Was ist die Ausgabe von du -bh add.bin?
Ein Lebenslauf

Antworten:

9

Ich nehme an, das add.binist eine spärliche Datei.

Die meisten Unix-Dateisysteme unterstützen spärliche Dateien (mit nahezu beliebiger Größe). Grundsätzlich können Sie vor dem Schreiben einen beliebigen Versatz anstreben, und die Blöcke, die Sie überspringen, werden nicht tatsächlich der Festplatte zugeordnet. Wenn Sie versuchen, sie zu lesen, sind sie voller Nullen. Wenn Sie ihnen schreiben, entstehen sie auf magische Weise (aber nur die, an die Sie schreiben).

Hier ist ein Beispiel:

$ 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

Die von mir erstellte Datei enthält einen 4-Kilobyte-Block auf der Festplatte, von dem nur die ersten vier Zeichen verwendet werden. Wenn Sie die Datei jedoch auf normale Weise (von Anfang an nacheinander) lesen, müssen Sie ein Gigabyte Nullen durchlesen, bevor Sie auf die stoßen foo.

Unter Linux kann dunormalerweise die tatsächliche Festplattennutzung einer Datei mit geringer Dichte gemeldet werden. Sie können festlegen, dass die "scheinbare Größe" (die den ls -lBerichten ähnlicher ist ) angegeben wird, indem Sie die -bOption übergeben. Das ist eine Gnu-Erweiterung. Posix muss dubei der Berichterstattung über spärliche Dateigrößen nicht genau sein. ("Es liegt an der Implementierung, genau zu definieren, wie genau die Methoden sind.")

Vermutlich arm-none-eabi-objcopymacht es etwas Ähnliches wie das ddobige Beispiel, indem es das ELF-formatierte exein ein RAM-Image erweitert und das Bild durch Suchen füllt, anstatt die Datei mit Nullen zu füllen. Dies ist in der Tat der klassische Anwendungsfall für Dateien mit geringer Dichte, die speicherabgebildet werden können ( mmap), ohne dass Kosten für nicht verwendete Blöcke anfallen.

Rici
quelle
Die Links, auf die ich verwies, sagten dies im Grunde.
slm
@slm: Ich sehe nur einen Link; Ich überflog die ersten paar Screenfulls, sah aber nichts Relevantes.
Rici
Ja, deshalb habe ich gesagt, dass es "im Grunde" so ist. Sie sagten es präziser, aber Zeilen wie diese: "Ich denke, Sie haben die Bin-Datei angefordert, sowohl RAM- als auch FLASH-Bereich zu enthalten." sagen im Wesentlichen, dass die Datei mit spärlichen Daten geladen ist. Es gibt diesen SO-Link, auf den ich auch hier noch nicht verwiesen habe: stackoverflow.com/questions/9725268/… . Ihre Antwort ist das "Was", aber wir vermissen immer noch das "Warum".
slm
1
Nun, ich habe es behoben. Das Problem war das Linker-Skript. Tatsächlich füllte objcopy add.bin mit Nullen von der Adresse 0x0000002c bis 0xa000000. Dank an alle.
David Martínez
1
@ MichaelKjörling: Ein persischer König suchte einen Partner für seine Tochter. Drei Bewerber bewarben sich. Der König brachte sie zu seinem Orangenhain, wo sie am Ufer seines Sees saßen. Ein riesiger Orangenbaum wölbte sich über ihnen. Der König blinzelte auf den See und fragte: "Was schwimmt das im Schatten des Baumes?" "Na, es ist eine Orange", sagte der erste Bewerber. Der zweite sah sich die Frucht genau an und antwortete: "Nein, es ist eine Zitrone." Der dritte Bewerber watete zu den Früchten und hob sie auf. "Es ist eine halbe Zitrone", berichtete er ... Manchmal ist es am besten, nicht zu sicher zu sein , was Sie zu sehen glauben.
Rici