다른 플랫폼 요구 사항으로 Linux 이식 [닫기]


28

Linux를 사용할 수 있으며 X86, ARM, PowerPC 등과 같은 다양한 플랫폼에 이식되었습니다.

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

필자는 Linux가 C로 작성된 소프트웨어라는 것을 이해하고있다. 따라서 Linux를 X86에서 ARM 또는 기타로 포팅 할 때 특정 대상 아키텍처의 컴파일러로 코드를 다시 컴파일하는 것이 문제가 아닌가?

다른 주변 장치 용 장치 드라이버를 제쳐두고 Linux를 새로운 아키텍처로 이식 할 때 수행해야 할 작업 컴파일러가 우리를 위해 모든 것을 처리하지 않습니까?


11
아키텍처 별 커널 소스를 살펴 보았다고 가정 할 수 있습니까? git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/…
Kusalananda

답변:


57

Linux 커널의 코드 대부분이 C로 작성되었지만 해당 코드의 일부는 여전히 실행중인 플랫폼에 따라 다르며이를 처리해야합니다.

이 중 하나의 특정 예는 대부분의 아키텍처 (페이지 테이블의 계층 구조)에서 유사한 방식으로 작동하지만 각 아키텍처에 대한 특정 세부 사항 (예 : 각 아키텍처의 레벨 수)이있는 가상 메모리이며 x86에서도 증가하고 있습니다. 리눅스 커널 코드는 페이지 테이블 레벨이 더 적은 아키텍처 (컴파일러는 C로 작성되지만 아키텍처의 세부 사항은 고려.)

다른 많은 영역은 각 아키텍처에 따라 매우 다르며 아치 별 코드로 처리해야합니다. 그러나 대부분은 어셈블리 언어의 코드와 관련이 있습니다. 예를 들면 다음과 같습니다.

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

  • 시스템 호출 : 사용자 공간 코드가 시스템 호출을 트리거 할 수있는 메커니즘은 일반적으로 아키텍처에 따라 다릅니다 (그리고 때로는 특정 CPU 모델, 예를 들어 인텔과 AMD에서 다른 명령을 도입 했으므로 이전 CPU에는 해당 명령이 없을 수 있음) 그것들은 여전히 ​​독특 할 것입니다.)

  • 인터럽트 처리기 : 인터럽트 (하드웨어 인터럽트)를 처리하는 방법에 대한 자세한 내용은 일반적으로 플랫폼별로 다르며 일반적으로 플랫폼에 사용되는 특정 호출 규칙을 처리하기 위해 어셈블리 수준의 접착제가 필요합니다. 또한 인터럽트를 활성화 / 비활성화하기위한 프리미티브는 일반적으로 플랫폼에 따라 다르며 어셈블리 코드도 필요합니다.

  • 초기화 : 초기화 방법에 대한 세부 사항에는 일반적으로 플랫폼에 특정한 세부 사항이 포함되며 종종 커널의 진입 점을 처리하기 위해 일부 어셈블리 코드가 필요합니다. 다중 CPU (SMP)가있는 플랫폼에서 다른 CPU를 온라인 상태로 만드는 방법에 대한 자세한 내용은 일반적으로 플랫폼마다 다릅니다.

  • 잠금 프리미티브 (Locking Primitives) : 잠금 프리미티브 (스핀 록과 같은)의 구현에는 일반적으로 플랫폼 별 세부 사항도 포함됩니다. 일부 아키텍처는이를 효율적으로 구현하기 위해 다른 CPU 명령을 제공하거나 선호하기 때문입니다. 일부는 원자 연산을 구현하고 일부는 원자 적으로 테스트 / 업데이트 할 수있는 cmpxchg를 제공하지만 (다른 기록기가 먼저 들어 오면 실패) 다른 명령은 CPU 명령에 대한 "잠금"수정자를 포함합니다. 여기에는 종종 어셈블리 코드 작성이 포함됩니다.

