실행 파일에 바이너리 형식 사양이 필요한 이유는 무엇입니까?

실행 파일에 바이너리 형식 사양이 필요한 이유는 무엇입니까?

나는 Linux 또는 Windows와 같은 운영 체제가 C/C++로 작성되고 특정 아키텍처(예: AMD64)로 컴파일되어 해당 아키텍처에 적합한 기계 코드를 생성한다는 것을 이해합니다.

내 질문 -

  1. 바이너리 코드에 별도의 사양이 필요한 이유는 무엇입니까? Linux는 ELF를 사용하고 Windows는 Portable Executable Format을 사용합니까?
  2. 이 바이너리 형식 사양 없이 운영 체제와 해당 운영 체제에서 실행되는 프로그램을 만들 수 있습니까?
  3. 바이너리 형식은 아키텍처에 따라 달라지나요, OS에 따라 달라지나요, 아니면 둘 다인가요?
  4. 바이너리 형식은 실행 파일에만 적용할 수 있나요? 아니면 운영 체제 코드에도 적용할 수 있나요?

답변1

짐작하셨겠지만, 실행 파일 형식에는 단순한 기계어 코드 이상의 내용이 포함되어 있습니다. 예를 들어 다음과 같은 작업을 수행할 수 있습니다.

  • 실행 파일이 어떤 아키텍처를 대상으로 하는지 등 OS에 대한 메타데이터를 지정합니다. 이 메타데이터는머리글파일의.

  • 프로그램을 지정하세요공들여 나열한 것기억 속에. 최신 OS에서 대부분의 실행 파일은 단일 청크로 메모리에 로드되지 않습니다.지역/섹션/세그먼트. 이러한 세그먼트 중 일부에는 실행 가능한 코드가 포함됩니다. 그 중 일부는 텍스트 문자열과 같이 변경할 수 없는 데이터를 포함합니다. 그 중 일부는 프로그램 힙에 대해 쓰기 가능한 메모리로 지정됩니다.

    프로그램마다 이러한 섹션의 크기에 대한 요구 사항(요청)이 다릅니다. 이것은 모두 헤더에 지정되어 있습니다.

  • 일부 형식에서는전자 서명, 바이너리가 어디서 왔는지 확인할 수 있습니다.


  1. 바이너리 코드에 별도의 사양이 필요한 이유는 무엇입니까? Linux는 ELF를 사용하고 Windows는 Portable Executable Format을 사용합니까?

