Linux 커널은 어떻게 자체적으로 컴파일 할 수 있습니까?


89

내 컴퓨터에 Linux 시스템을 설치할 때 Linux 커널의 컴파일 프로세스를 잘 이해하지 못합니다.

다음은 나를 혼란스럽게하는 몇 가지 사항입니다.

  1. 커널은 C로 작성되었지만 컴파일러를 설치하지 않고 어떻게 커널을 컴파일 했습니까?
  2. 커널이 컴파일되기 전에 내 컴퓨터에 C 컴파일러가 설치되어있는 경우 컴파일러를 설치하지 않고 어떻게 컴파일러 자체를 컴파일 할 수 있습니까?

나는 며칠 동안 너무 혼란 스러웠습니다. 답변에 감사드립니다.


C- 컴파일러는 AT & T 연구소에서 주어진 컴퓨터 용으로 UNIX를 컴파일하기 위해 어떤 종류의 어셈블러로 작성되었습니다. 한 장을 놓치거나 ... 또는 그 중 몇 개!). 짧은 이야기는 컴퓨터에 C 언어에 대한 적절한 컴파일러가있는 한 다른 컴퓨터에 대해 유닉스 커널을 다시 작성할 필요가 없다는 것입니다. 이러한 컴파일러는 대상 컴퓨터의 특정 어셈블러로 작성되었습니다. "처음 컴파일러는 주어진 컴퓨터의 어셈블러로 작성되었고, UNIX는 C로 작성되었습니다."라고 말하는 Roughty
Victor

답변:


208

리눅스 박스의 첫 번째 바이너리는 (아마도) 다른 리눅스 박스에서 빌드되었습니다.

첫 번째 Linux 시스템의 바이너리는 다른 플랫폼 에서 빌드되었습니다 .

해당 컴퓨터의 바이너리는 또 다른 플랫폼 에 구축 된 원래 시스템으로 루트를 추적 할 수 있습니다.

...

이 정도까지 밀어 붙이면 더 원시적 인 도구로 빌드 된 컴파일러를 찾을 수 있습니다.이 도구는 호스트가 아닌 다른 머신에서 빌드되었습니다.

...

계속 밀면 기계 전면 패널의 스위치를 설정 하여 지침을 입력 할 수 있도록 제작 된 컴퓨터를 찾을 수 있습니다 .

아주 멋진 것들.

규칙은 "도구를 빌드하는 도구를 빌드하는 도구를 빌드하십시오 ..."입니다. 물리적 환경을 실행하는 도구와 매우 유사합니다. "부트 스트랩으로 자신을 끌어 당기기"라고도합니다.


3
반드시 부정한 것은 아닙니다. 최적화되지 않았습니다. 첫 번째 컴파일러는 386에서 작동하도록 최적화되지만 재 컴파일 된 버전은 보유한 아키텍처에 따라 최적화됩니다.
Breton

1
세 번째 단계를 추가 할 수 있습니다. 모든 것이 정상이면 두 번째 단계 출력이 세 번째 단계의 출력과 같아야합니다.
Ismael

27
단순한 소프트웨어가 아니라 하드웨어입니다. 컴퓨터 없이는 P4 (또는 486) 같은 것을 만들 수 없습니다.
BCS

1
@BCS : 아, 네. 우리는 소프트웨어와 하드웨어 도구가 긴밀하게 연결되어 있고 상호 의존적이라는 점에 도달했습니다.
dmckee --- 전 중재자 새끼 고양이

4
"작동하는 복잡한 시스템은 작동하는 단순한 시스템에서 진화 한 것으로 항상 밝혀졌습니다." en.wikipedia.org/wiki/Gall's_law
ajuc

33

다음을 구분해야한다고 생각합니다.

compile , v : 컴파일러를 사용하여 소스 코드를 처리하고 실행 가능한 코드를 생성합니다 [1] .

install , v : 연결, 설정 또는 사용할 것을 준비하려면 [2] .

컴파일은 소스 코드에서 바이너리 실행 파일을 생성합니다. 설치는 이진 실행 파일을 나중에 실행할 수있는 올바른 위치에 놓기 만하면됩니다. 따라서 바이너리를 사용할 수있는 경우 설치 및 사용에 컴파일이 필요하지 않습니다. "cook"및 "serve"와 같이 "컴파일"및 "설치"를 적절하게 생각하십시오.

이제 질문 :

  1. 커널은 C로 작성되었지만 컴파일러를 설치하지 않고 어떻게 커널을 컴파일 했습니까?

커널은 컴파일러 없이는 컴파일 할 수 없지만 컴파일 된 바이너리에서 설치할 수 있습니다 .

