Linux를 다른 플랫폼으로 포팅하기 위한 요구 사항 [닫기]

Linux를 다른 플랫폼으로 포팅하기 위한 요구 사항 [닫기]

나는 Linux를 사용할 수 있고 X86, ARM, PowerPC 등과 같은 다양한 플랫폼으로 이식되었다는 것을 알고 있습니다.

그러면 이식에 있어서 정확히 무엇이 필요합니까?

내 이해는 Linux가 C 언어로 작성된 소프트웨어라는 것입니다. 그렇다면 처음에 X86에서 ARM이나 다른 플랫폼으로 Linux를 포팅할 때 특정 타겟 아키텍처에 맞는 컴파일러로 코드를 다시 컴파일해야 하는 문제가 아닌가요?

다양한 주변 장치용 장치 드라이버를 따로 설정하고 Linux를 새로운 아키텍처로 포팅할 때 수행해야 할 추가 작업은 무엇입니까? 컴파일러가 우리를 위해 모든 것을 처리하지 않나요?

답변1

Linux 커널의 코드 대부분은 C로 작성되었지만 코드의 많은 부분은 여전히 ​​실행되는 플랫폼에 매우 구체적이므로 이를 고려해야 합니다.

특별한 예는 대부분의 아키텍처(페이지 테이블 계층 구조)에서 비슷한 방식으로 작동하는 가상 메모리입니다. 그러나 각 아키텍처에는 특정 세부 정보가 있습니다(예: 각 아키텍처의 수준 수 또는 x86에서는 이 또한 증가하고 있습니다). Linux 커널 코드는 이러한 계층 구조 탐색을 처리하기 위해 매크로를 도입하고, 페이지 테이블 수준이 더 적은 아키텍처에서는 컴파일러가 이러한 매크로를 무시할 수 있습니다. 따라서 코드는 C로 작성되지만 아키텍처의 세부 사항을 고려하십시오. )

다른 많은 영역은 각 아키텍처마다 매우 구체적이며 아키텍처별 코드를 사용하여 처리해야 합니다. 그러나 대부분은 어셈블리 언어 코드와 관련이 있습니다. 예는 다음과 같습니다:

  • 컨텍스트 스위치: 컨텍스트 전환에는 전환 중인 프로세스의 모든 레지스터 값을 저장하고 CPU에 예약된 프로세스의 세이브 세트에서 레지스터를 복원하는 작업이 포함됩니다. 심지어 레지스터의 수와 세트도 각 아키텍처에 따라 매우 다릅니다. 이 코드는 일반적으로 레지스터에 대한 전체 액세스를 허용하고 컨텍스트 전환 성능이 시스템에 중요하므로 가능한 한 빨리 실행되도록 어셈블리로 구현됩니다.

  • 시스템 호출: 사용자 공간 코드가 시스템 호출을 트리거하는 메커니즘은 종종 아키텍처별로 다릅니다(때로는 특정 CPU 모델에만 국한되기도 합니다. 예를 들어 Intel과 AMD는 이에 대한 다른 지침을 도입했는데 이는 이전 CPU에는 없을 수 있으므로 이러한 지침의 세부 사항은 정보는 여전히 고유합니다.)

  • 인터럽트 핸들러:인터럽트(하드웨어 인터럽트)가 처리되는 방법에 대한 세부 사항은 플랫폼에 따라 달라지는 경우가 많으며 플랫폼에서 사용하는 특정 호출 규칙을 처리하기 위해 어셈블리 수준의 연결이 필요한 경우가 많습니다. 또한 인터럽트를 활성화/비활성화하는 기본 요소는 플랫폼에 따라 다르며 어셈블리 코드도 필요합니다.

  • 초기화: 초기화가 발생하는 방법에 대한 세부 정보에는 플랫폼별 세부 정보도 포함되는 경우가 많으며 커널 진입점을 처리하기 위해 일부 어셈블리 코드가 필요한 경우가 많습니다. 다중 CPU(SMP)가 있는 플랫폼에서 추가 CPU를 온라인으로 가져오는 방법에 대한 세부 정보도 플랫폼별로 달라지는 경우가 많습니다.

  • 기본 요소 잠금: 잠금 프리미티브(예: 스핀록)의 구현에는 플랫폼별 세부 정보도 포함되는 경우가 많습니다. 일부 아키텍처에서는 이러한 명령어를 효율적으로 구현하기 위해 다양한 CPU 명령어를 제공(또는 선호)하기 때문입니다. 일부는 원자적 작업을 구현하고, 일부는 원자적으로 테스트/업데이트할 수 있는 cmpxchg를 제공하고(다른 기록기가 먼저 오면 실패함), 다른 일부는 CPU 명령에 "잠금" 수정자를 포함합니다. 여기에는 일반적으로 어셈블리 코드 작성도 포함됩니다.

