
Linux 소스에는 다음 위치에 두 개의 서로 다른 head.S 파일이 있습니다.
각각의 목적은 무엇이며 실행 순서는 무엇입니까?
답변1
더 나은 답변을 환영하지만, 제가 이해하는 바는 이것이 어셈블리에서 직접 작성한 커널 시작 코드(아키텍처별)라는 것입니다(이 시점에서는 베어메탈 CPU와 메모리에 대한 원시 액세스 권한만 있음을 기억하세요. 아직 파일 관리자가 없기 때문에 파일 시스템에 저장된 복잡한 라이브러리에 액세스합니다. 이는 누가 빅뱅을 만들었는지 묻는 것과 같습니다. 이것을 부트 로더(디스크에서 RAM으로 부트 섹터를 로드하는)와 혼동하지 마십시오. 나는 이전 답변에서 그것들을 혼동했습니다.
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
' bootloader ' ' kernel '
' ' ' '
+------+ ' +-----------------------------------+ +------------------------------+ ' ' +-----------------------------+ +---------------------------------------+ '
| BIOS | --> ' | arch/x86/boot/header.S::call main | --> | arch/x86/boot/main.c::main() | ' --> ' | init/main.c::start_kernel() | --> | arch/x86/kernel/setup.c::setup_arch() | '
+------+ ' +-----------------------------------+ +------------------------------+ ' ' +-----------------------------+ +---------------------------------------+ '
' ' ' '
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
(편집: 이것은 Minix입니다. 원래 잘못 넣었습니다.)
+------+ +--------------------+ +------------------+ +------------------------+
| BIOS | --> | Bootloader (mbr.S) | --> | startup (head.S) | --> | kernel/main.c::kmain() |
+------+ +--------------------+ +------------------+ +------------------------+
head.S의 끝에는 선이 보일 것입니다.
call _C_LABEL(kmain)
이는 커널의 진입점입니다.
kernel/main.c
head.S
나는 컴파일 타임에 커널 이미지의 맨 위에 붙는다고 생각합니다 . BIOS는 이 코드 블록이 맨 처음에 있고 램 디스크의 루트 파일 시스템이기 때문에 실행하는 것을 알고 있습니다.
압축된 부분과 압축되지 않은 부분이 있는 이유는 커널 이미지의 아키텍처 특정 어셈블리 부분이기 때문에 압축을 수행할 만큼 숙련된 프로그래머가 없기 때문이라고 생각합니다. C로 작성된 루틴(그러나 어셈블리로 컴파일된 루틴) 으로 점프할 수 있으면 kmain
커널 공간을 훨씬 더 작게 만드는 압축 해제 루틴에 액세스할 수 있습니다.
http://duartes.org/gustavo/blog/post/kernel-boot-process/
어셈블리를 사용하는 진입점
우리는 모든 것을 C로 작성하는 것을 좋아하지만 약간의 어셈블리를 피할 수는 없습니다. 커널의 시작점 역할을 하는 x86 어셈블리 언어로 작은 파일을 작성하겠습니다. 어셈블리 파일이 수행할 작업은 C로 작성할 외부 함수를 호출한 다음 프로그램 흐름을 중단하는 것뿐입니다.
이 어셈블리 코드가 커널의 시작점 역할을 하도록 어떻게 보장할 수 있나요?
우리는 최종 커널 실행 파일을 생성하기 위해 객체 파일을 연결하는 링커 스크립트를 사용할 것입니다. (자세한 내용은 나중에 설명) 이 링커 스크립트에서 바이너리가 주소 0x100000에 로드되도록 명시적으로 지정합니다. 앞서 말했듯이 이 주소는 커널이 있을 것으로 예상되는 주소입니다. 따라서 부트로더는 커널의 진입점 실행을 관리합니다.
http://arjunsreedharan.org/post/82710718100/kernel-101-lets-write-a-kernel