Step-by-Step
InitCall에 대한 정리 본문
1. initcall의 개념
리눅스 커널에서 initcall은 커널이 부팅될 때 실행되는 초기화 함수들을 관리하는 메커니즘입니다.
이 메커니즘은 다양한 서브시스템과 드라이버가 특정 순서대로 초기화되도록 돕습니다.
2. initcall의 실행 단계
리눅스 커널의 initcall은 다음과 같은 우선순위 단계로 나뉩니다. (각각 include/linux/init.h에 정의됨)
https://github.com/torvalds/linux/blob/master/include/linux/init.h
linux/include/linux/init.h at master · torvalds/linux
Linux kernel source tree. Contribute to torvalds/linux development by creating an account on GitHub.
github.com
0 | pure_initcall | - 가장 먼저 실행되는 초기화 단계 - 기본적인 시스템 설정 전에 실행되어야 하는 코드 등록 |
1 | core_initcall, core_initcall_sync | - 코어 서브시스템 초기화 - sync는 해당 단계에서 동기적으로 실행 |
2 | postcore_initcall, postcore_initcall_sync | - 아키텍처별 초기화 코드 진행 - CPU, MMU, 특정 하드웨어 관련 설정을 수행 |
3 | subsys_initcall, subsys_initcall_sync | - 시스템의 서브 시스템 (네트워크, 디바이스 드라이버 프레임워크 등) 초기화 - 디바이스 드라이버가 올라가기 전에 |
4 | fs_initcall, fs_initcall_sync | - 파일 시스템 관련 초기화 - 파일 시스템 드라이버 및 기본적인 스토리지 인터페이스 초기화 |
5 | rootfs_initcall, rootfs_initcall_sync | - 루트 파일시스템을 마운트 하기 위해 초기화 - fs_initcall 이후에 실행됨 |
6 | device_initcall, device_initcall_sync | - 개별 디바이스 드라이버 초기화 - 하드웨어 관련 장치 및 장치 드라이버 로딩 |
7 | late_initcall, late_initcall_sync | - 가장 마지막에 실행되는 초기화 단계 - 사용자 공간으로 전환하기 직전에 수행해야 하는 초기화 |
기타 | __initcall | - device_initcall의 별칭 (디바이스 드라이버 초기화) |
기타 | __exitcall | - 종료시 실행할 함수를 등록하는 매크로 |
이러한 단계는 각 서브시스템이 올바른 순서대로 실행될 수 있도록 도와줍니다.
부팅 과정에서 순차적으로 실행되며, 커널 초기화와 관련된 여러 작업을 단계적으로 실행할 수 있도록 설계되어 있습니다.
/*
* A "pure" initcall has no dependencies on anything else, and purely
* initializes variables that couldn't be statically initialized.
*
* This only exists for built-in code, not for modules.
* Keep main.c:initcall_level_names[] in sync.
*/
#define pure_initcall(fn) __define_initcall(fn, 0)
#define core_initcall(fn) __define_initcall(fn, 1)
#define core_initcall_sync(fn) __define_initcall(fn, 1s)
#define postcore_initcall(fn) __define_initcall(fn, 2)
#define postcore_initcall_sync(fn) __define_initcall(fn, 2s)
#define arch_initcall(fn) __define_initcall(fn, 3)
#define arch_initcall_sync(fn) __define_initcall(fn, 3s)
#define subsys_initcall(fn) __define_initcall(fn, 4)
#define subsys_initcall_sync(fn) __define_initcall(fn, 4s)
#define fs_initcall(fn) __define_initcall(fn, 5)
#define fs_initcall_sync(fn) __define_initcall(fn, 5s)
#define rootfs_initcall(fn) __define_initcall(fn, rootfs)
#define device_initcall(fn) __define_initcall(fn, 6)
#define device_initcall_sync(fn) __define_initcall(fn, 6s)
#define late_initcall(fn) __define_initcall(fn, 7)
#define late_initcall_sync(fn) __define_initcall(fn, 7s)
#define __initcall(fn) device_initcall(fn)
#define __exitcall(fn) \
static exitcall_t __exitcall_##fn __exit_call = fn
#define console_initcall(fn) ___define_initcall(fn, con, .con_initcall)