커널에 main () 함수가 있습니까? [닫은]


52

장치 드라이버와 커널 프로그래밍을 배우고 있습니다. Jonathan Corbet의 책에 따르면 main()장치 드라이버 에는 기능 이 없습니다 .

그래서 두 가지 질문이 있습니다.

  • main()장치 드라이버에 기능이 필요하지 않습니까?
  • 커널 자체에 main()기능이 있습니까?

누군가 나에게 이것을 설명 할 수 있습니까?


1
또한 동일한 사용자가 여기에 물었습니다 : stackoverflow.com/q/18266063/827263
Keith Thompson

@KeithThompson ... 예 ... 내가 원하는 것에 대한 답변을 얻지 못했기 때문에 여기에 물었습니다.
누군가

@Shadur ... 어쨌든 이제 막 닫으려고합니다 ... 그리고 나는 그것을 마이그레이션 할 특권이 없습니다 ...
누군가

이것은이 하나가 더 많은 의견을 :-)이, 다른 방법으로 주위에 폐쇄되어 있어야합니다
치로 틸리가新疆改造中心法轮功六四事件

답변:


82

사용자 공간 프로그램 에서 바이너리가 실행될 때 libc 초기화 코드에 의해 호출되는main() 프로그램의 진입 점 입니다. libc 자체는 메모리 할당, I / O, 프로세스 관리 등을 위해 커널 syscall 인터페이스에 의존하므로 커널 코드에는 libc에 의존 할 수있는 사치가 없습니다.

즉, main()커널 코드에서 와 동등한 것은 커널 이미지를로드 한 후 부트 로더start_kernel()호출하여 이를 이미지 압축을 풀고 필수 하드웨어 및 메모리 페이징을 설정합니다. start_kernel()대부분의 시스템 설정을 수행하고 결국 init 프로세스를 생성합니다.

Linux 커널 모듈의 진입 점은 module_init()매크로 를 호출하여 커널에 등록 된 초기화 기능입니다 . 등록 된 모듈 init 함수는 커널 시작 중에 함수를 통해 커널 코드에 의해 호출됩니다do_initcalls() .


11
mainC 에서 메소드 의 실제 목적을 인식 해주셔서 감사합니다 . (OS가 직접 호출하는 것은 OS가 너무 일반적으로 잘못 이해하고 main있습니다. 내가 그걸 위해 할 수 있다면 또 다른 공감대를 줘.
CVn

1
@ 토마스 ...이 훌륭한 답변 주셔서 감사합니다 ....
누군가

17

커널에는 main기능 이 없습니다 . mainC 언어의 개념입니다. 커널은 C와 어셈블리로 작성됩니다. 커널의 엔트리 코드는 어셈블리에 의해 작성됩니다.

부팅 순서는 다음과 같이 구성됩니다.

  1. BIOS는 일반적으로 부팅 블록 장치에서 부팅 로더를로드합니다. 현재 인기있는 부트 로더는 grub입니다.
  2. Grub은 초기 루트 장치 ( initrd) 로 커널 이미지를 램에로드합니다 . 그런 다음 일부 주소의 코드가 실행됩니다.
  3. 커널 이미지에는 파일 시스템 모듈, 장치 드라이버와 같은 일부 커널 모듈이 있습니다. 커널 이미지는 파일 시스템 모듈을 사용하여 루트 파일 시스템을 마운트합니다. 이제 커널은 디스크에서 모든 커널 모듈을로드하고 실행할 수 있습니다.
  4. 커널은 초기화 작업을 실행합니다. 예 : PCI 버스를 통과하고 모든 PCI 장치를 찾고 모든 장치 드라이버를 초기화하십시오.
  5. 마지막으로 커널은 프로세스 0과 프로세스 1 ( init프로세스)을 작성하고 CPU 컨텍스트를 링 0에서 링 3으로 전환 한 다음 초기화 프로세스를 시작합니다 (프로세스 ID는 1 임). 이제 커널 부팅이 완료되었습니다!
  6. init프로그램은 모두 초기화 스크립트를 실행합니다. 모든 서비스가 시작되었습니다. 쉘이 호출됩니다. 사용자는 로그인 할 수 있습니다.

main함수 C의 함수이다. 실제로 주된 방법은 C 프로그램의 진입 점이 아닙니다. C 런타임은 전에 많은 함수를 호출합니다 main. GCC에는 확장 기능인 생성자가 있습니다. "생성자"로 선언 된 함수가 전에 호출 main됩니다.

예를 들면 다음과 같습니다.

/* This should not be used directly. Use block_init etc. instead. */ 
#define module_init(function, type) \
    static void _attribute__((constructor)) do_qemu_init ## function(void) { \
    register_module_init(function, type); \
} 

이 매크로는 qemu 프로젝트에서 가져온 것입니다.


주요 메소드는 ac 메소드입니다. 실제로 주요 메소드는 c 프로그램의 항목이 아닙니다 .C 런타임은 주요 메소드보다 많은 메소드를 호출했습니다.
Edward Shen

bios는 보통 부트 로더를로드하고, 그 부트 로더는 커널 이미지 (그리고 아마도 initrd)를로드합니다. 커널 코드는 initrd가 아닌 커널 이미지에 있습니다.
Stéphane Chazelas

GCC에는 확장 기능인 생성자가 있습니다. 메소드 선언 "constructor"는 main 메소드보다 먼저 호출됩니다. 예를 들면 다음과 같습니다. / * 직접 사용해서는 안됩니다. 대신 block_init 등을 사용하십시오. * / #define module_init (함수, 타입) \ static void _attribute __ ((생성자)) do_qemu_init ## function (void) {\ register_module_init (함수, 타입); \}
Edward Shen

1
initrd.img 커널 이미지가 아닙니다 . 부팅 할 때 커널이로드 한 모듈 세트입니다. 커널 이미지의 이름은 일반적으로 "vmlinuz"로 시작하지만 배포판마다 다릅니다.
goldilocks

3
이 답변은 "모든 것이 PC / Linux / i86"으로 가득 차 있으며, 그렇게 부팅되고 커널은 그렇게 작동합니다. 왜 모든 사람들이 이것이 세상에서 유일하게 가능한 방법이라고 생각합니까?
Jens

9

예를 들어 arch / x86 / boot / main.c 에는 시스템을 실제 모드에서 보호 모드로 전환하도록 준비하기위한 main () 함수가 있지만 다른 아키텍처에는 그러한 코드가 없습니다. x86 플랫폼에서 Linux 커널 2.6.x 부팅이 작동하는 방법에 대한 좋은 개요 가 있습니다. 정말 읽을 가치가 있습니다.

하우투 리눅스 커널 개발 문서에 따르면 리눅스 커널은

표준 C 라이브러리에 의존하지 않는 독립형 C 환경이므로 C 표준의 일부는 지원되지 않습니다.

C 표준 BTW에 따르면

'주'기능을 정의하기 위해 독립 환경의 프로그램이 필요한지 여부는 구현 정의입니다.

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