플랫폼에 또는 아키텍처 특정 코드가 커널에 필요한 아마 다른 지역 (특히, 또는 리눅스 커널에서.)이있다 커널 소스 트리를 보면, 아래 아키텍처 특정 하위 트리가 arch/이하 include/arch/더 찾을 수있는 곳이 이것의 예.

예를 들어, 각 아키텍처에서 사용 가능한 시스템 호출 수가 다르고 일부 시스템 호출은 다른 아키텍처가 아닌 일부 아키텍처에 존재한다는 것을 알 수 있습니다. x86에서도 syscall 목록은 32 비트와 64 비트 커널간에 다릅니다.

요컨대, 플랫폼에 특정한 커널을 알고 있어야하는 경우가 많이 있습니다. 리눅스 커널은 이들 대부분을 추상화하려고 시도하므로, 메모리 관리 및 스케줄링 작동 방식과 같은 고급 알고리즘을 C로 구현하고 모든 아키텍처에서 동일하게 (또는 대부분 동일하게) 작동 할 수 있습니다.


7
아주 좋은 쓰기! syscall 수의 변동은 대부분 기록과 관련이 있습니다. 새로운 포트에는 포트 시점에 유효한 syscall이 포함되며, 이전 포트에있는 이전 수하물에는 신경 쓰지 않으므로 일반적으로 더 이상 사용되지 않는 syscall은 포트에 없습니다 더 이상 사용되지 않습니다. (모든 시나리오를 다루지는 않습니다 ...)
Stephen Kitt

10

Linux 커널 포팅 외에도 "사용자 공간"프로그램에 대한 ABI ( Application Binary Interface) 를 정의 하고 사용자 공간 소프트웨어 스택의 최하위 계층을 포팅해야합니다. Linux는 일반적으로 GNU 프로젝트의 저수준 사용자 공간 구성 요소와 함께 사용되며 가장 중요한 부분은 다음과 같습니다.

  • C 컴파일러, 어셈블러, 링커 : GCCGNU Binutils의 . 완전히 새로운 CPU 아키텍처의 경우 커널 자체가 C 프로그램이며 컴파일되어야하므로 커널 포팅을 시작하기 전에이 소프트웨어를 포팅해야합니다. Linux에서 OS 커널로 사용하는 것이 아니라 플랫폼의 CPU에 대한 "백엔드"지원이 이미있는 경우, 수행해야 할 작업이 훨씬 적고 커널이 작동 할 때까지 대부분의 작업을 연기하지 않아도됩니다. 달리는.
  • C 런타임 라이브러리 : " GNU libc ". 이 라이브러리는 코드를 포함 하게 시스템 호출을 달리 커널와 직접 상호 작용을.
  • "외국어 기능 인터페이스"라이브러리 인 libffi 는 많은 고급 언어 통역사의 필수 구성 요소이며 적은 수의 손으로 쓰는 어셈블리 언어 가 필요한 몇 가지 남은 작업 중 하나를 수행 합니다.

다른 많은 소프트웨어에는 선택적인 플랫폼 종속 구성 요소가 있습니다. 예를 들어, 새로운 CPU 아키텍처에 대해 NSSOpenSSL에 대해 수동으로 최적화 된 암호화 기본 요소 를 작성 하고 IonMonkeyV8에 대한 적시 컴파일 백엔드 를 작성하면 웹 탐색이 훨씬 빨라집니다 . 그러나 새로운 플랫폼을 구축하는 데 반드시 필요한 것은 아닙니다.


1

커널에 이식하려는 하드웨어에 대해 알려 주어야합니다. 커널의 역할은 하드웨어와 직접 인터페이스하는 것이므로 제대로 작동하려면 커널은 CPU, 발진기 (시계) 및 다양한 종류의 직렬 포트 (SPI, CAN, I2C 등).

예전에는 드라이버가 작동하는 데 사용할 플랫폼 별 코드를 작성하여이 작업을 수행했습니다. 요즘에는 장치 트리 정의를 작성하여 수행됩니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.