Sự khác biệt giữa tệp ELF và tệp bin là gì?


97

Những hình ảnh cuối cùng được tạo ra bởi các trình tuân thủ chứa cả tệp bin và tệp ELf định dạng bộ nạp mở rộng, sự khác biệt giữa hai tệp này là gì, đặc biệt là tiện ích của tệp ELF.


Đây là những gì NASM phải nói . Không phải ARM cụ thể, nhưng có thể là cùng một khái niệm. Ví dụ: nếu bạn biên dịch một tệp chỉ chứa NOPkhông có -f(hoặc -fbin), nó sẽ biên dịch thành một byte duy nhất 0x90, thay vì một vùng chứa ELF 400 byte có -felf32. Vì vậy, chỉ là mã thô, không có siêu dữ liệu vùng chứa. NASM cho biết nó chủ yếu được sử dụng cho các tệp MS-DOS .COM và .SYS . sectioncác chỉ thị hầu như bị bỏ qua và chỉ tạo ra sự liên kết.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Đây là một cách thức mà các file bin có thể hữu ích: để thực hiện một boot sector để hệ điều hành triển khai: stackoverflow.com/a/32483545/895245
Ciro Santilli郝海东冠状病六四事件法轮功

Câu trả lời:


94

Tệp Bin là một tệp nhị phân thuần túy không có bản sửa lỗi hoặc định vị bộ nhớ, nhiều khả năng nó có hướng dẫn rõ ràng để được tải tại một địa chỉ bộ nhớ cụ thể. Trong khi....

Các tệp ELF là Định dạng có thể Liên kết Thực thi được bao gồm bảng tra cứu ký hiệu và bảng có thể định vị lại, có nghĩa là, nó có thể được tải tại bất kỳ địa chỉ bộ nhớ nào bởi hạt nhân và tự động, tất cả các ký hiệu được sử dụng, được điều chỉnh theo độ lệch từ địa chỉ bộ nhớ đó. đã được tải vào. Thông thường các tệp ELF có một số phần, chẳng hạn như 'dữ liệu', 'văn bản', 'bss', để đặt tên nhưng một số ít ... nó nằm trong các phần đó mà thời gian chạy có thể tính toán nơi điều chỉnh các tham chiếu bộ nhớ của biểu tượng động vào thời gian chạy.


"nhiều khả năng nó có hướng dẫn rõ ràng để được tải tại một địa chỉ bộ nhớ cụ thể": điều này có nghĩa là quá trình tạo tệp bin thêm mã bổ sung để tải dữ liệu đến địa chỉ cụ thể?
Penghe Geng

1
Theo như tôi đã tìm hiểu thì tệp bin giống như chạy chương trình từ độ lệch 0 và phân đoạn dữ liệu được nhúng bên trong. Nếu điều này là sai, xin vui lòng sửa cho tôi.
Martin Kersten

@MartinKersten đúng, các tệp bin bắt đầu từ độ lệch 0.
t0mm13b

1
@ t0mm13b Vì vậy, các tệp .elf có thể được ghi vào bộ điều khiển vi mô giống như tệp .hex thông thường nhưng nó tốn nhiều bộ nhớ flash hơn và mỗi khi vi được đặt lại, địa chỉ của các phần sẽ thay đổi?
Aelgawad

@BlackyDucky, tôi không tin là có thể. Nếu một bộ vi điều khiển cố gắng thực thi dữ liệu ELF trực tiếp, nó sẽ hiểu sai tiêu đề và dữ liệu khác dưới dạng hướng dẫn, phải không?
iX3

40

Tệp bin chỉ là các bit và byte đi vào rom hoặc một địa chỉ cụ thể mà từ đó bạn sẽ chạy chương trình. Bạn có thể lấy dữ liệu này và tải trực tiếp, bạn cần biết địa chỉ cơ sở là gì mặc dù thông thường không có ở đó.

Một tệp elf chứa thông tin bin nhưng nó được bao quanh bởi rất nhiều thông tin khác, thông tin gỡ lỗi có thể có, ký hiệu, có thể phân biệt mã với dữ liệu trong tệp nhị phân. Cho phép nhiều hơn một phần dữ liệu nhị phân (khi bạn kết xuất một trong những phần này vào một thùng rác, bạn sẽ nhận được một tệp bin lớn với dữ liệu điền để đưa nó vào khối tiếp theo). Cho bạn biết bạn có bao nhiêu tệp nhị phân và có bao nhiêu dữ liệu bss muốn được khởi tạo thành số không (công cụ gnu gặp sự cố khi tạo tệp bin một cách chính xác).

Định dạng tệp elf là một tiêu chuẩn, arm xuất bản các cải tiến / biến thể của nó trên tiêu chuẩn. Tôi khuyên mọi người nên viết một chương trình phân tích cú pháp elf để hiểu những gì trong đó, đừng bận tâm đến thư viện, nó khá đơn giản chỉ cần sử dụng thông tin và cấu trúc trong spec. Giúp khắc phục sự cố gnu nói chung khi tạo tệp .bin cũng như gỡ lỗi tập lệnh trình liên kết và những thứ khác có thể giúp làm rối đầu ra bin hoặc elf của bạn.


