Tại sao ls báo cáo một tập tin lớn và du không?


7

Khi tôi chạy arm-none-eabi-objcopy -O binary add.elf add.binmọi thứ có vẻ ổn. Nhưng, sau này khi tôi chạy, ls -lh add.bin add.elfđây là đầu ra tôi nhận được:

-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

đây là một tập tin lớn Nhưng khi tôi chạy du -h add.binđầu ra là:

Thêm 8,0K.bin

Chuyện gì đang xảy ra ở đây vậy?

Chỉnh sửa: Đầu ra của arm-none-eabi -A -t -x add.bin:

Cảnh báo: không thể định vị 'add.bin'. Lý do: Giá trị quá lớn đối với loại dữ liệu được xác định

Đầu ra của arm-none-eabi -A -t -x add.elf:

phần kích thước phần bổ sung
.text 0x2c 0x0
.data 0xc 0xa0000000
.ARM.attribut 0x14 0x0
Tổng 0x4c

Đầu ra của du -bh add.bin:

Thêm 2,6G.bin

Đây là cách tôi sửa nó:

Ban đầu khi tôi liên kết chương trình với lệnh arm-none-eabi-ld -Tld_script.lds -o add.elf add.o, tập lệnh ld ld_script.ldschứa tệp này:

PHẦN {
        . = 0x00000000;
        .bản văn : { 
                * (.bản văn); 
        }

        . = 0xA0000000; / * Địa chỉ bắt đầu RAM * /
        .dữ liệu :{ 
                * (.dữ liệu); 
        }
}

Đoạn mã trên điền từ 0x00000000 đến 0xA0000000 với 0s. Lỗi này có thể được giải quyết theo cách sau:

PHẦN {
        . = 0x00000000;
        .bản văn : { 
                * (.bản văn); 
        }
        flash_sdata = .; / * Bắt đầu dữ liệu trong flash ngay sau văn bản * /

        . = 0xA0000000; / * Địa chỉ bắt đầu RAM * /
        ram_sdata = .;

        / * AT chỉ định addr tải. của phần .data * /
        .data: AT (flash_sdata) { 
                * (.dữ liệu); 
        }
        ram_edata = .; / * Địa chỉ kết thúc dữ liệu trong RAM * /
        data_size = ram_edata - ram_sdata;
}

Và sau đó trong nguồn tôi đã thêm một phần để sao chép dữ liệu từ Flash sang RAM. Một cái gì đó như thế này:

        @ Sao chép dữ liệu vào RAM.
khởi đầu:
        ldr r0, = flash_sdata
        ldr r1, = ram_sdata
        ldr r2, = data_size

bản sao:
        ldrb r4, [r0], # 1
        strb r4, [r1], # 1
        subs r2, r2, # 1
        bản sao

Nếu tiếng Anh của tôi không quá chính xác, đây là liên kết giúp tôi khắc phục vấn đề. (Và một trang web tốt để học lập trình nhúng ARM).


Chủ đề này nghe có vẻ liên quan đến Q: embdev.net/topic/150574
slm

Nhìn bề ngoài, có vẻ như tệp .bin kết quả không bị nén hoặc nó bao gồm các phần bộ nhớ (.data) trong tệp .bin của bạn khiến tệp có kích thước không phù hợp quá lớn.
slm

Lệnh này báo cáo gì cho các tập tin kết quả? arm-none-eabi-size.exe -A -t -x <file>.
slm

Đầu ra của du -bh add.bincái gì?
một CVn

Câu trả lời:


9

Tôi cho rằng đó add.binlà một tập tin thưa thớt.

Hầu hết các hệ thống tệp unix đều hỗ trợ các tệp thưa thớt (có kích thước gần như tùy ý). Về cơ bản, bạn có thể tìm cách bù trừ tùy ý trước khi bắt đầu ghi và các khối bạn bỏ qua sẽ không thực sự được ánh xạ vào đĩa. Nếu bạn cố đọc chúng, chúng sẽ đầy 0. Nếu bạn viết thư cho họ, họ sẽ kỳ diệu tồn tại (nhưng chỉ những người bạn viết).

Đây là một ví dụ:

$ 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

Tệp tôi tạo có một khối 4 kilobyte trên đĩa, trong đó chỉ có bốn ký tự đầu tiên được sử dụng. Nhưng nếu bạn đọc tệp theo cách thông thường (tuần tự từ đầu), bạn sẽ phải đọc qua một gigabyte số không trước khi bạn gặp phải foo.

Trên Linux, duthông thường có thể báo cáo việc sử dụng đĩa thực tế của một tệp thưa. Bạn có thể yêu cầu nó báo cáo "kích thước rõ ràng" (sẽ giống với ls -lbáo cáo hơn) bằng cách chuyển -btùy chọn này. Đó là một phần mở rộng Gnu; Posix không yêu cầu duphải chính xác trong báo cáo về kích thước tệp thưa thớt. ("Tùy thuộc vào việc triển khai để xác định chính xác các phương thức của nó chính xác đến mức nào.")

Có lẽ, arm-none-eabi-objcopythực hiện một cái gì đó khá giống với ddví dụ ở trên, trong đó nó mở rộng ELF được định dạng exethành hình ảnh RAM và điền vào hình ảnh bằng cách tìm kiếm thay vì điền vào tệp bằng không. Trên thực tế, đây là trường hợp sử dụng cổ điển cho các tệp thưa thớt, có thể được ánh xạ bộ nhớ ( mmap) mà không phát sinh chi phí cho các khối không sử dụng.


Các liên kết tôi tham khảo về cơ bản là nói điều này.
SLM

@slm: Tôi chỉ thấy một liên kết; Tôi lướt qua vài màn hình đầu tiên, nhưng không thấy gì liên quan.
rici

Vâng, đó là lý do tại sao tôi nói rằng "về cơ bản" nói điều này. Bạn nói chính xác hơn nhưng những dòng như thế này: "Tôi đoán bạn đã yêu cầu tệp bin chứa cả vùng RAM và vùng FLASH." về cơ bản nói rằng tập tin được tải với dữ liệu thưa thớt. Có liên kết SO này mà tôi chưa tham khảo ở đây: stackoverflow.com/questions/9725268/ mẹo . Câu trả lời của bạn là "cái gì", nhưng chúng ta vẫn còn thiếu "tại sao".
slm

1
Vâng, tôi đã sửa nó. Vấn đề là kịch bản liên kết. Thực tế, objcopy đã điền add.bin với các số 0 từ địa chỉ 0x0000002c đến 0xa000000. Cảm ơn tất cả.
David Martínez

1
@ MichaelKjorling: Một vị vua Ba Tư đã tìm kiếm bạn đời cho con gái mình. Ba người cầu hôn được áp dụng. Nhà vua đưa họ đến khu rừng cam của mình, nơi họ ngồi bên hồ của mình. Một cây cam khổng lồ cong trên đầu. Nhà vua nheo mắt bên hồ và hỏi, "cái gì trôi nổi trong bóng cây?". "Tại sao, đó là một quả cam," người cầu hôn đầu tiên nói. Người thứ hai nhìn kỹ vào quả và trả lời: "Không, đó là một quả chanh." Người cầu hôn thứ ba lội ra trái cây và nhặt nó lên. "Đó là một nửa quả chanh," anh báo cáo ... Đôi khi, tốt nhất là đừng quá chắc chắn về những gì bạn nghĩ rằng bạn nhìn thấy.
rici
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.