por que ls reporta um arquivo enorme e du não?

6

Quando executo arm-none-eabi-objcopy -O binary add.elf add.bin , tudo parece estar ok. Mas, mais tarde, quando eu executar ls -lh add.bin add.elf , esta é a saída que recebi:

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

este é um arquivo enorme. Mas quando eu corro du -h add.bin , a saída é:

8,0K    add.bin

O que está acontecendo aqui?

Editar: Saída de arm-none-eabi -A -t -x add.bin :

 Warning: could not locate 'add.bin'.  reason: Value too large for defined data type

Saída de arm-none-eabi -A -t -x add.elf :

section           size         addr
.text             0x2c          0x0
.data              0xc   0xa0000000
.ARM.attributes   0x14          0x0
Total             0x4c

Saída de du -bh add.bin :

2,6G    add.bin

Foi assim que consertei:

Inicialmente, quando eu vincular o programa com o comando arm-none-eabi-ld -Tld_script.lds -o add.elf add.o , o arquivo de script ld ld_script.lds contém isso:

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

        . = 0xA0000000;  /* RAM starting address */
        .data :{ 
                * (.data); 
        }
}

O código acima preenche de 0x00000000 a 0xA0000000 com 0s. Este erro pode ser resolvido da seguinte maneira:

SECTIONS {
        . = 0x00000000;
        .text : { 
                * (.text); 
        }
        flash_sdata = .; /* Start data in flash right after the text */

        . = 0xA0000000;  /* RAM starting address */
        ram_sdata = .;

        /* AT specifies the load addr. of .data section */
        .data : AT (flash_sdata) { 
                * (.data); 
        }
        ram_edata = .;   /* Address of end of data in RAM */
        data_size = ram_edata - ram_sdata;
}

E, na fonte, adicionei uma peça para copiar os dados do Flash para a RAM. Algo parecido com isto:

        @ Copy data to RAM.
start:
        ldr   r0, =flash_sdata
        ldr   r1, =ram_sdata
        ldr   r2, =data_size

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

Se o meu inglês não for muito preciso, este é o link que me ajuda para consertar o problema. (E um bom site para aprender programação embarcada ARM).

    
por David Martínez 23.11.2013 / 22:59

1 resposta

8

Suponho que add.bin seja um arquivo esparso.

A maioria dos sistemas de arquivos unix suportam arquivos esparsos (de tamanhos quase arbitrários). Basicamente, você pode procurar um offset arbitrário antes de começar a escrever, e os blocos que você pula não serão realmente mapeados para o disco. Se você tentar lê-los, eles estarão cheios de 0s. Se você escrever para eles, eles vão surgir magicamente (mas apenas aqueles para os quais você escreve).

Veja um exemplo:

$ 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

O arquivo que criei tem um bloco de 4 kilobytes em disco, dos quais apenas os quatro primeiros caracteres são usados. Mas se você ler o arquivo da maneira normal (sequencialmente desde o começo), você terá que ler um gigabyte de zeros antes de encontrar o foo .

No Linux, du normalmente é capaz de relatar o uso real do disco de um arquivo esparso. Você pode informá-lo para informar o "tamanho aparente" (que será mais parecido com o que ls -l reporta) passando a opção -b . Essa é uma extensão do Gnu; O Posix não exige que du seja preciso em seus relatórios de tamanhos de arquivos esparsos. ("Cabe à implementação definir exatamente como seus métodos são precisos").

Presumivelmente, arm-none-eabi-objcopy faz algo semelhante ao exemplo dd acima, pois expande o exe formatado em ELF em uma imagem RAM e preenche a imagem procurando em vez de preencher o arquivo com zeros. Este é, na verdade, o caso de uso clássico para arquivos esparsos, que podem ser mapeados na memória ( mmap ) sem incorrer em um custo para blocos não utilizados.

    
por 23.11.2013 / 23:21

Tags