플랫폼 또는 아키텍처별 코드가 커널(또는 특히 Linux 커널)에 필요할 수도 있습니다. 커널 소스 트리를 살펴보면 이에 대한 추가 정보와 예를 찾을 수 있는 아키텍처별 하위 트리가 아래와 아래에 arch/있습니다 .include/arch/

각 아키텍처에서 사용 가능한 시스템 호출 수가 다르며 특정 시스템 호출이 일부 아키텍처에만 존재하고 다른 아키텍처에는 존재하지 않는다는 사실과 같은 일부는 실제로 놀랍습니다. (x86에서도 시스템 호출 목록은 32비트 커널과 64비트 커널 간에 다릅니다.)

간단히 말해서, 커널은 플랫폼별 사항에 대해 많은 것을 알아야 합니다. Linux 커널은 이 중 많은 부분을 추상화하려고 시도하므로 더 높은 수준의 알고리즘(예: 메모리 관리 및 예약 작동 방식)을 C로 구현하고 모든 아키텍처에서 동일한(또는 거의 동일한) 방식으로 작동할 수 있습니다.

답변2

Linux 커널을 포팅하는 것 외에도 다음을 정의해야 합니다.애플리케이션 바이너리 인터페이스(ABI) "사용자 공간" 프로그램 및 포트에 대한 사용자 공간 소프트웨어 스택의 가장 낮은 계층입니다. Linux는 일반적으로 GNU 프로젝트의 하위 수준 사용자 공간 구성 요소와 함께 사용되며, 그 중 가장 중요한 구성 요소는 다음과 같습니다.

  • C 컴파일러, 어셈블러 및 링커:걸프 협력 협의회그리고GNU Binutils. 완전히 새로운 CPU 아키텍처를 사용하면 커널 포팅을 시작하기 전에 소프트웨어를 포팅해야 합니다. 커널 자체가 C 프로그램이고 컴파일되어야 하기 때문입니다. 플랫폼의 CPU에 이미 "백엔드" 지원이 있고 Linux를 운영 체제 커널로 사용하지 않는 경우 수행할 작업이 훨씬 적어지고 커널이 나타날 때까지 대부분을 연기할 수 있습니다. 달리기.
  • C 런타임 라이브러리: "GNU 라이브러리".이 라이브러리에는 코드가 포함되어 있습니다.만들다시스템 호출을 수행하고 그렇지 않으면 커널과 직접 상호 작용합니다.
  • "외부 함수 인터페이스" 라이브러리,쿠피, 이는 많은 고급 언어 통역사의 중요한 부분이며 남은 작업 중 하나를 수행합니다.필요소량의 손으로 쓴 어셈블리 언어입니다.

다른 많은 소프트웨어에는 선택적 플랫폼 종속 구성 요소가 있습니다. 예를 들어 수동으로 최적화된 암호화 기본 요소를 작성하면 웹 검색 속도가 훨씬 빨라집니다.국가안보국그리고OpenSSL새로운 CPU 아키텍처 및 JIT(Just-In-Time) 컴파일 백엔드와 함께 작동합니다.이온 원숭이그리고V8. 하지만 새로운 플랫폼을 구축하는 데에는 이것이 필수가 아닙니다.

답변3

어떤 하드웨어로 포팅하려는지 커널에 알려주어야 합니다. 커널의 임무는 하드웨어와 직접 상호 작용하는 것이므로 하드웨어가 제대로 작동하려면 커널이 CPU, 발진기(시계) 및 다양한 직렬 포트(SPI, CAN, I2C)와 같은 주변 장치에 대해 알아야 합니다. , 등.).

과거에는 드라이버가 실행하는 데 사용할 플랫폼별 코드를 작성하여 이를 수행할 수 있었습니다. 오늘은 이 작업을 다음과 같이 작성하여 수행합니다.장치 트리 정의.

관련 정보