그 이유는 주로 역사적이며 OS는 전환해야 할 강력한 이유가 없는 한 기존의 '기본'(또는 '기본') 형식을 고수하는 경향이 있습니다(예: NT 3.1의 DOS MZ 형식에서 PE로, .out을 Linux 1.2에서는 ELF로, 수년에 걸쳐 다양한 Unix에서는 COFF에서 ELF로 변환합니다.

기본 기계어 코드는 CPU 아키텍처에 따라 다르지만 그렇지 않은 경우(syscall 및 연결된 라이브러리는 제쳐두고) OS 간에 대체로 이식 가능하다는 점에 유의해야 합니다. 실제로 최신 Windows 및 Linux에서는 두 가지 실행 파일 형식을 모두 실행할 수 있습니다. ELF 실행 파일은 WSL을 통해 Windows에서 실행되고 PE 실행 파일은 WINE을 통해 Linux에서 실행됩니다.

  1. 이 바이너리 형식 사양 없이 운영 체제와 해당 운영 체제에서 실행되는 프로그램을 만들 수 있습니까?

우리는 이러한 형식의 기본 목적으로 돌아갑니다. 프로그램의 일부를 로드할 위치를 OS에 알려주는 메타데이터가 없으면 대부분의 최신 실행 파일을 실행할 수 없습니다. 다음과 같은 매우 오래된 형식COM거의 순수한 코드를 포함하고 있지만 특별히 유연하지 않아 인기가 떨어졌습니다.

실제로는 운영 체제가 존재할 필요조차 없습니다. 하드웨어 수준에서 (레거시) BIOS가 있다고 가정하면,BIOS는 디스크(MBR)의 특정 위치에서 실행을 시작합니다., 이는 OS를 인계받아 시작하거나 원하는 다른 작업을 수행하는 임의의 기계 코드일 수 있습니다. (MBR 자체는 실행 코드와 직접적인 관련이 없지만 이진 형식으로 볼 수 있습니다.) 그러나 최신 UEFI에서는 더 복잡한 실행 가능 형식(PE)을 지정합니다.

  1. 바이너리 형식 아키텍처가 종속적입니까, OS 종속적입니까, 아니면 둘 다입니까?

실제로 형식에 따라 다릅니다. 일부 형식은 특정 아키텍처를 가정합니다. 다른 것들은 헤더에 지정된 "매직 넘버" 목록에서 아키텍처를 선택할 수 있게 해줍니다. 또 다른 것들은 아키텍처에 완전히 구애받지 않습니다(예: Java 및 .NET/CIL 바이트코드).

마찬가지로 형식은 일반적으로 OS에 제한을 두지 않지만 OS는 (기본적으로) 인식하고 실행할 수 있는 형식이 제한됩니다. 물론, 코어 OS 위에 있는 호환성 레이어는 코어 OS가 인식할 수 없는 다른 형식(예: JVM, .NET/CLR, WSL&WINE 등)을 실행할 수 있습니다.

  1. 바이너리 형식은 실행 파일에만 적용할 수 있나요? 아니면 운영 체제 코드에도 적용할 수 있나요?

대부분의 최신 운영 체제의 대부분은 "일반적인" 실행 파일 모음일 뿐입니다. 그러나 운영 체제의 일부 부분은 "특별"하며 반드시 나머지 부분과 동일한 형식을 사용하지는 않습니다. 일반적으로 이는 부트로더와 커널에만 적용됩니다.

특정하고 매우 일반적인 예를 가져오려면 레거시 BIOS 부트로더가~ 아니다Linux 및 Windows에서 사용되는 ELF 또는 PE 형식이어야 합니다. Linux 커널은 일반적으로 다음과 같은 방식으로 구축됩니다.ELF 파생 형식GRUB 부트로더는로드할 수 있습니다, 그러나 사용된 부트로더와 호환되도록 다른 형식일 수 있습니다. Linux 커널은 또한 다음을 지원합니다.EFI 스텁직접 UEFI 부팅과 호환되는 최소 PE/COFF 헤더가 포함된 모드입니다.

답변2

이 형식의 주요 용도는 프로그램을 메모리에 로드하는 것입니다.짐을 싣는 사람.

  1. 바이너리 코드에 별도의 사양이 필요한 이유는 무엇입니까? Linux는 ELF를 사용하고 Windows는 Portable Execution Format을 사용합니까?

정중한 답변: OS가 다르고 요구 사항도 다르기 때문입니다. Unix 담당자의 답변: Microsoft는 (사각형) 바퀴를 재발명하는 것을 좋아하기 때문입니다.

  1. 이 바이너리 형식 사양 없이 운영 체제와 해당 운영 체제에서 실행되는 프로그램을 만들 수 있습니까?

예, 하지만 아주 사소한 것, 즉 "재배치"할 필요가 없고 외부 코드에 연결할 필요가 없는 사소한 프로그램을 실행하는 상당히 기본적인 OS입니다.

  1. 바이너리 형식 아키텍처가 종속적입니까, OS 종속적입니까, 아니면 둘 다입니까?

없음. ELF 형식은 많은 운영 체제 및 아키텍처에서 사용됩니다.

  1. 바이너리 형식은 실행 파일에만 적용할 수 있나요? 아니면 운영 체제 코드에도 적용할 수 있나요?

Linux에서 부팅 가능한 커널은 ELF가 아닐 수 있지만 커널 모듈은 ELF 형식을 사용합니다.

관련 정보