일반적으로 운영 체제를 설치할 때 미리 컴파일 된 커널 (이진 실행 파일)을 설치합니다. 다른 사람이 편집했습니다. 커널을 직접 컴파일하려는 경우에만 소스와 컴파일러 및 기타 모든 도구가 필요합니다.

젠투와 같은 "소스 기반"배포판에서도 컴파일 된 바이너리를 실행하기 시작합니다.

따라서 다른 사람이 커널을 컴파일했기 때문에 커널을 컴파일하지 않고도 평생을 살 수 있습니다.

  1. 커널이 컴파일되기 전에 내 컴퓨터에 C 컴파일러가 설치되어있는 경우 컴파일러를 설치하지 않고 어떻게 컴파일러 자체를 컴파일 할 수 있습니까?

커널 (OS)이 없으면 컴파일러를 실행할 수 없습니다. 따라서 컴파일러를 실행하려면 컴파일 된 커널 을 설치 해야하지만 커널 자체 를 컴파일 할 필요는 없습니다 .

다시 말하지만, 가장 일반적인 방법은 컴파일러의 컴파일 된 바이너리를 설치하고 컴파일러 자체 및 커널을 포함하여 다른 모든 것을 컴파일하는 데 사용하는 것입니다.

자, 닭고기와 계란 문제. 첫 번째 바이너리는 다른 사람에 의해 컴파일됩니다. dmckee의 훌륭한 답변을 참조하십시오.


14

이 현상을 설명하는 용어는 부트 스트래핑 이며, 읽어보기에 흥미로운 개념입니다. 임베디드 개발에 대해 생각해 보면 소프트웨어를 필요로하는 알람 시계, 전자 레인지, 원격 제어와 같은 많은 장치가 자체 소프트웨어를 컴파일 할만큼 강력하지 않다는 것이 분명해집니다. 실제로 이러한 종류의 장치에는 일반적으로 컴파일러만큼 복잡한 것을 원격으로 실행할 수있는 리소스가 충분하지 않습니다.

그들의 소프트웨어는 데스크톱 컴퓨터에서 개발 된 다음 컴파일이 완료되면 복사됩니다.

이런 종류의 관심이 있다면 내 머리에서 떠오르는 기사는 Trusting Trust에 대한 성찰 ( pdf )입니다. 이것은 고전적이고 재미있는 읽기입니다.


1
크로스 컴파일과 부트 스트랩을 혼동하고 있습니다. 첫 번째는 PC에만 존재하며 대상 아키텍처에 대한 opcode를 생성하는 컴파일러를 포함합니다. 분명히 다른 컴퓨터 없이는 그렇게 할 수 없기 때문에 닭과 달걀의 딜레마가 있습니다. 딜레마에 대한 답은 부트 스트랩입니다. 손으로 쓰거나 기존의 단순한 컴파일러를 사용하여 더 복잡한 컴파일러를 생성합니다.
Kevin Vermeer 2011 년

12

커널은 자체적으로 컴파일되지 않으며 사용자 공간에서 C 컴파일러에 의해 컴파일됩니다. 대부분의 CPU 아키텍처에서 CPU는 현재 실행중인 코드가 가지고있는 권한을 나타내는 특수 레지스터에 여러 비트가 있습니다. x86에서 이들은 코드 세그먼트 (CS) 레지스터 의 현재 권한 수준 비트 (CPL)입니다 . CPL 비트가 00이면 코드는 커널 모드 라고도하는 보안 링 0 에서 실행 중이라고 합니다 . CPL 비트가 11이면 코드는 보안 링 3 ( 사용자 모드 라고도 함) 에서 실행 중이라고 합니다 . 다른 두 조합 인 01과 10 (각각 보안 링 1과 2)은 거의 사용되지 않습니다.

사용자 모드와 커널 모드에서 코드가 할 수있는 것과 할 수없는 것에 대한 규칙은 다소 복잡하지만, 사용자 모드는 권한을 크게 줄였습니다.

이제 사람들이 운영 체제의 커널에 대해 이야기 할 때, 그들은 상승 된 권한으로 커널 모드에서 실행되는 OS 코드 부분을 말합니다. 일반적으로 커널 작성자는 보안상의 이유로 커널을 가능한 한 작게 유지하려고하므로 추가 권한이 필요하지 않은 코드에는 커널이 없습니다.

C 컴파일러는 이러한 프로그램의 한 예입니다. 커널 모드에서 제공하는 추가 권한이 필요하지 않으므로 대부분의 다른 프로그램과 마찬가지로 사용자 모드에서 실행됩니다.

