ls는 대용량 파일을 보고하지만 du는 보고하지 않는 이유는 무엇입니까?

ls는 대용량 파일을 보고하지만 du는 보고하지 않는 이유는 무엇입니까?

달리면 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 추가.빈

여기서 무슨 일이 일어나고 있는 걸까요?

편집 : 출력 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 시작 주소*/
        . 데이터:{
                * (.data);
        }
}

위의 코드는 0x00000000에서 0xA0000000까지 0으로 채워집니다. 이 오류는 다음을 통해 해결할 수 있습니다.

장{
        . = 0x00000000;
        . 텍스트: {
                * (.텍스트);
        }
        flash_sdata = .; /* 플래시의 텍스트 직후에 데이터 시작 */

        . = 0xA0000000; /* RAM 시작 주소*/
        ram_sdata = .;

        /* AT는 로딩 주소를 지정합니다. .data 섹션*/
        .data : AT (flash_sdata) {
                * (.data);
        }
        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
        서브2, 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자만 사용된 4KB 블록이 있습니다. 그러나 일반적인 방법으로(처음부터 순차적으로) 파일을 읽으면 foo.

Linux에서는 du일반적으로 스파스 파일의 실제 디스크 사용량을 보고하는 것이 가능합니다. ls -loptions 를 전달하여 "겉보기 크기"(보고된 내용과 더 유사함)를 보고하도록 지시할 수 있습니다 -b. 이것은 Gnu 확장입니다. Posix는 du희소 파일 크기에 대한 정확한 보고를 요구하지 않습니다. ("메소드가 얼마나 정확한지 정의하는 것은 구현에 달려 있습니다.")

아마도 ELF 형식을 RAM 이미지로 확장 하고 파일을 0으로 채우는 대신 이를 찾아 이미지를 채운다는 점에서 arm-none-eabi-objcopy위의 예와 매우 유사한 작업을 수행할 것입니다 . 실제로 이는 미사용 블록 비용을 발생시키지 않고 메모리 매핑( )이 가능한 희소 파일의 전형적인 사용 사례입니다.ddexemmap

관련 정보