1
0x7C00 nghe giống như một thứ bộ nạp khởi động không nhất thiết phải sử dụng elf. đây là một câu hỏi chung chung. một hệ điều hành sẽ có các quy tắc cho không gian địa chỉ (ảo), chuỗi công cụ sẽ cần được nhắm mục tiêu theo các quy tắc của hệ điều hành đó, sau đó định dạng tệp sẽ chỉ ra các mục có thể tải với địa chỉ cộng với một điểm nhập sau khi được tải, cộng với những thứ khác. elf chỉ là một vật chứa, giống như một chiếc hộp, bạn phải đóng gói nó phù hợp với trường hợp sử dụng được nhắm mục tiêu.
old_timer

1
nếu bạn muốn in một số ascii vào vga, bạn viết một chương trình để thực hiện việc đó có một số dữ liệu hoặc toán học tạo dữ liệu một cách nhanh chóng hoặc một số kết hợp, sau đó bạn tải chương trình đó vào không gian mã xác định của hệ điều hành, rồi chạy nó. bạn thường không chuyển dữ liệu ngay vào một thiết bị ngoại vi vật lý và đây là hệ điều hành hiếm hoi cho phép bạn làm điều đó bằng mọi cách hoặc cho phép trình tải của nó làm điều đó.
old_timer

1
đối với kim loại trần, đặc biệt nếu tệp elf này là bộ nạp khởi động và / hoặc chương trình đầu tiên chạy, thì điểm nhập và _start không liên quan vì bạn sử dụng tệp elf làm bước đệm cho một công cụ lập trình flash (như openocd over jtag) hoặc thông qua bất cứ điều gì-bất cứ-cái gì-đối tượng -O binary file.elf file.bin và sau đó tệp đó bằng cách nào đó được tải vào flash. Chưa đi và đã thử một bộ nạp khởi động trên x86 nhưng giả sử rằng bios không thể phân tích cú pháp các tệp elf nên nó cũng cần phải là một hình ảnh bộ nhớ. so a -O tệp bin loại nhị phân
old_timer

1
thực thể riêng biệt là phần cứng / logic hoặc thiết kế khác. đối với hệ điều hành thì hệ điều hành tạo ra các quy tắc, đối với vi điều khiển, thiết kế chip / bộ xử lý tạo ra các quy tắc. ví dụ: nếu có một bảng vectơ và sau đó các vectơ trỏ đến các trình xử lý, bạn phải cuộn tất cả chúng vào tập lệnh trình liên kết của mình, v.v. để dữ liệu có thể tải được dành cho flash mà thứ khởi động.
old_timer

1
Để mở rộng rằng mục tiêu của bạn có các quy tắc, có thể là hệ điều hành hoặc bộ xử lý hoặc bộ nạp khởi động nhiều giai đoạn, v.v. Và bạn cần xây dựng "nhị phân" của mình dựa trên các quy tắc đó, bootstrap và linkerscript là quan trọng nhất. Sau đó, nó rất rộng về từng mục tiêu và cách bạn áp dụng tệp nhị phân đó và những định dạng tệp nào được hỗ trợ. Giả sử gnu trên một số nền tảng phát triển máy chủ lưu trữ, định dạng tệp elf là đầu ra mặc định và sau đó bạn sử dụng các công cụ khi cần thiết (nếu mục tiêu là các tiện ích / bộ tải cụ thể) để trích xuất hoặc chuyển đổi từ elf sang thứ gì đó khác.
old_timer

30

một số tài nguyên:

  1. ELF cho kiến ​​trúc ARM
    http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
  2. ELF từ wiki
    http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

Định dạng ELF thường là đầu ra mặc định của quá trình biên dịch. nếu bạn sử dụng chuỗi công cụ GNU, bạn có thể dịch nó sang định dạng nhị phân bằng cách sử dụng đối tượng, chẳng hạn như:

  arm-elf-objcopy -O binary [elf-input-file] [binary-output-file]

hoặc sử dụng tiện ích fromELF (mặc dù được tích hợp trong hầu hết các IDE như ADS):

 fromelf -bin -o [binary-output-file] [elf-input-file]

6
Điều này đã được thêm vào sau khi các chi tiết tập tin bin đã được trả lời, và không add-on một kỹ thuật thực tế hữu ích. +1 cho điều đó.
erbdex

-1

Tôi chỉ muốn sửa một điểm ở đây. Tệp ELF được tạo ra bởi Trình liên kết, không phải trình biên dịch.

Nhiệm vụ Trình biên dịch kết thúc sau khi tạo tệp đối tượng (* .o) ra khỏi tệp mã nguồn. Trình liên kết liên kết tất cả các tệp .o với nhau và tạo ra ELF.


Bị phản đối vì nó không trả lời câu hỏi cũng như không nhất thiết phải chính xác. Định nghĩa rộng rãi, biên dịch bao gồm liên kết. Trích dẫn từ ldtài liệu : Thông thường bước cuối cùng khi biên dịch một chương trình là chạy ld.
bzeaman
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.