Linux의 경우 커널은 커널의 소스 코드와 커널의 컴파일 된 실행 파일의 두 부분으로 구성됩니다. C 컴파일러가있는 모든 컴퓨터는 소스 코드의 커널을 이진 이미지로 컴파일 할 수 있습니다. 그렇다면 이진 이미지로 무엇을해야하는지에 대한 질문이 있습니다.

새 시스템에 Linux를 설치할 때 일반적으로 물리적 미디어 (예 : CD DVD) 또는 네트워크에서 미리 컴파일 된 바이너리 이미지를 설치합니다. BIOS는 미디어 또는 네트워크에서 커널의 부트 로더 (의 바이너리 이미지)를로드 한 다음 부트 로더는 하드 디스크에 커널 (의 바이너리 이미지)을 설치합니다. 그런 다음 재부팅 할 때 BIOS가 하드 디스크에서 커널의 부트 로더를로드하고 부트 로더가 커널을 메모리로로드하면 작동이 중지됩니다.

자신의 커널 을 다시 컴파일 하려면 약간 까다 롭지 만 수행 할 수 있습니다.


5

어느 것이 먼저 있었습니까? 닭고기 또는 계란?

공룡 시대부터 알이 ..

.. 어떤 사람들은 닭이 실제로 큰 짐승의 후손이라고 말하면서 모든 것을 혼동합니다 .. 긴 이야기 짧게 : 기술 (달걀)은 현재 제품 (치킨) 이전에 존재했습니다.

커널을 빌드하려면 커널이 필요합니다. 즉, 다른 하나와 함께 빌드합니다.

첫 번째 커널은 원하는 모든 것이 될 수 있습니다 (원하는 최종 제품을 만들 수있는 합리적인 것 ^ __ ^).

Bran의 Kernel Development의이 튜토리얼 에서는 선택한 가상 머신으로 테스트 할 수있는 작은 커널을 개발하고 빌드하는 방법을 알려줍니다.

의미 : 커널을 어딘가에 작성하고 컴파일하고 비어있는 (OS가없는) 가상 머신에서 읽습니다.

이러한 Linux 설치에서 발생하는 작업은 복잡성이 추가 된 동일한 아이디어를 따릅니다.


5

아래로 내려가는 것은 거북이가 아닙니다. 당신이 말했듯이, 당신은 그 운영 체제를 실행하는 시스템에서 이전에 컴파일 된 적이없는 운영 체제를 컴파일 할 수 없습니다. 마찬가지로, 적어도 컴파일러의 첫 번째 빌드는 다른 컴파일러에서 수행되어야합니다 (그리고 첫 번째 빌드가 아직 자체 소스 코드를 컴파일 할 수없는 것으로 판명되는 경우 일반적으로 일부 후속 빌드도).

최초의 Linux 커널이 Minix 상자에서 컴파일 된 것 같지만 확실하지는 않습니다. GCC는 당시 사용 가능했습니다. 많은 운영 체제의 초기 목표 중 하나는 자체 소스 코드를 컴파일 할 수있을만큼 충분히 컴파일러를 실행하는 것입니다. 나아가 첫 번째 컴파일러는 거의 확실히 어셈블리 언어로 작성되었습니다. 첫 번째 어셈블러는 원시 기계 코드로 작성해야하는 가난한 사람들이 작성했습니다.

Linux From Scratch 프로젝트 를 확인할 수 있습니다 . 실제로 책에서 두 시스템을 구축합니다. 직접 구축하지 않은 시스템에 구축 된 "임시 시스템"과 임시 시스템에 구축 된 "LFS 시스템"입니다. 책이 현재 쓰여지는 방식은 실제로 다른 Linux 상자에 임시 시스템을 구축하지만 이론적으로는 완전히 다른 OS에 임시 시스템을 구축하도록 조정할 수 있습니다.


1

귀하의 질문을 올바르게 이해하고 있다면. 커널은 요즘 "자체 컴파일"하지 않습니다. 오늘날 대부분의 Linux 배포판은 Linux 라이브 CD를 통해 시스템 설치를 제공합니다. 커널은 CD에서 메모리로로드되고 디스크에 설치된 것처럼 정상적으로 작동합니다. Linux 환경이 설치되어 시스템에서 실행되면 필요한 파일을 디스크에 쉽게 커밋 할 수 있습니다.

부트 스트랩 문제에 대해 이야기하고 있다면; dmckee는 그것을 꽤 멋지게 요약했습니다.

또 다른 가능성을 제시하는 것 뿐입니다 .

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